from a text file with accents I want to make it a .csv file that we can download
let data = decodeURI('a;b;é;É');
this.download(data, 'test.csv', 'data:text/csv;charset=utf-8');
here the code to download:
download(content, fileName, mimeType): boolean {
const a = document.createElement('a');
mimeType = mimeType || 'application/octet-stream;charset=UTF-8';
a.href = 'data:' + mimeType + ',' + encodeURIComponent(content);
a.setAttribute('download', fileName);
document.body.appendChild(a);
setTimeout(() => {
a.click();
document.body.removeChild(a);
}, 66);
return true;
}
I have strange accents in excell :
test.csv
a b é É
how can i solve this problem?
Prepend '\ufeff' to your data let data = '\ufeff'+decodeURI('a;b;é;É');, take look at UTF with BOM https://en.wikipedia.org/wiki/Byte_order_mark
Related
i want to download file from server in angular :
this code from service:
DownloadVerifyFile(requestId, fileId): any {
return this.httpClient
.get(this.appConfig.apiEndpoint + '/VerifyRequest/File/' + requestId + '/' + fileId,
{ responseType: 'blob' });
}
and this code for download that file in brwoser:
DownloadFile(fileId): void {
this.requestService.DownloadVerifyFile(this.id,fileId).subscribe(response => {
const a = document.createElement('a')
const objectUrl = URL.createObjectURL(response)
a.href = objectUrl
a.download = response;
a.click();
URL.revokeObjectURL(objectUrl);
});
}
but i have a problem with that , when i downlaod file , file name is this [object Blob] but i want to download by orginal name for example if file is file1.jpg , when downloaded file name must be fil1.jpg not [object Blob] . how can i solve this problem ???
Because you have named the file by response(It is an object). You were almost achieved. Just a little change as following:
a.download = response;
to
a.download = 'fil1.jpg';
Then you will get the correct file name.
I'm forced to use an old firefox version 26. I have the below code working perfectly on firefox 72, way more recent, I know. While stepping through the download function, I realize my problem has something to do with the a.click(). While comparing the debugging consoles between browsers I don't notice any differences in the function, but the a.click() isn't triggering the saveAs popup.
Here is the json list format, which has indices equal to n select box elements.
testn:{
val: "pass",
desc: "test description"}
JS
jsonData = $("#myform").serializeArray();
function download(content, fileName, contentType) {
var a = document.createElement("a");
var file = new Blob([content], {type: contentType});
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
}
if (confirm("Save results to <SCRIPT_PATH_LOCATION>")){
download(JSON.stringify(jsonData), 'webform.results.json', 'text/plain');
} else {
return false
}
I figured it out. Modern convenience allowed me to get away with not adequately appending the new element, "a" onto the webform.
JS
jsonData = $("#myform").serializeArray();
function download(content, fileName, contentType) {
var a = document.createElement("a");
//Insert these
document.body.appendChild(a);
a.style = "display: none";
//Insert complete
var file = new Blob([content], {type: contentType});
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
}
if (confirm("Save results to <SCRIPT_PATH_LOCATION>")){
download(JSON.stringify(jsonData), 'webform.results.json', 'text/plain');
} else {
return false
}
The thing is axios calls return files. sometimes xlsx, sometimes plain txt.
In javascript, as soon as I get them, i force download it via blob.
Something like this:
var headers = response.headers;
var blob = new Blob([response.data], {
type: headers['content-type']
});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "report.xlsx";
link.click();
As you see, I got something like this: link.download = "report.xlsx" . What I want is to replace xlsx with dynamic mime type so that sometimes it's report.txt and sometimes it's report.xlsx.
How do I do that from content-type?
You can get the file extension using the content type of headers.
Use this Javascript library - node-mime
You just want to pass your headers['content-type'], it will give you the file extension which you need to set for download name.
var ctype = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
console.log(mime.getExtension(ctype));
<script src="https://wzrd.in/standalone/mime#latest"></script>
Example: In your case,
var headers = response.headers;
var blob = new Blob([response.data], {
type: headers['content-type']
});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "report." + mime.getExtension(headers['content-type']);
link.click();
Incomplete list of MIME types from Mozilla Developers.
What is the backend of your application? I used this in C# (.NET Core) to get the content type of a file then set it as a header in the response:
public string GetContentType (string filePath) {
var contentTypeProvider = new FileExtensionContentTypeProvider();
string contentType;
if( !contentTypeProvider.TryGetContentType( filePath, out contentType ) ) {
contentType = "application/octet-stream";
};
return contentType;
}
Edit: modified OP code to handle content type dynamically:
var headers = response.headers;
var responseType = headers['content-type'];
var fileType = "text/plain";
var fileName = "report.txt";
if ( responseType == "application/octet-stream" ) {
fileType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
fileName = "report.xlsx";
}
var blob = new Blob([response.data], {
type: fileType
});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
I get a byte[] file from my server with the content of a file. I know the name and the content-type. So far I have tried the following for downloading the file:
const a = document.createElement('a');
document.body.appendChild(a);
a.style.display = 'none';
const file = new Blob([content], {type: 'text/plain'});
const url = window.URL.createObjectURL(file);
a.href = url;
a.download = "test.txt";
a.click();
window.URL.revokeObjectURL(url);
But this solution just downloads a text file with the binary content in it. How can I convert the binary data to the correspondent file type in the client side using JavaScript/Typescript? Thanks!
You can use file-saver
import { saveAs } from 'file-saver';
const file = new Blob([content], {type: 'text/plain'});
FileSaver.saveAs(file, "test.txt");
saveByteArray(bytes, type) {
var blob = new Blob([bytes],{type:type});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "fileName";
link.click();
}
I have the following Javascript code to export CSV file on the client side. However Google Chrome crashes every time I try to export a large array. What is the limit of the data string allowed in Chrome? Is it possible that it is hitting the memory limit allowed in Chrome? If the data string is too long for Chrome, how will I go about exporting large CSV files on the client side?
var csvRows = [...]; //Array with 40000 items, each item is 100 characters long.
var csvString = csvRows.join("\r\n");
var a = document.createElement('a');
a.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csvString);
a.target = '_blank';
a.download = 'export.csv';
document.body.appendChild(a);
a.click();
(Expected file size is about 6.4MB)
had the same Problem and solved it using Blob.
For example:
csvData = new Blob([csvString], { type: 'text/csv' });
var csvUrl = URL.createObjectURL(csvData);
a.href = csvUrl;
Source:
https://stackoverflow.com/a/24611096/3048937
I used following function to download CSV. Worked for me in IE/Firefox/Chrome
function downloadFile(data, fileName) {
var csvData = data;
var blob = new Blob([ csvData ], {
type : "application/csv;charset=utf-8;"
});
if (window.navigator.msSaveBlob) {
// FOR IE BROWSER
navigator.msSaveBlob(blob, fileName);
} else {
// FOR OTHER BROWSERS
var link = document.createElement("a");
var csvUrl = URL.createObjectURL(blob);
link.href = csvUrl;
link.style = "visibility:hidden";
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}