I've got this code:
let file: File = fileList[0];
console.log(file);
var fileReader = new FileReader();
fileReader.onload = (event) => {
this.fileString = fileReader.result as string;
};
fileReader.readAsText(file);
That saves a file's blob as a string. Now I need code that can recover the original blob from the fileString. I'm not seeing any posts that address this already.
Does anyone know how I can recover the original blob?
Currently, I'm trying this code (because the file I'm uploading it a word doc):
var myblob = new Blob([this.fileString], {
type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
});
console.log(myblob);
saveAs(myblob, "test.docx");
And I'm surprised to see that the original file when console logged is size: 247583 and when I console log in the 2nd section, it's size 433474
Related
I have a binary string (from an REST API) that is the content of a Excel file.
PK\x03\x04\x14\x00\x06\00\x00\x00���N�0\x10E�H�C�-#\b5��\x12*Q>�ēƪc[�ii����\x10B�\x15j7�\x12��{2��h�nm���ƻR\f����U^\x1B7/���%�\x17\x19�rZY�\x14\x1B#1\x19__�f�\x00�q��R4D�AJ�\x1Ah\x15\x16>����V\x11�ƹ\f�Z�9����NV ...
What I want is to put this content in a FileReader object. I tried to convert the content to blob and to use readAsBinaryString but it doesn't work.
Maybe I missed something
However, when I use an input type=file, it's works with this example
$("#input").on("change", (e) => {
selectedFile = e.target.files[0];
});
let fileReader = new FileReader();
fileReader.readAsBinaryString(selectedFile);
fileReader.onload = (event)=>{
let data = event.target.result;
let workbook = XLSX.read(data,{type:"binary"});
}
What I would like is for selectedFile to reflect the binary string and not have to go through an input type=file
Thanks for your help
You can create a Blob object from the binary string, then create a File object from the Blob and finally, create a FileReader object from the File object.
var binaryString = "PK\x03\x04\x14\x00\x06\00\x00\x00���N�0\x10E�H�C�-#\b5��\x12*Q>�ēƪc[�ii����\x10B�\x15j7�\x12��{2��h�nm���ƻR\f����U^\x1B7/���%�\x17\x19�rZY�\x14\x1B#1\x19__�f�\x00�q��R4D�AJ�\x1Ah\x15\x16>����V\x11�ƹ\f�Z�9����NV ...";
// create a Blob object
var blob = new Blob([binaryString], { type: "application/vnd.ms-excel" });
// create a File object from the Blob
var file = new File([blob], "file.xlsx");
// create a FileReader object
var reader = new FileReader();
// use the readAsArrayBuffer method to read the file
reader.readAsArrayBuffer(file);
// when the reading is done, log the result
reader.onloadend = function () {
console.log(reader.result);
};
I'm working on a REST web application that manages documents between users and uploaders. The backend is written in Java and my Document entity contains, besides various attributes, a byte[] content. I was able to send a file created at server side by
#GET
...
document.setContent(Files.readAllBytes(Paths.get("WEB-INF/testFile.txt")));
return Response.ok(document).build();
and retrieve it at front-end (vueJs) through
async function download(file) {
const fileURL = window.URL.createObjectURL(new Blob([atob(file.content)]));
const fileLink = document.createElement("a");
fileLink.href = fileURL;
fileLink.setAttribute("download",`${file.name}.${file.type}`);
document.body.appendChild(fileLink);
fileLink.click();
fileLink.remove;
window.URL.revokeObjectURL(fileURL);
}
the problem is that when I try to upload a file and then download it, its content is not parsed correctly (is shown undefined, string in Base64 or numbers depending on how I try to solve it). The file is sent by a post request and is retrieved through an input form bound to an onFileSelected function.
function onFileSelected(e) {
var reader = new FileReader();
reader.readAsArrayBuffer(e.target.files[0]);
reader.onloadend = (evt) => {
if (evt.target.readyState === FileReader.DONE) {
var arrayBuffer = evt.target.result;
this.file.content = new Uint8Array(arrayBuffer);
//this.file.content = arrayBuffer;
}
};
}
axios.post(...,document,...)
and I have tried using atob and btoa as well before assigning the value to this.file.content. If I print the file on server Welcome.txt it gives B#ae3b74d and if I use Arrays.toString(welcome.getContent()) it gives an array of numbers but as soon as it passed to the frontend its content become in Base64 welcome: { ... content: IFRoaXMgaXMgYSB0ZXN0IGZpbGUhIAo...}. Any idea? Thank you a lot!
I have a working API call that returns in the response body a string prepared in Bytes format on the Python side that is a zip file. The String looks something like this, but longer:
PK��Q��F���������������/export_file.csv��uX\M�
This is a zip file containing one csv file. In tools such as postman, hitting the same POST endpoint with the same parameters in the body, I can successfully download a valid zip file, unzip the contents, and view the .csv file. In the browser debugger tools, I can see the API endpoint returning a successful response, with the same string above in the body.
Where I have failed at every attempt is on the react side, doing the work necessary to take this string and download the same zip file. Every suggestion I've read on SO and everywhere else has failed me. Here is what some of my failed attempts look like:
(Also note that a successful API call returns a 26kb payload from this example)
export function downloadZipFile(responseBody){
/* Blob Attempts */
// These download a 46kb file. Attempting to open gives "The compressed zip folder is invalid"
// var blob = new Blob([responseBody], {type: "content-type"});
// var blob = new Blob([responseBody], {type: "application/zip"});
// var blob = new Blob([responseBody], {type: "application/zip, application/octet-stream"});
// var blob = new Blob([responseBody], {type: "application/octet-stream"});
// var blob = new Blob([responseBody], {type: "octet/stream"});
var fileName = "export.zip";
saveAs(blob,fileName);
/* Data String Attempts */
// const dataStr = "data:application/zip;" + responseBody; // "Failed - Network Error"
// const dataStr = "data:application/zip, application/octet-stream;" + responseBody; // Downloads 1kb File "The compressed zip folder is invalid"
// const dataStr = "data:application/zip,application/octet-stream;" + responseBody; // Downloads 1kb File "The compressed zip folder is invalid"
// const dataStr = "data:application/octet-stream;" + responseBody; // "Failed - Network Error"
let downloadElement = document.createElement('a');
downloadElement.setAttribute("href", dataStr);
downloadElement.setAttribute("download", "export.zip");
document.body.appendChild(downloadElement);
downloadElement.click();
downloadElement.remove();
}
I've arrived late, but hope to help someone.
It is really important to set responseType as 'arraybuffer' in the api call, like this:
...
export const getZip = async (id) => {
const { data } = await axios.get(
"/sypa-applications/export",
{
id
},
{ responseType: "arraybuffer" }
);
return data;
}
...
Then you can download the ZIP from both ways:
1.- Using file-saver npm dependency:
let blob = new Blob([data], { type: "application/zip" });
saveAs(blob, "fileName.zip");
2.- Using DOM:
const url = window.URL.createObjectURL(new Blob([data], { type: "application/zip" });
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "fileName.zip");
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
I couldn't download the ZIP until I set the responseType param to "arraybuffer" in the GET request.
Best regard,
Alberto.
Did you check this tool? https://gildas-lormeau.github.io/zip.js/
There is an example for unzipping a file using js in the browser. http://gildas-lormeau.github.io/zip.js/demos/demo2.html
It seems that this is what you want. First unzip the file and the use the .csv as wanted
I'm trying to export data from an Angular 6 web application.
I have an array of string, where each string is a csv line, formatted like this:
var csvLines = ['val1,val2\n', 'val3,val4\n'...];
Once I've added all the data to i need to the array, i write it to the console:
This looks fine...
Now i wan't to convert it to a blob and download it as a .CSV file.
The download is fine, but the format of the output is wrong.
When I run the following code:
const blob = new Blob([csvLines], {type: 'text/csv;encoding:utf-8'});
const reader = new FileReader();
reader.onload = () => {
console.log(reader.result);
};
reader.readAsText(blob);
I get this output.
NOTE the commas that are appended on every line but the first - this mess up my csv.
Can anyone tell me why this is happening and perhaps how to disable the comma appending?
I have tried to create the Blob with text/plain as mimetype and without the encoding, but the commas are still appended.
Because you are passing csvLines as [csvLines] to new Blob(..), you are passing an array containing an array. It seems like the subarray is joined using commas.
Just use new Blob(csvLines, { type: 'text/csv;encoding:utf-8' }); and you should be fine.
const csvLines = ['val1,val2\n', 'val3,val4\n'];
const blob = new Blob(csvLines, { type: 'text/csv;encoding:utf-8' });
const reader = new FileReader();
reader.onload = () => {
console.log(reader.result);
};
reader.readAsText(blob);
When i do a post request to a route i have
/generate/image
i get something like: var file =
����JFIF��C��C��� ��
�����+�}Yϭ�F39M>���������>���;��ˋ��uXʽ�w�ڤx\-[2g��k�S���H���m
[�V?[_W����#��v��}6�[��F�F�%����n�...
in the client i do:
var blob = new Blob([file], {type: 'image/png'});
var reader = new FileReader();
reader.onload = function (e) {
$('#result').attr('src', e.target.result);
};
reader.readAsDataURL(blob);
but i get a corrupt image
what can i do?
EDIT:
if i do
img.src = 'data:image/png;base64,' + btoa(file);
i get:
Uncaught InvalidCharacterError: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
Please don't use base64 and wast bandwidth + CPU
Send the image binary as is and handle them correctly with Ajax.
You should not get the result as a string. set xhr responseType to blob or use fetch's blob method.
fetch("/generate/image").then(res => res.blob())
When you have the blob don't use the file reader to turn it to a url.
Use URL.createObjectURL(blob)
At your backend you can do following:
var fs = require('fs');
fs.readFile(path to image from you file, 'base64', function(err, buf){
/* Here you can send your base64 image data to client. Your base64 data is in buf.
I am using socket. You can just send. Read more about readFile function*/
socket.emit('image upload', { image: true, buffer: buf });
});
As my client receives data from socket, I call a function:
socket.on('image upload', function(data){
displayImage(data);
});
var displayImage = function(data){
var URL = 'data:image/jpg;base64,'+data.buffer;
document.querySelector('#img-id').src = URL;
};
The image will then be showed in img tag.
Hope this works for you.