Binary data to file download of any extension in JavaScript - javascript

I have a binary data saved in MongoDB. How can I covert this binary data into downloadable file of any filetype(.txt,.pdf,.img).
Using JavaScript blob I tried to generate and download the file as per below code snippet;
const a = document.createElement('a');
document.body.appendChild(a);
a.style.display = 'none';
const data = =attachments[0].file.data;
const blob = new Blob([data], {type: "octet/stream"});
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
This doesn't seem to work as it downloads a file with no extension and as [object Object] if I open the file through Notepad. What data should be set as first parameter in the new Blob(data, type) to get the correct file

Related

Download string data as file based on the file type (text/Json)

I am trying to downloading a string data as file such as text, and json files based on the fileType we are passing as parameter. I have tried below code.
function downloadString(text, fileType, fileName) {
var blob = new Blob([text], { type: fileType });
var a = document.createElement('a');
a.download = fileName;
a.href = URL.createObjectURL(blob);
a.dataset.downloadurl = [fileType, a.download, a.href].join(':');
a.style.display = "none";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(function() { URL.revokeObjectURL(a.href); }, 1500);
}
Downloading is working. But it always download txt file even if we pass json filetype.
Can anyone help this?

Angular download base64 file data

When I try to save on Angular a base64 file with this format :
// receivedFile.file = "data:image/jpeg;base64,/9j/4AAQSkZJR..."
var a = document.createElement('a');
const blob = new Blob([receivedFile.file], {type: receivedFile.infos.type});
a.href = URL.createObjectURL(blob);
a.download = receivedFile.infos.name;
a.click();
This code give me a corrupted file, how can I do ?
In Angular (and in general) I use file-saver :
import { saveAs } from 'file-saver';
const blob = new Blob([receivedFile], {type: receivedFile.infos.type});
FileSaver.saveAs(blob, receivedFile.infos.name);
Also, try to remove the data:image/jpeg;base64, part of the string :
receivedFile.file.replace("data:image/jpeg;base64," , "")
Here is the code which converts base64 to downloadable file format in angular.
If for example your file type is csv, then below is the code snippet
downloadFile(base64:any,fileName:any){
const src = `data:text/csv;base64,${base64}`;
const link = document.createElement("a")
link.href = src
link.download = fileName
link.click()
link.remove()
}
//calling above function with some sample base64 data
downloadFile("c21hbGxlcg==","demo.csv")
Note: The file type can be anything you can give based on the need(In src of above code snippet).Here I am considering the csv file as example.
So by calling this above function You can download the resultant file will be downloaded from browser.
To resolve this problem :
Removed data:image/jpeg;base64 from the receivedFile.file.
Use the function atob(), const byteCharacters = atob(receivedFile.file);
Then make the blob
const blob = new Blob([byteCharacters], {type: this.receivedFile.infos.type});
try this
const downloadLink = document.createElement('a');
const fileName = 'sample.pdf';
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();

Cannot change csv file charset to windows-1251

I try to create a button that would download a csv file. I have to make the file using windows-1251 charset.
But no matter what I do the file ended up in utf-8. Right now I'm trying something like:
async createCsv(result) {
const arrData = result.data
const aliases = result.aliases
let csvContent = [
Object.keys(arrData[0]).map(item => aliases[item]).join(";"),
...arrData.map(item => Object.values(item).join(";"))
]
.join("\n")
.replace(/(^\[)|(\]$)/gm, "");
const data = new Blob([csvContent], {
type: "text/csv;charset=windows-1251;"
});
const link = document.createElement("a");
link.setAttribute("href", URL.createObjectURL(data));
link.setAttribute("download", (new Date).toLocaleString() + ".csv");
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
And the file is in utf-8.
Is there a way to change the charset?
looking for the same last day.
that's the answer that really works
blob with conversion to 8bit cp1251 or cp1252
in my project ends up with the following
import * as iconv from 'iconv-lite'
let outdata = this.bankf.getOutputFile();
const encoded = iconv.encode (outdata,'win1251');
var file = new Blob ([encoded], {type: 'text/plain;charset=windows-1251'});
var link = document.createElement("a");
var url = URL.createObjectURL(file);
link.setAttribute("href", url);
link.setAttribute("download", "filename.txt");
document.body.appendChild(link);
link.click();
setTimeout(function() {document.body.removeChild(link); window.URL.revokeObjectURL(url); }, 0);
still looking for other solution as iconv brings around 400kb code , but for now. at least it works

Download base64 encoded file

In React, I uploaded a file using:
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function() {
let base64data = reader.result;
uploadFile(base64data);
return;
}
This gives me a Base64 encoded text data:application/octet-stream;base64,JVBERi0xLj...
This is fine as when I decode 'JVBERi0xLj...' I get the correct text in case of a text file.
When a download request is made to the server I get the same data back but I'm having a difficulty downloading the file. I receive the same base64 encoded string in the response from the server but unable to open the downloaded file.
I have done the following:
const blob = new Blob([fetchData], { type: 'application/pdf' })
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = blob;
a.download = 'doc.pdf';
a.click();
Any ideas?
Note: The upload file is converted to base64 to avoid any http communication issues.
Solution following your suggestions:
let fetchDataModified = `data:application/pdf;base64,${fetchData }`;
let a = document.createElement("a");
a.href = fetchData;
a.download = 'doc.pdf';
a.click();
When converting to Base64 during upload the data type was set to 'application/octet-stream'. However, when downloading I changed that to 'application/pdf' following Vaibhav's suggestion and used createElement instead of createObjectURL and it worked. Thank you
“data:application/pdf” + the base64 string that you saved into our database

Saving a Uint8Array to a binary file

I am working on a web app that opens binary files and allows them to be edited.
This process is basically ondrop -> dataTransfer.files[0] -> FileReader -> Uint8Array
Essentially, I want to be able to save the modified file back as a binary file. Ideally as a file download with a specified file name.
There doesn't seem to be any standard method of doing this, and that sucks, because everything up to that point is well supported.
I am currently converting the array to a string using String.fromCharCode(), base64 encoding that, and using a data uri in a hyperlink like data:application/octet-stream;base64,.., along with the download attribute to specify filename.
It seems to work, but it's quite hacky and I think converting the raw bytes to a string might introduce encoding issues depending on the byte values. I don't want the data to become corrupt or break the string.
Barring that, is there a better/proper method for getting an array of bytes as a binary file to the user?
These are utilities that I use to download files cross-browser. The nifty thing about this is that you can actually set the download property of a link to the name you want your filename to be.
FYI the mimeType for binary is application/octet-stream
var downloadBlob, downloadURL;
downloadBlob = function(data, fileName, mimeType) {
var blob, url;
blob = new Blob([data], {
type: mimeType
});
url = window.URL.createObjectURL(blob);
downloadURL(url, fileName);
setTimeout(function() {
return window.URL.revokeObjectURL(url);
}, 1000);
};
downloadURL = function(data, fileName) {
var a;
a = document.createElement('a');
a.href = data;
a.download = fileName;
document.body.appendChild(a);
a.style = 'display: none';
a.click();
a.remove();
};
Usage:
downloadBlob(myBinaryBlob, 'some-file.bin', 'application/octet-stream');
(shorter) ES6 version of the top answer:
const downloadURL = (data, fileName) => {
const a = document.createElement('a')
a.href = data
a.download = fileName
document.body.appendChild(a)
a.style.display = 'none'
a.click()
a.remove()
}
const downloadBlob = (data, fileName, mimeType) => {
const blob = new Blob([data], {
type: mimeType
})
const url = window.URL.createObjectURL(blob)
downloadURL(url, fileName)
setTimeout(() => window.URL.revokeObjectURL(url), 1000)
}

Categories

Resources