I am trying to create a custom Word document output using Hogan and Blob. It works as expected for .md files but I am trying to generalize to .docx or other file types.
From following an online tutorial this is what I have so far:
app.markdown = app.template.render(data);
updateLink(
app.markdown,
"text/plain",
"example.md",
document.getElementById("mdLink")
);
app.markdown is valid markdown as expected. And this is the updateLink function:
function updateLink(content, contentType, filename, link) {
const blob = new Blob([content], { type: contentType });
const url = window.URL.createObjectURL(blob);
window.URL.revokeObjectURL(link.href);
link.href = url;
link.download = filename;
}
So, the above works for .md files, but when I try changing "example.md" to "example.docx" and "text/plain" to "application/msword", and clicking the link results in a .docx file being downloaded but Word is not able to open the content. So what format do I need to convert my markdown to so that it works natively with Word? (Ideally I would also be able to preserve some of the markdown styling into the Word styling). Thanks!
Related
I have a question for a confidential project that I am working on, so I cannot share too much detail. Hopefully the below code is enough to at least provide some suggestions as to what can be wrong.
Whenever I programmatically download a word blob from an anchor link, it fails on the second try only saying that it could not open the file as it is corrupt. I also see that the file is about 14KB larger.
// route file
var buffer = await Packer.toBuffer(doc); // create buffer using DOCX.js Packer
res.header(
"output_name",
`${unique_output_str}.docx` // <--- this is a template string which changes each time the document is generated, based on unique attributes that the user selects
);
res.send(Buffer.from(buffer));
How I download:
var response = await axios.patch(
path, // <--- this is defined elsewhere (not relevant to question)
formData, // <--- this is defined elsewhere (not relevant to question)
{ responseType: "blob" }
);
const url = URL.createObjectURL(
new Blob([response.data], {
type:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
})
);
const link = document.createElement("a");
link.href = url;
link.download = response.headers["output_name"];
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
How come my first download after form submission produces a good docx file, but resubmitting the form with other data (changes in text for text input) produces corrupt files?
I want to rename a blob file downloaded from a server. I looked for other solutions but they mainly deal with the created anchor link and setting name to anchor. I tried this approach:
getRenamed(title): void {
this.docTitle = title;
this.requestService.download(title).subscribe((response) => {
let thefile = new Blob([response], {
type:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
let url = window.URL.createObjectURL(thefile);
window.open(url);
});
}
But the problem with this approach is that it creates a random filename. And I want to give it a specific filename.
I am using laravel. I don't want to return url of the pdf to the front-end, as it's located in google cloud and i don't want the link to be seen. That's why I need to return pdf directly and let user download it through browser.
I tried this:
return response()->json(['data' => file_get_contents(Storage::url($cert_path))]);
//this says: malformed utf-8 characters, 500 error
Then I googled and tried this:
$file = file_get_contents(Storage::url($cert_path));
$file = mb_convert_encoding($file, 'HTML-ENTITIES', "UTF-8");
return response()->json(['data'=>$file]);
//this returns pdf, but in front, when i have a download code of js, when I download it, the whole pdf is empty.
The url of the pdf is correct, as I can go to that url and see the pdf.
how do I return pdf successfully?
I will also include javascript download code:
var blob = new Blob([pdf], {
type: 'application/pdf'
});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "ffa.pdf";
link.click();
I am using pdf js out of the box.
The problem is that I am using a blob "blob:http://localhost:9001/12fc5fc1-bd5f-4af1-a434-0e38cb55ead"
Because of this, the url doesnt contain ".pdf" so when viewer.js parses it, it dowloads as "document.pdf"
If there anyway to use a custom file name in this situation?
Thanks
Well, there are a couple of problems here:
1) When you use Blob you are pointing to an address of memory of your browser, thats the main reason you get that name.
2) to get a pdf, you should set your blob with the type of pdf, here is an example:
var blob = new Blob([data], {type: 'application/pdf'});
var url = window.URL.createObjectURL(blob);
you will get that extrange url but with a pdf extention.
The same you can do with zip or other type of file. Hope this answer helps!
I have a base64 string, file type. File type can be image, text or even pdf. I need to show download link and when user clicks it should start downloading as expected file.
Concisely, server sends me file as base64 string, and I need to save it as file on browser. How can I save base64 string as file on browser? It would be best if solution works on IE9 also.
You can use download.js.
download(base64String, filename, mimeType)
Adapted from https://gist.github.com/RichardBray/23decdec877c0e54e6ac2bfa4b0c512f to work on Firefox.
function downloadBase64File(contentBase64, fileName) {
const linkSource = `data:application/pdf;base64,${contentBase64}`;
const downloadLink = document.createElement('a');
document.body.appendChild(downloadLink);
downloadLink.href = linkSource;
downloadLink.target = '_self';
downloadLink.download = fileName;
downloadLink.click();
}
You can do this from js to download pdf.
Use:
document.location = 'data:application/pdf;base64,' + base64String
You get the effect you desire (web page showing a link, and when user clicks, the save as dialog pops up) when the appropriate response headers are present when the browser requests the resource:
Content-Disposition: attachment; filename="yourfilename.extension"
If you're getting the file from the server as a base64 string embedded in your html, perhaps you can skip the embedding and simply embed a direct link to the file on your server, having the server serve it up to the user.
Related SO on Content-Disposition