I've studied all of the SO Similar Questions about this problem, a few were helpful, but did not directly address the saving of an xlsx file to the local Win10 downloads folder.
The xlsx file sits on a CentOS 7 server. If I use Filezilla to copy it to Win10, it's fine.
Looking at the component code below, I am reading the xlsx from the server and getting its base64Str, which matches exactly what I used to store the file. I create a blob fine, but FileSaver, saves the Win10 file with its contents as the base64Str, instead of a an xlsx binary. Can FileSaver save binary content, or only text?
Thanks for helping!
Component Code
//INPUT DATA: docName: test.xlsx; mediaType: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; snippet base64Str: VUVzREJCUU...FBQUFBPQ=
//NOTE: input data is from a CentOS 7 filesystem
const byteStr = atob(base64Str);
const arrayBuffer = new ArrayBuffer(byteStr.length);
const int8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < byteStr.length; i++) {
int8Array[i] = byteStr.charCodeAt(i);
}
const blob = new Blob([arrayBuffer], { type: mediaType }); //also tried type: 'application/octet-stream'
//alternate technique that produces same corrupted result
//const base64Response = await fetch(`data:` +mediaType +`;base64,${base64Str}`);
//const blob = await base64Response.blob();
fileSaver.saveAs(blob, docName); //saves to Win10 downloads folder
Please try The below code. (Here in this example I have demonstrate the following 1) Input base64 string to a input text area 2) on click of download file link 3) will prompt to download the file into correct xlsx format without corrupted data).
Kindly modify the code as per your need . Example only demonstrate the file download feature.
Point to notice :
var mediaType="data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,";
function saveAsXlsxFile(){
var mediaType="data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,";
var userInp = document.getElementById('base64input');
// var userInp = "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";
var a = document.createElement('a');
a.href = mediaType+userInp.value;
//a.href = mediaType+userInp;
a.download = 'filename.xlsx';
a.textContent = 'Download file!';
document.body.appendChild(a);
}
<textarea placeholder="paste the base64 data here, exclude readable headers" id='base64input' type="textarea"></textarea>
<br>
<input onclick="saveAsXlsxFile()" type="button" value="update content of link"></button>
HTML code for demo only ( not mandatory for your requirement)
<textarea placeholder="paste the base64 data here, exclude readable headers" id='base64input'></textarea>
<br>
<input onclick="saveAsXlsxFile()" type="button" value="update content of link"></button>
Sample userInp value Try this :
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
Happy to help further if needed. :)
so I used this. Might also work for anyone trying to convert a static base 64 string to xlxs file. This solutions assumes that you know the file type.
let toConvert = 'UEsDBBQAAAgIABSJA..'//supply your full plain string here
let file = `data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,${toConvert}`;
setTimeout(() => {
fileSaver.saveAs(file, 'fileName');
}, 1300);//timeout is only added to simulate time to load. you can take it out
Regards
Not sure if this works , but try setting the mediaType like below :
const mediaType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
Related
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!
I have hacked together a small tool to extract shipping data from Amazon CSV order data. it works so far. here is a simple version as JS Bin: http://output.jsbin.com/jarako
For printing stamps/shipping labels, I need a file for uploading to Deutsche Post and to other parcel services. I used a small function saveTextAsFile which i found on stackoverflow. Everything good so far. No wrong displayed special characters (äöüß...) in the output textarea or downloaded files.
All these german post / parcel services sites accept only latin1 / iso-8859-1 encoded files for upload. But my downloaded file is always utf-8. If i upload it, all special characters (äöüß...) go wrong.
How can i change this? I still searched a lot. I have tried i.e.:
Setting the charset of the tool to iso-8859-1:
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
But the result is: Now I have wrong special characters still in the output textarea and in the downloaded file. If I upload it to the post site, I still get more wrong characters. Also if I check the encoding in CODA Editor it still says the downloaded file is UTF-8.
The saveTextAsFile function uses var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});. May be there is a ways to set the charset for download there!?
function saveTextAsFile()
{
var textToWrite = $('#dataOutput').val();
var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
var fileNameToSaveAs = "Brief.txt";
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null)
{
// Chrome allows the link to be clicked
// without actually adding it to the DOM.
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
}
else
{
// Firefox requires the link to be added to the DOM
// before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
Anyhow, there have to be a way to download files in other encoding as the site uses itself. The Amazon site, where i download the CSV file from is UTF-8 encoded. But downloaded CSV file from there is Latin1 (iso-8859-1) if i check it in CODA...
SCROLL DOWN TO THE UPDATE for the real solution!
Because I got no answer, I have searched more and more. It looks like there is NO SOLUTION in Javascript. Every test download I'v made, which was generated in javascript was UTF-8 encoded. Looks like Javascript is only made for UNICODE / UTF-8 or an other encoding would (possibly) only apply if the data would be transported again using a former HTTP transport. But for a Javascript, which runs on the client no additional HTTP transport happens, because the data is still on the client..
I have helped me now with building a small PHP Script on my server, to which i send the Data via GET or POST request. It converters the encoding to latin1 / ISO-8859-1 and downloads it as file. This is a ISO-8859-1 file with correctly encoded special characters, which I can upload to the mentioned postal and parcel service sites and everything looks good.
latin-download.php: (It is VERY IMPORTANT to save the PHP file itself also in ISO-8859-1, to make it work!!)
<?php
$decoded_a = urldecode($_REQUEST["a"]);
$converted_to_latin = mb_convert_encoding($decoded_a,'ISO-8859-1', 'UTF-8');
$filename = $_REQUEST["filename"];
header('Content-Disposition: attachment; filename="'.$filename.'"; content-type: text/plain; charset=iso-8859-1;');
echo $converted_to_latin;
?>
in my javascript code i use:
<a id="downloadlink">Download File</a>
<script>
var mydata = "this is testdata containing äöüß";
document.getElementById("downloadlink").addEventListener("click", function() {
var mydataToSend = encodeURIComponent(mydata);
window.open("latin-download.php?a=" + mydataToSend + "&filename=letter-max.csv");
}, false);
</script>
for bigger amounts of data you have to switch from GET to POST...
UPDATE 08-Feb-2016
A half year later now i have found a solution in PURE JAVASCRIPT. Using inexorabletash/text-encoding. This is a polyfill for Encoding Living Standard. The standard includes decoding of old encodings like latin1 ("windows-1252"), but it forbids encoding into these old encoding types. So if you use the browser implemented window.TextEncoder function it does offer only UTF encoding. BUT, the polyfill solution offers a legacy mode, which does ALLOW also encoding into old encodings like latin1.
i use it like that:
<!DOCTYPE html>
<script>
// 'Copy' browser build in TextEncoder function to TextEncoderOrg (because it can NOT encode windows-1252, but so you can still use it as TextEncoderOrg() )
var TextEncoderOrg = window.TextEncoder;
// ... and deactivate it, to make sure only the polyfill encoder script that follows will be used
window.TextEncoder = null;
</script>
<script src="lib/encoding-indexes.js"></script> // needed to support encode to old encoding types
<script src="lib/encoding.js"></script> // encording polyfill
<script>
function download (content, filename, contentType) {
if(!contentType) contentType = 'application/octet-stream';
var a = document.createElement('a');
var blob = new Blob([content], {'type':contentType});
a.href = window.URL.createObjectURL(blob);
a.download = filename;
a.click();
}
var text = "Es wird ein schöner Tag!";
// Do the encoding
var encoded = new TextEncoder("windows-1252",{ NONSTANDARD_allowLegacyEncoding: true }).encode(text);
// Download 2 files to see the difference
download(encoded,"windows-1252-encoded-text.txt");
download(text,"utf-8-original-text.txt");
</script>
The encoding-indexes.js file is about 500kb big, because it contains all the encoding tables. Because i need only windows-1252 encoding, for my use i have deleted the other encodings in this file. so now there are only 632 byte left.
The problem is not the encoding but the fact that the special characters are displayed wrong in some applications, e.g. Microsoft Excel. UTF-8 is fine for displaying all special German characters. You can fix the problem by adding a Byte order mark (BOM) in front of the csv.
const BOM = "\uFEFF"
let csvData = BOM + csvData
const blob = new Blob([csvData], { type: "text/csv;charset=utf-8" });
Solution based on this github post
You cannot force a web server to send you data in a given encoding, only ask it politely. Your approach to just convert to the format you need is the right way to go.
If you wanted to avoid the PHP script, you may have luck specifying the encoding as a parameter when creating your Blob:
var textFileAsBlob = new Blob(textToWrite, {
type: 'text/plain;charset=ISO-8859-1',
encoding: "ISO-8859-1"
});
See Specifying blob encoding in Google Chrome for more details.
We transform HTML to PDF in the backend (PHP) using dompdf. The generated output from dompdf is Base64 encoded with
$output = $dompdf->output();
base64_encode($output);
This Base64 encoded content is saved as a file on the server. When we decode this file content like this:
cat /tmp/55acbaa9600f4 | base64 -D > test.pdf
we get a proper PDF file.
But when we transfer the Base64 content to the client as a string value inside a JSON object (the server provides a RESTful API...):
{
"file_data": "...the base64 string..."
}
And decode it with atob() and then create a Blob object to download the file later on, the PDF is always "empty"/broken.
$scope.downloadFileData = function(doc) {
DocumentService.getFileData(doc).then(function(data) {
var decodedFileData = atob(data.file_data);
var file = new Blob([decodedFileData], { type: doc.file_type });
saveAs(file, doc.title + '.' + doc.extension);
});
};
When we log the decoded content, it seems that the content is "broken", because several symbols are not the same as when we decode the content on the server using base64 -D.
When we encode/decode the content of simple text/plain documents, it's working as expected. But all binary (or not ASCII formats) are not working.
We have searched the web for many hours, but didn't find a solution for this that works for us. Does anyone have the same problem and can provide us with a working solution? Thanks in advance!
This is a example for a on the server Base64 encoded content of a PDF document:
JVBERi0xLjMKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZwovT3V0bGluZXMgMiAwIFIKL1BhZ2VzIDMgMCBSID4+CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9PdXRsaW5lcyAvQ291bnQgMCA+PgplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMKL0tpZHMgWzYgMCBSCl0KL0NvdW50IDEKL1Jlc291cmNlcyA8PAovUHJvY1NldCA0IDAgUgovRm9udCA8PCAKL0YxIDggMCBSCj4+Cj4+Ci9NZWRpYUJveCBbMC4wMDAgMC4wMDAgNjEyLjAwMCA3OTIuMDAwXQogPj4KZW5kb2JqCjQgMCBvYmoKWy9QREYgL1RleHQgXQplbmRvYmoKNSAwIG9iago8PAovQ3JlYXRvciAoRE9NUERGKQovQ3JlYXRpb25EYXRlIChEOjIwMTUwNzIwMTMzMzIzKzAyJzAwJykKL01vZERhdGUgKEQ6MjAxNTA3MjAxMzMzMjMrMDInMDAnKQo+PgplbmRvYmoKNiAwIG9iago8PCAvVHlwZSAvUGFnZQovUGFyZW50IDMgMCBSCi9Db250ZW50cyA3IDAgUgo+PgplbmRvYmoKNyAwIG9iago8PCAvRmlsdGVyIC9GbGF0ZURlY29kZQovTGVuZ3RoIDY2ID4+CnN0cmVhbQp4nOMy0DMwMFBAJovSuZxCFIxN9AwMzRTMDS31DCxNFUJSFPTdDBWMgKIKIWkKCtEaIanFJZqxCiFeCq4hAO4PD0MKZW5kc3RyZWFtCmVuZG9iago4IDAgb2JqCjw8IC9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMQovTmFtZSAvRjEKL0Jhc2VGb250IC9UaW1lcy1Cb2xkCi9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nCj4+CmVuZG9iagp4cmVmCjAgOQowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMDggMDAwMDAgbiAKMDAwMDAwMDA3MyAwMDAwMCBuIAowMDAwMDAwMTE5IDAwMDAwIG4gCjAwMDAwMDAyNzMgMDAwMDAgbiAKMDAwMDAwMDMwMiAwMDAwMCBuIAowMDAwMDAwNDE2IDAwMDAwIG4gCjAwMDAwMDA0NzkgMDAwMDAgbiAKMDAwMDAwMDYxNiAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDkKL1Jvb3QgMSAwIFIKL0luZm8gNSAwIFIKPj4Kc3RhcnR4cmVmCjcyNQolJUVPRgo=
If you atob() this, you don't get the same result as on the console with base64 -D. Why?
Your issue looks identical to the one I needed to solve recently.
Here is what worked for me:
const binaryImg = atob(base64String);
const length = binaryImg.length;
const arrayBuffer = new ArrayBuffer(length);
const uintArray = new Uint8Array(arrayBuffer);
for (let i = 0; i < length; i++) {
uintArray[i] = binaryImg.charCodeAt(i);
}
const fileBlob = new Blob([uintArray], { type: 'application/pdf' });
saveAs(fileBlob, 'filename.pdf');
It seems that only doing a base64 decode is not enough...you need to put the result into a Uint8Array. Otherwise, the pdf pages appear blank.
I found this solution here:
https://github.com/sayanee/angularjs-pdf/issues/110#issuecomment-579988190
You can use btoa() and atob() work in some browsers:
For Exa.
var enc = btoa("this is some text");
alert(enc);
alert(atob(enc));
To JSON and base64 are completely independent.
Here's a JSON stringifier/parser (and direct GitHub link).
Here's a base64 Q&A. Here's another one.
I am encoding a MP3 file to Base64 in Node Js using this method :
encodebase64 = function(mp3file){
var bitmap = fs.readFileSync(mp3file);
var encodedstring = new Buffer(bitmap).toString('base64');
fs.writeFileSync('encodedfile.bin', encodedstring);}
and then again I want to construct the MP3 file from the Base64 bin file, but the file created is missing some headers , so obviously there's a problem with the decoding.
the decoding function is :
decodebase64 = function(encodedfile){
var bitmap = fs.readFileSync(encodedfile);
var decodedString = new Buffer(bitmap, 'base64');
fs.writeFileSync('decodedfile.mp3', decodedString);}
I wondered if anyone can help
Thanks.
Perhaps it is an issue with the encoding parameter. See this answer for details. Try using utf8 when decoding to see if that makes a difference. What platforms are you running your code on?
#Noah mentioned an answer about base64 decoding using Buffers, but if you use the same code from the answer, and you try to create MP3 files with it, then they won't play and their file size will be larger than original ones just like you experienced in the beginning.
We should write the buffer directly to the mp3 file we want to create without converting it(the buffer) to an ASCII string:
// const buff = Buffer.from(audioContent, 'base64').toString('ascii'); // don't
const buff = Buffer.from(audioContent, 'base64');
fs.writeFileSync('test2.mp3', buff);
More info about fs.writeFile / fs.writeFileAsync
I am experiencing difficulties with uploading files via ajax without sing html form.
My case is like this:
I have a textarea
I would like to zip the content of that textarea and upload it to the server via AJAX (right now I am using JSZip)
For testing purpose, I try to create a dummy zip file to send like this (not getting textarea content):
var zip = new JSZip();
zip.file("hello1.txt", "Hello First World\n");<br/>
zip.file("hello2.txt", "Hello Second World\n");<br/>
var content = zip.generate();
Then I use Jquery ajax method to send, like this:
$.post("the_url",
{
GradeRequest : {
submitter_id : "foobar",
evaluationset_id : 9,
mode : 1,
source_file : "a.cpp",
file: content
}
}
);
But the file is not received on the server.
I have read question in How can I upload files asynchronously?, but all solutions are using html form. Is there any solution which does not involve any html form ?
Thanks in advance.
In the server side, I'm using Yii PHP Framework:
$model = $this->model;
if ($model !== null && isset($_POST['GradeRequest'])) {
$model->setAttributes($_POST['GradeRequest']);
if ($model->validate()) {
if (isset($_FILES['GradeRequest']['tmp_name']['file']) && $_FILES['GradeRequest']['tmp_name']['file'] !== "") {
$model->file = file_get_contents($_FILES['GradeRequest']['tmp_name']['file']);
$model->source_file = $_FILES['GradeRequest']['name']['file'];
}
$this->setReply(true, "Ok");
$model->client_id = $this->clientId;
$model->request_id = $this->requestRecord->id;
$model->save();
} else {
$this->setReply(false, $model->getErrors());
}
}
As a proof of concept, I have created a form version like this and it works (the file got uploaded to the server):
<form enctype="multipart/form-data" method="post" action="[the_url]>
EvaluationSet id: <input type="text" name="GradeRequest[evaluationset_id]" /><br />
<input type="hidden" name="GradeRequest[mode]" value="0" />
<input type="hidden" name="GradeRequest[submitter_id]" value="Someone" />
Source file : <input type="text" name="GradeRequest[source_file]" /><br />
File : <input type="file" name="GradeRequest[file]" /><br />
<input type="submit" />
There the FormData object that can help you (it's part of the so called xmlHttpRequest version 2): this is a compatibility chart, with some linked references and examples.
With that, you can add key/value pairs to the POST form, including File objects, and send it all via the common send method of xmlHttpRequest.
File objects can be easily retrieved using a <input type="file"> element, or even using drag & drop from your desktop.
If you want to upload some file content as a file, you'll have to create a Blob. This feature is still experimental but supported by Chrome and Firefox (at least... and Safari I guess?):
var builder = new BlobBuilder();
builder.append(content);
var blob = builder.getBlob("application/zip");
Keep in mind that at this moment you'll have to use MozBlobBuilder in Firefox and WebKitBlobBuilder in Chrome instead.
In some tutorials I've seen that the string is actually converted into a Uint8Array first. Maybe that's based on a older reference, because the append method of BlobBuilder should accept plain strings too. Never tried it though.
If your content is a Base64 encoded string, you'll have to convert it using atob (should be supported by every browser that also supports Blob and FormData).
Edit: BlobBuilder is now deprecated due to the new draft of the Blob constructor. So everything you'll have to do to get the Blob is:
var blob = new Blob([content], "application/zip");
The rest is quite simple:
var form = new FormData();
form.append("file", blob);
The problem here is that the file name on the server side is unpredictable and depends on the user agent. I've seen some uses of append with a third parameter specifying the file name, but I guess it's a good idea to send the actual file name to a separate key/value pair in the FormData object.
I finally get it through !! Many thanks for MaxArt.
Basically, it is what MaxArt has said with Uint8Array conversion. I got the conversion reference from Eric Bidelman here.
Here's how I've done it:
var zip = new JSZip();
zip.file("hello1.txt", "Hello First World\n");
zip.file("hello2.txt", "Hello Second World\n");
var content = zip.generate(); //Generate dummy zip file (adjust to your need)
var oBlob = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder)(); //Instantiate blob builder
var raw = atob(content); //decode the base64 string
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) { //convert to uInt8Array
uInt8Array[i] = raw.charCodeAt(i);
}
oBlob.append(uInt8Array.buffer); //append it to blobbuilder
oMyForm.append("GradeRequest[file]", oBlob.getBlob("application/zip")); //because you create a zip file, so get the zip type
//send it
var oReq = new XMLHttpRequest();
oReq.open("POST", "{{the_url}}");
oReq.send(oMyForm);