Unable to open PDF while converting it from a HTML in react - reactjs

I am getting an html file from a backend application and now saving it in pdf format in react. However, unable to open it in adobe :(
CreateFile(data, contentType) {
let file;
if (contentType === "text/html") {
// file = new Blob([data], { type: contentType });
file = new Blob([new Uint8Array(data)], { type: contentType });
}
saveDocument() {
let contentType = "application/pdf";
let file = this.createFile(data,
contentType.toLowerCase());
if (window.navigator.msSaveOrOpenBlob) // IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
else { // others apart from Safari and Opera mini
var a = document.createElement("a"),
url = window.URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
can anyone help?

I suggest you using a library like wkhtmltopdf in your backend to convert the html into pdf before sending it.

Related

Download file in ReactJS app preserving the original filename

I'm serving pdf file with nodejs/koa2
ctx.body = readableStream;
ctx.attachment('file.pdf');
The file successfully arrives and on the client side i receive it with ReactJS application:
const document = useSelector(selectors.getFile(documentFile.key));
if (document) {
window.open(window.URL.createObjectURL(new Blob([document], { type: "application/octet-stream" })), "_self");
}
...
const openFile = useCallback((key) => {
dispatch(actions.getFile.request(key))
}, [dispatch]);
It successfully downloads the file, but completely ignores response header Content-Disposition: attachment; filename="file.pdf" and downloads it under the name like d3aa7870-bd35-4645-a926-294392343cfc which is taken from the BLOB url: Request URL: blob:http://localhost:3000/d3aa7870-bd35-4645-a926-294392343cfc.
Could you please advise how to correctly save it under the name of file.pdf on the client side?
just create an element and set download attribute with file name
const document = useSelector(selectors.getFile(documentFile.key));
if (document) {
const url =window.URL.createObjectURL(new Blob([document], { type: "application/octet-stream" }))
const a = document.createElement("a");
a.style = "display: none";
document.body.appendChild(a);
a.href = url;
a.download = "fileName";
a.click();
window.URL.revokeObjectURL(url);
}

Download a zip file in reactjs without any plugins

I am getting a response from a rest api whose Content-Type is text/html and Content-Encoding is gzip.
I tried to download it using blob
const blob = new Blob([res], { type: 'application/gzip' });
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
document.body.appendChild(a);
a.click();
But the downloaded gz file was not able to open (seems to be corrupted).
can some one help me with downloading zip file in reactjs.
Edit: require a solution without using any external plugins
you can use jszip npm module.
For example:
var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
var img = zip.folder("images"); //images is the folder which will be zip
img.file("smile.gif", imgData, {base64: true});
zip.generateAsync({type:"blob"}).then(function(content) {
saveAs(content, "example.zip");
});
To use it without jszip, you can try the following code:
function str2bytes (str) {
var bytes = new Uint8Array(str.length);
for (var i=0; i<str.length; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}
and its usage:
var blob = new Blob([str2bytes(myData)], {type: "application/zip"});
saveAs(blob, "data.zip");
But jszip is a better alternative approach.

How to download and save a pdf file from ASP.NET Core API from database in Angular?

My Angular project cannot download (for Save as) a pdf file via ASP.NET core Api. The pdf file is stored in SQL server.
I tried a number of ways posted in stackoverflow but none of the ones works for me. Some examples download a pdf file but if It was tried to open, It caught an error '..not support...damaged'.
API (I perfer returning a row instead of a single vaule byte[] only)
[HttpGet]
[Route("detail/{studentid:int}/{reportSeq:int}")]
public async Task<ActionResult<byte[]>> GetStudentAcademicReport2(int StudentID, int ReportSeq)
{
var report = await _context.AcademicReportDetails.FromSql("select * from [dbo].[ufnStudentAcademicReport] (8213, 8158)").FirstOrDefaultAsync();
if (report == null)
{
return NotFound();
}
return report.ReportContent;
}
Not working in Angular
this.httpClient.get("https://localhost:44369/api/values/detail/8213/8158", { responseType: 'blob'})
.subscribe(response => {
console.log(response);
const url = window.URL.createObjectURL(new Blob([response]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf');
document.body.appendChild(link);
link.click();
Not working in Angula
this.httpClient.get("http://localhost:5000/api/studentacademicreports/detail/8213/8158", { responseType: 'arraybuffer'})
.subscribe(response => {
console.log(response);
const file = new Blob([response], {type: 'application/pdf'});
const fileURL = window.URL.createObjectURL(file);
let objectURL = 'data:image/jpeg;base64,' + response;
let fileURL2 = this.sanitizer.bypassSecurityTrustUrl(objectURL);
const link = document.createElement('a');
link.href = fileURL;
link.download = 'sample.pdf';
link.click();
Working in Windows form project
cmd.CommandText = "select * from [dbo].[ufnStudentAcademicReport] (8213, 8158)";
cmd.CommandType = CommandType.Text;
if (cmd.Connection.State != ConnectionState.Open)
{
cmd.Connection.Open();
}
DbDataReader read = cmd.ExecuteReader();
if (read.HasRows)
{
while (read.Read())
{
byte[] b = null;
b = (byte[])read.GetValue(read.GetOrdinal("ReportContent"));
System.IO.File.WriteAllBytes(#"c:\temp\test.pdf", b);
}
}
Not working in Windows form project via API
HttpClient http = new HttpClient();
var NewResponse = await http.GetAsync("https://localhost:44369/api/values/detail/8213/8158");
var content = await NewResponse.Content.ReadAsByteArrayAsync();
System.IO.File.WriteAllBytes(#"c:\temp\test111.pdf", content);
As you can see from my above sample codes that it works if a pdf in varbinary(Max) is downloaded directly using SQLCommand but doesn't work if a pdf is downloaded via API. I am suspecting that API returns byte[] in Json format. Student photos are displayed successfully via the api without any issue but downloading Pdf file doesn't work. What causes downloaded PDF files corrupted in my codes?
When you return byte[] from ASP.NET Core action it's result is base64 encoded and that's why you get a "corrupted" file. You have to return FileResult from action in order to let the framework process binary data properly
public async Task<FileResult> GetStudentAcademicReport2(int StudentID, int ReportSeq)
{
var report = await _context.AcademicReportDetails.FromSql("select * from [dbo].[ufnStudentAcademicReport] (8213, 8158)").FirstOrDefaultAsync();
if (report == null)
{
return NotFound();
}
return File(report.ReportContent, "application/pdf", "test.pdf");
}

Download A File in ReactJS

I am trying to download a file using ReactJS. I have the link of the file and I can actually open the file through my browser. After several attempts. Here, is my function to download the file.
saveFile(filename) {
let blob = new Blob();
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
const a = document.createElement('a');
document.body.appendChild(a);
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}, 0)
}
}
Unfortunately, I get the pop-up as expected but I get a 0 MB file downloaded.
Any ideas on how to do around this? Note that the file is mp3

Download .xls file via POST

I am using AngularJS and in POST request download file .xls
this.$http.post('/api/rept/detc/xls', params).then((response) => {
let blob = new Blob([response], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
}),
objectUrl = URL.createObjectURL(blob);
window.open(objectUrl);
})
But then download file without format with name (in this format: c65c45f8-e6a3-458d-xxxx-43c5fcxxxxx).
How can I download without FileSave package?
Similar approach that worked for me:
this.$http.post('/api/rept/detc/xls', params).then((response) => {
let blob = new Blob([response]);
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = 'filename_here';
a.target = '_blank';
a.click();
})

Resources