How to download excel file with axios vuejs? - javascript

On the controller I return a path to where the excel file is located..Now I want to download that file
Below is my code:
reportExcel(val) {
axios
.get("/algn/api/report/" + val)
.then((res) => {
var url = res.data; // http://localhost.local/public/files/data.xlsx
const a = document.createElement("a");
a.href = url;
a.download = url.split("/").pop();
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
})
.catch((error) => {
console.log(error);
});
},
I am getting the error as "Excel cannot open the file "data.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". (The original excel file is still usable).
I have tried all the solutions which I found in google but nothing worked. Please help. Thanks

Try this:
reportExcel(val) {
axios
// add responseType
.get("/algn/api/report/" + val, {responseType : 'blob'})
.then((res) => {
const url = window.URL.createObjectURL(new Blob([res]));
const a = document.createElement("a");
a.href = url;
const filename = `file.xlsx`;
a.setAttribute('download', filename);
document.body.appendChild(link);
a.click();
a.remove();
})
.catch((error) => {
console.log(error);
});
},
Assuming the link gives correct excel file, we can inform that it is file (not the usual JSON) by specifying {responseType : 'blob'} in the request. Then, create the file using window.URL.createObjectURL(new Blob([res])). The rest is small adjustments to handle file instead of text.

Related

How can I fix this image download error in javascript?

This is my code:
function downloadImage(url) {
fetch(url, {
mode: 'no-cors',
})
.then(response => response.blob())
.then(blob => {
let blobUrl = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.download = url.replace(/^.*[\\\/]/, '');
a.href = blobUrl;
document.body.appendChild(a);
a.click();
a.remove();
})
}
var url = 'https://c4.wallpaperflare.com/wallpaper/203/636/834/minimalism-landscape-digital-
windows-11-hd-wallpaper-preview.jpg';
downloadImage(url)
i can successfully download the image but when I open the image it's shows Sorry, Photos can't open this file because the format is currently unsupported, or the file is corrupted
When I use unsplash image url in that time it's work well. Can anyone tell me please why it's happening and how can I fix this issue.
The issue here is the Response object , fetch is being called with mode:'no-cors', resulting in the response object to have type as "opaque" and hence using response.blob() will result into a Blob size of 0 and Blob type of "" (read more below in Response.blob()).
The mime-type is set as expected and your code works as expected but since you are making a cross origin request you are getting Response.blob() as empty and the file you subsequently save(download through anchor tag) has no data.
Read more about Response.blob()
Read more about Response.type
Read more about CORS Protocol
to validate the above try and console.log the blob like so :
function downloadImage(url) {
fetch(url, {
mode: 'no-cors',
})
.then(response => response.blob())
.then(blob => {
console.log(blob); //log the blob and check its size;
let blobUrl = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.download = url.replace(/^.*[\\\/]/, '');
a.href = blobUrl;
document.body.appendChild(a);
a.click();
a.remove();
})
}
Do like this because you're not defining MIME type while downloading the file.
return fetch(urlEndpoint, options)
.then((res) => res.blob())
.then((blob) => URL.createObjectURL(blob))
.then((href) => {
Object.assign(document.createElement('a'), {
href,
download: 'filename.png',
}).click();
});
or else you can do like this
download(filename,url) {
fetch(url, {
mode: 'no-cors',
})
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(uril => {
var link = document.createElement("a");
link.href = uril;
link.download = filename + ".png";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
}

Excel JS workbook to PDF (File gets corrupt)

I have downloaded a file through some options, using filesaver or [a]download, but only with the xlsx extension. When I try to download it as a .pdf, the file is downloaded, but it does get corrupted, and I am not able to view it, while the excel file is okay. The excel workbook is created using excel Js.
The piece of code that represents the problem is below.
private exportExcel(workbook: any, filename: string) {
workbook.xlsx.writeBuffer().then((data) => {
console.log(data);
let blob = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const anchor = document.createElement('a');
const url = URL.createObjectURL(blob);
anchor.href = url;
anchor.download = filename;
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
URL.revokeObjectURL(url);
const urlpdf = URL.createObjectURL(new Blob([data], {type: "application/pdf"}));
fetch(urlpdf).then(res => res.blob()).then(blob => {
const data = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = data;
a.download = 'file';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(data);
})
}).catch(err => console.log(err))
}
I have tryed it using fetch, not using blob (then I get an error) but none of the options exports a valid .pdf. Thanks in advance.
I am using angular framework

Open blob file stored in indexDB on ios/Ipad

Hello i download file using axios like so.
return axios({
method: "get",
url: URL,
responseType: "blob",
})
.then((response) => {
return {
...val,
blob: response.data,
};
})
.catch((_) => {
onError(val);
});
After that i store it in indexDB using Dexie.
const { id } = dataToSave;
return db.files.put(dataToSave, id);
I have file in db like blob
Next i want to save it like so:
download(myBlob, title, mimeType);
i try using filesaver,downloadjs or manualy
const { title, blob, mimeType } = material;
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
// the filename you want
a.download = title;
document.body.appendChild(a);
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}, 1000);
It will download file only right after i download it to blob (browser session).
When i refresh page i get error WebkitBlobResource:1.
Any workaround of problem ? To either download file (pdf,html) or open it in new or same tab.
For now store data as arraybuffer, not blob works.

handling file download from api call

In react, I am testing my file download based on John Culviner's solution mentioned in this post
axios.post('api/downloadMyFile',
data
).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]))
const a = document.createElement('a');
a.href = url;
a.download = "test.zip"
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
}).catch((err) => {
}
So file test.zip is getting downloaded. but when I tried to open it after saving it I am getting Compressed Zip folder error in windows.
Also, I noticed that I don't need to specify the name of the file in the line a.download = "test.zip" because the webservice is getting the file from shared storage and it already has a name.
So in this case, do I need to have the filename also in the response object? something like response.filename so that I could use it in the following line instead of naming it manually:
a.download = response.filename
The response.data returned from Axios is a JSON string. So creating a Blob from that JSON doesn't produce the correct object. From the Axios docs:
// responseType indicates the type of data that the server will
respond with
// options are: 'arraybuffer', 'document', 'json',
'text', 'stream'
// browser only: 'blob'
responseType: 'json',
// default
The simple fix is to tell Axios to provide the response in the form of a Blob. Then the URL.createObjectURL() will produce a URL to a file that is in the correct format.
axios.post('api/downloadMyFile', data, { responseType: 'blob' })
.then(blob=>{
const url = window.URL.createObjectURL(blob.data);
const a = document.createElement('a');
a.href = url;
a.download = "download.zip"
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})

How download Excel file in Vue.js application correctly?

I'm struggling to download an Excel file in xlsx format in my Vue.js application. My Vue.js application make post request to the Node.js application which download that Excel file from remote SFTP server. Backend application works without any problems.
In Vue.js application I use next code:
axios.post(config.backendHost + '/excel', {
file_name: fileName
}).then((response) => {
const url = URL.createObjectURL(new Blob([response.data], {
type: 'application/vnd.ms-excel'
}))
const link = document.createElement('a')
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
});
After downloading file by browser, file opens automatically and I am experiencing an error that looks like this:
We found a problem with some content .xlsx. Do you want us to try and recover as much as we can?
You need to add the response type as a third argument in your post call
{
responseType: 'blob'
}
Your final code like that
axios.post(config.backendHost + '/excel', {
file_name: fileName
}, {
responseType: 'blob'
}).then((response) => {
const url = URL.createObjectURL(new Blob([response.data], {
type: 'application/vnd.ms-excel'
}))
const link = document.createElement('a')
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
});
Or you can use the library FileSaver.js to save your file
import FileSaver from 'file-saver'
axios.post(config.backendHost + '/excel', {
file_name: fileName
}, {
responseType: 'blob'
}).then((response) => {
// response.data is a blob type
FileSaver.saveAs(response.data, fileName);
});
my case worked:
axios.get(`/api/v1/companies/${companyId}/export`, {
responseType: 'blob',
}).then((response) => {
const url = URL.createObjectURL(new Blob([response.data]))
const link = document.createElement('a')
link.href = url
link.setAttribute(
'download',
`${companyId}-${new Date().toLocaleDateString()}.xlsx`
)
document.body.appendChild(link)
link.click()
})

Categories