Generating a PDF report in Flask and sending the file to the client using:
send_file(file,as_attachement=False)
On the React JS end I have a function the handles the PDF file: Using Axios:
const receiveFile = (data) => {
if (data.data) {
let url = window.URL.createObjectURL(new Blob([data.data]));
let link = document.createElement("a");
link.href = url
link.setAttribute("download", data.filename)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
}
The file gets sent without issue and the receiveFile received the data properly; however, my browser is set to open PDF files. Instead I am being asked to download it. How do I fix the code so the browser displays the PDF when it is received.
Related
I am trying to expose a .zip in VueJS containing multiple files that are stored in a remote server.
I have tried at least with just one .csv file: the download works, but opening the archive fails because the .zip is recognised as invalid.
What I have tried to do is, this following this previous issue:
try {
const response = await axios.get(download_url, {
responseType:'blob'
});
const url = window.URL.createObjectURL(new Blob([response.data));
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "filename.zip");
document.body.appendChild(link);
link.click();
} catch (error) {
console.log(error);
}
That allows me to download the .zip, but again, it is invalid and I cannot open it.
Then, I would like to be able to do it with multiple "download_urls", i.e. with multiple files in the same .zip, but for now I would be happy to succeed at least with one file!
Thank you in advance with your help.
Let the link () be directly what you are getting from axios (axios.get(url))
To download multiple file in one zip you could let the server pack them and provide public link to download (we can elaborate on this if you need to)
Again use that public link from the server to download the zip
Use download_url and put it in a
In my application written in Ionic 5 and Angular 8, I am in need to download multiple PDF links (file) in the same page on click of the link. I tried but the PDF links are opening in browser. Request to help me achieve this functionality.
https://stackblitz.com/edit/ionic-yzzwov?file=pages%2Fhome%2Fhome.html
The download attribute appears normal when same-origin, otherwise it will appear the same as without download attribute.
list three solutions:
Package the file into a file type that cannot be opened directly by the browser, such as ZIP
Through forwarding by the back end, the back end requests a third-party resource and returns it to the front end, which saves the file using tools such as file-Saver
If the third-party resource the URL points to has CORS configured, you can request the file through XHR
downloadFileXHR(filePath, fileName) {
var xhh = new XMLHttpRequest()
xhh.open('get', filePath)
xhh.responseType = 'blob'
xhh.onreadystatechange = function () {
if (xhh.readyState === 4 && xhh.status === 200) {
var blob = new Blob([xhh.response])
var csvUrl = URL.createObjectURL(blob)
var link = document.createElement('a')
link.href = csvUrl
link.download = fileName
link.click()
}
}
xhh.send()
An Axios request to server response the content of a PDF as a binary string.
export const fetchPDFfile = async (id: string): Promise<string> => {
const { data } = await http.get<string>(`${baseUrl}/${id}.pdf`);
return data;
};
The response in Chrome devtools and also console logging the data is like:
%PDF-1.4
%âãÏÓ
2 0 obj <</ColorSpa ......
..........
startxref
10991
%%EOF
is defining string as the expected type of Axios response body, correct? or it should be (cast to) Blob?
Now I want to download this as a PDF file in the client-side. There are plenty of questions regarding this but none worked for me and also none had a clear answer.
So what I did so far was (in a React component):
const data = await fetchPDFfile(props.id);
const blob = new Blob([data], { type: 'application/pdf' });
const href = window.URL.createObjectURL(blob);
const theLink = document.createElement('a');
theLink.href = href;
theLink.download = props.id + '.pdf';
document.body.appendChild(theLink);
theLink.click();
document.body.removeChild(theLink);
This downloads a PDF file with 3 blank pages. The number of pages is correct the original doc should bee 3 pages. But I see the white paper.
const href = window.URL.createObjectURL(data); // istead of blob throw Error.
How should I convert and download this PDF file? In general, is the process above needed, or should I directly download it from the server? (something like what cordova-plugin-file-transfer does)
Scenario
You want the file to be downloaded when the user clicks the link.
Solution 1-
Directly put the link in <a> tag.
Cons- Error message can not be shown on the screen if something went wrong.
So it leads to the next solution.
Solution 2-
Hit the URL as an API and download the file if you get the success message.
For this, I use File-server.js
**Don't forget to set the {responseType: 'blob'}, while making the request
http.get<string>(`${baseUrl}/${id}.pdf`, {responseType: 'blob'})
as we don't want the response with Content-Type: application/json
sample code:
import FileSaver from 'file-saver';
downloadPdf() {
var blob = new Blob([data], {type: "application/pdf"});
FileSaver.saveAs(blob, "filename");
}
Firstly use Blob as generic argument for Promise.
I will use fetch API as it can be tested quite easily.
fetch('https://www.jianjunchen.com/papers/CORS-USESEC18.slides.pdf').then(x => x.blob()).then(b => console.log(b.type))
This will log "application/pdf" it the file is trully pdf.
If you got a blob that is not PDF and you will re-wrap it to Blob with pdf type you might break the data. If you got trully a string and you convert it to Blob with pdf type the file will be broken as the PDF would be invalid.
If you want to know if b is trully a blob just console.log(b instanceof Blob) and it should say true. If you have recieved trully a blob you do not have to create new one as you did in new Blob([data]).
This example works just fine:
fetch('https://www.jianjunchen.com/papers/CORS-USESEC18.slides.pdf').then(x => x.blob()).then(b => {
const url = window.URL.createObjectURL(b);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = "a.pdf";
a.click();
window.URL.revokeObjectURL(url);
})
Sorry for broken code style but I was unable to paste it properly.
How can i save the response from api which gives me excel file with data and name ?
I have below api which gives me the excel file and i have to save it at default location as is.
https://mydomain.dev.com/export
I have gone through the multiple articles on the web but everywhere its explained to save the data as excel file at client side which is not the my case. For me, file type and name is already decided at server side and i have to just save as is.
Thanks a lot in advance
Here's how I usually handle this:
I start out by fetching the file and then use downloadjs to download the blob
async downloadFile() {
const res = await fetch("https://mydomain.dev.com/export");
const blob = res.blob();
// from downloadjs it will download your file
download(blob, "file.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
I always use this script to do this:
function downloadFile(absoluteUrl) {
var link = document.createElement('a');
link.href = absoluteUrl;
link.download = 'true';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
};
So just :
downloadFile("https://mydomain.dev.com/export");
It is working, but i hope that there is better solution.
I have a web application for downloading files. Everything works fine except when I want to download a file more than 1GB .
This is my java code:
InputStream in = new FileInputStream(new File(folderFile.getAbsolutePath()));
org.apache.commons.io.IOUtils.copy(in, response.getOutputStream());
response.flushBuffer();
in.close();
HTTP request :
$http({
method:'get',
url:this.apiDownloadFileUrl,
responseType:'arraybuffer',
cache: false
});
and here is client side: I got data successfully on client, but when I make it Blob , if the data size was more than 500MB , nothing happened and it wasn't downloaded. Also, I can download 300MB ...
How can I check if it is a memory problem, or a server problem? ... When I download from gmail , I can download more than 1GB .
.success(function(databack) {
var file = new Blob([ databack ], {
type : 'application/csv'
});
var fileURL = window.URL.createObjectURL(file);
var a = document.createElement('a');
a.href = fileURL;
a.target = '_blank';
a.download = data;
document.body.appendChild(a);
a.click();
Have you tried using the copyLarge() methods from IOUtils? For the copy() methods the JavaDoc says:
"For large streams use the copyLarge(InputStream, OutputStream) method."
You should check the response message first, and decide which side fire the problem.
As my experience, you should check whether the file was cached by the browser rather than any problems~