Excel export in JavaScript not working using Blob - javascript

I have some javascript problem. I'm struggling to download a file in xlsx format. In backend works everything fine - file is downloaded using for example swagger.
My code:
private async downloadDocumentTemplate(report: string) {
this.fileLoading = true;
try {
const result = await this.$store.dispatch("report/downloadDocument", report);
const blob = new Blob([result], {type: "application/octet-stream"});
var reader = new FileReader();
reader.addEventListener("loadend", function() {
});
reader.readAsArrayBuffer(blob);
console.log("blob contnet : " + blob.type);
FileSaver.saveAs(blob, 'report.xlsx');
} catch (ex) {
this.$store.commit("app/showErrorPopup", ex);
}
this.fileLoading = false;
}
After downloading file from the web and file is open automatically and I am experiencing an error that reads:
"We found a problem with some content .xlsx. Do you want us to try and recover as much as we can?" e

I had some similar issue. The problem in my case was how I parsed the Excel data. The script was putting wrong formatted information.
If downloading the file to the computer works, there must be an error in your code which parses the excel data.

Related

Attempting to download a .xlsx file and upload to Azure Blob Storage using Playwright with Javascript produces malformed .xlsx file with a bad header

I am trying to download an excel file and then upload it to Azure Blob Storage for use in Azure Data Factory. I have a playwright javascript that worked when the file was a .csv but when I try the same code with an excel file, it will not open in Excel. It says,
"We found a problem with some content in 'order_copy.xlsx'. Do you want us to try to recover as much as we can?:
After clicking yes, it says,
"Excel cannot open the file 'order_copy.xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file."
Any ideas on how to use the createReadStream more effectively to do this and preserve the .xlsx format?
I don't think the saveAs method will work since this code is being executed in an Azure Function with no access to a local known path.
My first thought was the content type was not right, so I set that, but it still did not work. I tried a UTF-8 encoder but that also did not work.
//const data = await streamToText(download_csv.createReadStream())
const download_reader = await download_csv.createReadStream();
let data = '';
for await (const chunk of download_reader) {
data += chunk; //---I suspect I need to do something different here
}
// const data_utf8 = utf8.encode(data) //unescape( encodeURIComponent(data) );
const AZURE_STORAGE_CONNECTION_STRING = "..." //---Removed string here
// Create the BlobServiceClient object which will be used to create a container client
const blob_service_client = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING);
// Get a reference to a container
const container_client = blob_service_client.getContainerClient('order');
const blob_name = 'order_copy.xlsx';
// Get a block blob client
const block_blob_client = container_client.getBlockBlobClient(blob_name);
const contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
const blobOptions = { blobHTTPHeaders: { blobContentType: contentType } };
//const uploadBlobResponse = await block_blob_client.upload(data_utf8, data_utf8.length, blobOptions);
const uploadBlobResponse = await block_blob_client.upload(data, data.length, blobOptions);
console.log("Blob was uploaded successfully. requestId: ", uploadBlobResponse.requestId);
Any guidance would be appreciated. Thank you in advance for your help!
-Chad
Thanks #Gaurav for the suggestion on not setting the data to a string. The following code worked after I changed to using a array of the chunks and concatenated it using the Buffer similar to your suggested code.
let chunks = []
for await (const chunk of download_reader) {
chunks.push(chunk)
}
const fileBuffer = Buffer.concat(chunks)
...
const uploadBlobResponse = await block_blob_client.upload(fileBuffer, fileBuffer.length, blobOptions);
Thanks everyone!

How to get bytecode from selected pdf in angular

I want to extract the bytecode from an file I select (pdf) to save it in my database. But I am always getting the error that my byte is undefined. Could someone look at my code and tell me what is wrong with it?
I tried to use the FileReader but my byte returns undefined, the formdata works fine it shows on the console every information I need for the file.
EDIT:
uploadFile2(files: FileList | null): void {
const file = files.item(0)
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
this.documentsArray.push({documentType: this.form.controls.dokumentType.value, file: reader.result})
console.log(this.documentsArray)
}
}
Hi I edited my code and now I am getting a base64 I think, but one question, it starts like this:
data:application/pdf;base64,JVBERi0xLjQKJfbk/N8KM......."
is the start with data:application/pdf correct or do I have to change something to save it in the database
I'd suggest you to store the file as a base64 String in your database.
This would look as following. With the line number 2 you're fetching the file from your input event.
const reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.onload = (event) => {
if (reader.result) {
//save pdf base64 into database
}

How to convert PNG image binary string to base64 without writing it to disk?

I successfully passed an image as binary string out of puppeteers page.evaluate() function back to node.js using:
async function getBinaryString(url) {
return new Promise(async (resolve, reject) => {
const reader = new FileReader();
const response = await window.fetch(url)
const data = await response.blob();
reader.readAsBinaryString(data);
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject('Error occurred while reading binary string');
});
}
I am able to save it with:
fs.writeFileSync(“image.png”, new Buffer.from(binaryString, "binary"), function (err) { });
But now I wish to convert this PNG image to base64 without saving it to file first because I will upload it to a different server. If I save it to file, I can do the following:
function base64Encode(file) {
const bitmap = fs.readFileSync(file);
return new Buffer.from(bitmap).toString('base64');
}
How do I skip the file saving part and get proper base64 data for my PNG?
I tried to pass binary string to new Buffer.from(binaryString).toString('base64') but I was unable to save it as a working PNG.
This doesn’t really warrant answering my own question but #Jacob reminded me that I forgot to try:
new Buffer.from(binaryString, 'binary').toString('base64');
with a "binary" parameter, which solved the issue and PNG was correctly formatted again when going from base64 to file or to image in a browser.
Maybe the code in question can be reused by some other puppeteer user, it took me a while to come up with and find pieces across the web.

Passing Uint8 array to PDF.js not working

I need to use PDF.js local, without a webserver. Just need to display a PDF which is in the same directory. Found this link here and also read in the FAQ that you can pass a Uint8 Array to PDF.js. I'm using filereader() to read the file. But I'm getting "Invalid PDF structure" error message. The PDF is ok - I've uploaded the whole thing to a webserver for testing. When opening the PDF with viewer.html online its working. What am I missing?
This is my code so far:
var file = new File(["compressed.tracemonkey-pldi-09.pdf"], "compressed.tracemonkey-pldi-09.pdf", {type: 'application/pdf'});
var fileReader = new FileReader();
fileReader.onload = function() {
var typedarray = new Uint8Array(fileReader.result);
pdfjsLib.getDocument(typedarray).then(function(pdf) {
//do something
});
};
fileReader.readAsArrayBuffer(file);

How do i remove files from a zip file uploaded through kendoUpload? Using jszip

After the user uploads a zipped file, i want to remove the images folder from it before sending it over the network. I am using kendo for uploading, and the existing functionality works fine. I just want to add on the removing images part. This is what i have so far:
function onSelect(e) {
var file = e.files[0];
if (endsWith(file.name, '.eds')) {
var contents = e.target.result;
var jszip = new JSZip(contents);
jszip.remove("apldbio/sds/images_barcode");
fileToSend = jszip.generate({type: "base64", compression: "DEFLATE"});
}
e.files[0] = fileToSend;
openProgressDialog(e.files.length); //this is existing code, works fine
}
target.result doesn't seem to exist in the event e. And nothing works properly from that point on. e should probably be used inside a FileReader object's onload(), (as seen here and here) but i have no idea how to use a FileReader for my purpose, with kendo Upload.
EDIT:I did some more reading and now i am using FileReader like this:
var reader = new FileReader();
reader.onload = function (e) {
// do the jszip stuff here with e.target.result
};
reader.onerror = function (e) {
console.error(e);
};
reader.readAsArrayBuffer(file);
Note : file = e.files[0] as in the 1st code block.
With this though, i get the error:
Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'.

Categories

Resources