Trigger print preview of base64 encoded PDF from javascript - javascript

I've looked around stackoverflow trying to find a way to do this for a while now, and can't find a suitable answer. I need to be able to load a PDF in either a new window or an iframe via a base64 encoded string and trigger a print preview of it immediately after loading it. I can easily load the PDF using both of those methods, but can't actually get it to show the print preview properly. Here is what I've tried:
Using embed element in a new window. Calling window.print() is blank, even after the content is loaded.
Using a hidden, dynamically created iframe with src="data:application/pdf;base64,JVBERi0..." and calling myFrame.contentWindow.print(). But this gives a CORS error. I'm not sure why, because I'm not loading a new domain through the iframe, just content.
Open a new window with only an iframe element like the one in #2 and calling a print on the whole window. This also shows a blank white page.
Open a new window with the data uri and print it. window.open('data:application/pdf;base64,JVBERi0...').print();. This doesn't work either, as it doesn't even show a print preview at all. I've also tried delaying it with a setTimeout but that doesn't do anything either.
At this point I'm very confused as to why none of these work, especially because in Chrome it display's custom menu bars like this:
And if I click the actual print icon there, the print preview is perfect. Whatever Chrome is doing when I click that button is exactly what I want to accomplish. Is there anyway to trigger that functionality? Or is there another way to accomplish what I want? And just to clarify, I only need this to work in Chrome, I don't need to worry about other browsers.

Here is a solution for point #3:
Open a new window with only an iframe element like the one in #2 and calling a print on the whole window. This also shows a blank white page.
In your case, it's throwing CORS error because it looks like for iframe src you are giving the base64String not the URL. Here is what you can do
Take your base64String, convert it to a Blob
Generate a URL from the Blob
Provide the generated URL to iframe.
After this you can print the content using iframe.contentWindow.print();
Here is the code to convert base64 to Blob
'use strict';
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize),
byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
}
const contentType = "application/pdf",
b64Data = "YourBase64PdfString", //Replace this with your base64String
blob = this.b64toBlob(b64Data, contentType),
blobUrl = URL.createObjectURL(blob);
Use blobUrl to the src of Iframe, once it's done, you can call print() on iframe as shown below
const iframeEle = document.getElementById("Iframe");
if (iframeEle) {
iframeEle.contentWindow.print();
}
Hope this helps...
More details on base64 to Blob is here Creating a Blob from a base64 string in JavaScript

you can use this,
function "printPreview(binaryPDFData)" to get print preview dialog of binary pdf data.
printPreview = (data, type = 'application/pdf') => {
let blob = null;
blob = this.b64toBlob(data, type);
const blobURL = URL.createObjectURL(blob);
const theWindow = window.open(blobURL);
const theDoc = theWindow.document;
const theScript = document.createElement('script');
function injectThis() {
window.print();
}
theScript.innerHTML = `window.onload = ${injectThis.toString()};`;
theDoc.body.appendChild(theScript);
};
b64toBlob = (content, contentType) => {
contentType = contentType || '';
const sliceSize = 512;
// method which converts base64 to binary
const byteCharacters = window.atob(content);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {
type: contentType
}); // statement which creates the blob
return blob;
};

Related

Use gmail-tester attachment data (PDF) with pdf-lib

pdf-lib I am using gmail-tester to pull down emails and I want to make PDF attachments into strings with pdf-lib
If I log out what I am getting back from email-tester for a PDF attachment it looks like:
data: 'JVBERi0xLjYKJeLjz9MKMSAwIG9iagoKPDwKL1N1YnR5cGUgL0Zvcm0KL1R5cGUgL1hPYmplY3QKL01hdHJpeCBbMSAwIDAgMSAwIDBdCi9Gb3JtVHlwZSAxCi9SZXNvdXJjZXMgCjw8Ci9Db2xvclNwYWNlIAo8PAovRGVmYXVsdFJHQiAyIDAgUgo-PgovRXh0R1N0YXRlIAo8PAovR1MxIAo8PAovb3AgdHJ1ZQo-Pgo-PgovUHJvY1NldCBbL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSV0KL0ZvbnQgCjw8Ci9GMSAzIDAgUgo-PgovWE9iamVjdCAKPDwKL0ltMSA0IDAgUgovSW0yIDUgMCBSCi9JbTAgNiAwIFIKPj4KPj4KL0xlbmd0aCAxODM3Ci9CQm94IFswIDAgMjg1IDUwMF0KPj4Kc3RyZWFtCnENcQ0yODUgMCAwIDUwMCAwIDAgY20NcQ1CVA03IFRyDS9GMSAxLjAgVGYNMC4yNDE3NSAwLjA0MTgwIC0wLjA3MzMzIDAuMTM3ODAgMC4wMDA1OCAwLjQ4NzEyIFRtDTAuMDAwMDAgLTAuODQyMjcgVGQNKFwwMDBcMDY1KSBUag0vRjEgMS4wIFRmDTAuMjQxNzUgMC4wNDE4MCAtMC4wNzMzMyAwLjEzNzgwIDAuMDAwNTggMC40ODcxMiBUbQ0wLjU0MDUzIC0wLjg0MjI3IFRkDShcMDAwXDA0MykgVGoNL0YxIDEuMCBUZg0wLjI0MTc1IDAuMDQxODAgLTAuMDczMzMgMC4xMzc4MCAwLjAwMDU4IDAuNDg3MTIgVG0NMS4yMzE5MyAtMC44NDIyNyBUZA0oXDAwMFwwNTcpIFRqDS9GMSAxLjAgVGYNMC4yNDE3NSAwLjA0MTgwIC0wLjA3MzMzIDAuMTM3ODAgMC4wMDA1OCAwLjQ4NzEyIFRtDTEuOTk0MTQgLTAuODQyMjcgVGQNKFwwMDBcMDYyKSBUag0vRjEgMS4wIFRmDTAuMjQxNzUgMC4wNDE4MCAtMC4wNzMzMyAwLjEzNzgwIDAuMDAwNTggMC40ODcxMiBUbQ0yLjY0OTkwIC0wLjg0MjI3IFRkDShcMDAwXDA1NikgVGoNL0YxIDEuMCBUZg0wLjI0MTc1IDAuMDQxODAgLTAuMDczMzMgMC4xMzc4MCAwLjAwMDU4IDAuNDg3MTIgVG0NMy4yMjYwNyAtMC44NDIyNyBUZA0oXDAwMFwwNDcpIFRqDUVUDS9JbTAgRG8NUQ1xDUJUDTcgVHINL0YxIDEuMCBUZg0wLjI0MTc1IDAuMDQxODAgLTAuMDczMzMgMC4xMzc4MCAwLjAwMDU4IDAuMTM3MTIgVG0NMCAtMC44NDIyNyBUZA0oXDAwMFwwNjUpIFRqDS9GMSAxLjAgVGYNMC4yNDE3NSAwLjA0MTgwIC0wLjA3MzMzIDAuMTM3ODAgMC4wMDA1OCAwLjEzNzEyIFRtDTAuNTQwNTMgLTAuODQyMjcgVGQNKFwwMDBcMDQzKSBUag0vRjEgMS4wIFRmDTAuMjQxNzUgMC4wNDE4MCAtMC4wNzMzMyAwLjEzNzgwIDAuMDAwNTggMC4xMzcxMiBUbQ0xLjIzMTkzIC0wLjg0MjI3IFRkDShcMDAwXDA1NykgVGoNL0YxIDEuMCBUZg0wLjI0MTc1IDAuMDQxODAgLTAuMDczMzMgMC4xMzc4MCAwLjAwMDU4IDAuMTM3MTIgVG0NMS45OTQxNCAtMC44NDIyNyBUZA0oXDAwMFwwNjIpIFRqDS9GMSAxLjAgVGYNMC4yNDE3NSAwLjA0MTgwIC0wLjA3MzMzIDAuMTM3ODAgMC4wMDA1OCAwLjEzNzEyIFRtDTIuNjQ5OTAgLTAuODQyMjcgVGQNKFwwMDBcMDU2KSBUag0vRjEgMS4wIFRmDTAuMjQxNzUgMC4wNDE4MCAtMC4wNzMzMyAwLjEzNzgwIDAuMDAwNTggMC4xMzcxMiBUbQ0zLjIyNjA3IC0wLjg0MjI3IFRkDShcMDAwXDA0NykgVGoNRVQNL0ltMSBEbw1RDXENQlQNNyBUcg0vRjEgMS4wIFRmDTAuMjQxNzUgMC4wNDE4MCAtMC4wNzMzMyAwLjEzNzgwIDAuMDAwNTggMC44MzExMiBUbQ0wLjAwMDAwIC0wLjg0MjI3IFRkDShcMDAwXDA2NSkgVGoNL0YxIDEuMCBUZg0wLjI0MTc1IDAuMDQxODAgLTAuMDczMzMgMC4xMzc4MCAwLjAwMDU4IDAuODMxMTIgVG0NMC41NDA1MyAtMC44NDIyNyBUZA0oXDAwMFwwNDMpIFRqDS9GMSAxLjAgVGYNMC4yNDE3NSAwLjA0MTgwIC0wLjA3MzMzIDAuMTM3ODAgMC4wMDA1OCAwLjgzMTEyIFRtDTEuMjMxOTMgLTAuODQyMjcgVGQNKFwwMDBcMDU3KSBUag0vRjEgMS4wIFRmDTAuMjQxNzUgMC4wNDE4MCAtMC4wNzMzMyAwLjEzNzgwIDAuMDAwNTggMC44MzExMiBUbQ0xLjk5NDE0IC0wLjg0MjI3IFRkDShcMDAwXDA2MikgVGoNL0YxIDEuMCBUZg0wLjI0MTc1IDAuMDQxODAgLTAuMDczMzMgMC4xMzc4MCAwLjAwMDU4IDAuODMxMTIgVG0NMi42NDk5MCAtMC44NDIyNyBUZA0oXDAwMFwwNTYpIFRqDS9GMSAxLjAgVGYNMC4yNDE3NSAwLjA0MTgwIC0wLjA3MzMzIDAuMTM3ODAgMC4wMDA1OCAwLjgzMTEyIFRtDTMuMjI2MDcgLTAuODQyMjcgVGQNKFwwMDBcMDQ3KSBUag1FVA0vSW0yIERvDVENDVENUQ0KZW5kc3RyZWFtIAplbmRvYmoKCjIgMCBvYmoKWy9JQ0NCYXNlZCA3IDAgUl0KZW5kb2JqCgozIDAgb2JqCgo8PAovTmFtZSAvRjEKL1N1YnR5cGUgL1R5cGUwCi9CYXNlRm9udCAvV1RVVExSK09sZFN0YW1wZXIKL1R5cGUgL0ZvbnQKL0VuY29kaW5nIC9JZGVudGl0eS1ICi9EZXNjZW5kYW50Rm9udHMgWzggMCBSXQovVG9Vbmljb2RlIDkgMCBSCj4-CmVuZG9iagoKNCAwIG9iagoKPDwKL05hbWUgL1gKL0RlY29kZVBhcm1zIAo8PAovSFNhbXBsZXMgWzEgMSAxIDFdCi9Db2x1bW5zIDI4NQovUm93cyA1MDAKL0NvbG9ycyAzCi9WU2FtcGxlcyBbMSAxIDEgMV0KL1FGYWN0b3IgMC4wCi9CbGVuZCAxCi9Db2xvclRyYW5zZm9ybSAxCj4-Ci9CaXRzUGVyQ29tcG9uZW50IDgKL0xlbmd0aCAxMDc5OAovQ29sb3JTcGFjZSAvRGV2aWNlUkdCCi9JbnRlbnQgL1JlbGF0aXZlQ29sb3JpbWV0cmljCi9IZWlnaHQgNTAwCi9TdWJ0eXBlIC9JbWFnZQovRmlsdGVyIC9EQ1REZWNvZGUKL1R5cGUgL1hPYmplY3QKL1dpZHRoIDI4NQovU01hc2sgMTAgMCBSCj4-CnN0cmVhbQr_2P_uAA5BZG9iZQBkgAAAAAH_2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf_AABEIAfQBHQMBEQACEQEDEQH_xAGiAAAABgIDAQAAAAAAAAAAAAAHCAYFBAkDCgIBAAsBAAAGAwEBAQAAAAAAAAAAAAYFBAMHAggBCQAKCxAAAgEDBAEDAwIDAwMCBgl1AQIDBBEFEgYhBxMiAAgxFEEyIxUJUUIWYSQzF1JxgRhikSVDobHwJjRyChnB0TUn4VM2gvGSokRUc0VGN0djKFVWVxqywtLi8mSDdJOEZaOzw9PjKThm83UqOTpISUpYWVpnaGlqdnd4eXqFhoeIiYqUlZaXmJmapKWmp6ipqrS1tre4ubrExcbHyMnK1NXW19jZ2uTl5ufo6er09fb3-Pn6EQACAQMCBAQDBQQEBAYGBW0BAgMRBCESBTEGACITQVEHMmEUcQhCgSORFVKhYhYzCbEkwdFDcvAX4YI0JZJTGGNE8aKyJjUZVDZFZCcKc4OTRnTC0uLyVWV1VjeEhaOzw9Pj8ykalKS0xNTk9JWltcXV5fUoR1dmOHaGlqa2xtbm9md3h5ent8fX5_dIWGh4iJiouMjY6Pg5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6vr_2gAMAwEAAhEDEQA_AN_j37r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvde9-691737r3Xvfuvd'... 452952 more characters,
filename: 'MISC.pdf',
mimeType: 'application/pdf'
I have been trying to pass this data pdf-lib into using either:
var byteCharacters = atob(data);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
this.document = await pdfLib.getDocument([byteArray]).promise
or just:
this.document = await pdfLib.getDocument({data}).promise
Both of these result in errors indicating the PDF is malformed. Does anyone have an idea what to do?
Oh, looks like it works if I use an older version of pdf-lib
"pdfjs-dist": "2.3.200",
and do:
this.document = await pdfLib.getDocument(Buffer.from(data, 'base64')).promise
then it works.

Downloading base64 pdf on Safari

I have a POST call that returns a base64 PDF. When I call this endpoint I convert it to a Blob and then download it. This works fine in all browsers except for Safari.
openPdf = () => {
const sendObj = {
fakeValue: 'test'
};
axios.post('https://fakeendpoint.com/create-pdf', sendObj)
.then((res) => {
const base64URL = res.data;
const binary = atob(base64URL.replace(/\s/g, ''));
const len = binary.length;
const buffer = new ArrayBuffer(len);
const view = new Uint8Array(buffer);
for (let i = 0; i < len; i += 1) {
view[i] = binary.charCodeAt(i);
}
// create the blob object with content-type "application/pdf"
const blob = new Blob([view], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
a.href = url;
a.download = 'Test.pdf';
a.target = '_blank';
a.click();
});
}
How can I get this to work in Safari?
Seems like Safari doesn't follow the standards for the a tag. I believe this previous SO post identifies the root cause. From the comments in the linked answer:
Note that specifying a target attribute in Safari seems to override the download attribute (this does not seem to be the case in Chrome, Firefox or Opera).
Try removing a.target = '_blank' in your code above and then testing it. It should work!
Unfortunately, I'm not sure how you would open it in a new tab with that change.
from a test I made - this occurs only when the PDF is too big. (and only on mobile Safari)
I assume it is related to the length of the URL.
The only drawback from removing target="_blank" is that if the user click on "back" it will loose the previous page state.

Converting a text XHR-Response to arraybuffer

I'm making an XHR request. At the time of making the request, I don't know whether the URL will return an image or not, so I'm setting xhr.responseType="text"
If the response returns with a Content-Type of image/png [or any other image MIME type], I'm making another request with xhr.responseType="arraybuffer". I then use the arraybuffer that's returned to render the image:
var uInt8Array = new Uint8Array(arraybuffer);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--) {
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var base64 = window.btoa(data);
//use this base64 string to render the image
Is there any way I can avoid making the second request?
I tried doing this -
var buf = new ArrayBuffer(responseText.length);
var bufView = new Uint8Array(buf);
for (var i=0, i<responseText.length; i++) {
bufView[i] = responseText.charCodeAt(i);
}
return buf;
but the responseText isn't the same as the data in the first code sample, and the resultant ArrayBuffer doesn't render the image correctly.
I had the same problem with a PDF being corrupted, but the handler is generic and handles text, JSON and files.
The easiest way to solve this is to do it the other way round: Always make the request with:
xhr.responseType = "blob";
Then when you want the response as text, just convert the binary data to text:
xhr.response.text().then(text => {
// do something
});
Having binary as the default return type I can just convert that to text where needed.

Convert an Image DataUrl to Blob in JavaScript with Webkit Fallback?

I have an image represented as data URL. I want this image to be converted into a blob.
I use the following method for this purpose:
function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var arrayBuffer = new ArrayBuffer(byteString.length);
var _ia = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteString.length; i++) {
_ia[i] = byteString.charCodeAt(i);
}
var dataView = new DataView(arrayBuffer);
var blob = new Blob([dataView], { type: mimeString });
return blob;
}
This function is working but as I found here: Blob support the blob sometimes need the webkit prefix to work. I know that for URL I could use the fallback with
var _URL = URL || webkitURL;
How do I have to include the webkit prefix version as a fallback for older browsers in my function? Do I have to use BlobBuilder() instead on Blob()?
Best way to feature detect support for Blob is try and catch
function supportsBlob() {
try {
return !!new Blob();
} catch (e) {
return false;
}
}

Window.Open with PDF stream instead of PDF location

Based on the question Open PDF in new browser full window, it looks like I can use JavaScript to open a new window with a PDF file with the following code:
window.open('MyPDF.pdf', '_blank');
I'd like to do so on a return trip from the server by adding a byte array instead of the file name to use as the URL location in window.open
I'm currently returning PDF files like this:
Response.Clear();
Response.ContentType = "application/pdf";
Response.BinaryWrite(pdfByteArray);
Response.Flush();
Is there a way to open a new window with a PDF byte array in javascript.
Something like this:
var script = "window.open('" + pdfByteArray + "', '_blank');";
ScriptManager.RegisterClientScriptBlock(Parent.Page, typeof(Page), "pdf", script, true);
It looks like window.open will take a Data URI as the location parameter.
So you can open it like this from the question: Opening PDF String in new window with javascript:
window.open("data:application/pdf;base64, " + base64EncodedPDF);
Here's an runnable example in plunker, and sample pdf file that's already base64 encoded.
Then on the server, you can convert the byte array to base64 encoding like this:
string fileName = #"C:\TEMP\TEST.pdf";
byte[] pdfByteArray = System.IO.File.ReadAllBytes(fileName);
string base64EncodedPDF = System.Convert.ToBase64String(pdfByteArray);
NOTE: This seems difficult to implement in IE because the URL length is prohibitively small for sending an entire PDF.
Note: I have verified this in the latest version of IE, and other browsers like Mozilla and Chrome and this works for me. Hope it works for others as well.
if (data == "" || data == undefined) {
alert("Falied to open PDF.");
} else { //For IE using atob convert base64 encoded data to byte array
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
var byteCharacters = atob(data);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var blob = new Blob([byteArray], {
type: 'application/pdf'
});
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else { // Directly use base 64 encoded data for rest browsers (not IE)
var base64EncodedPDF = data;
var dataURI = "data:application/pdf;base64," + base64EncodedPDF;
window.open(dataURI, '_blank');
}
}
Adding to #Dinesh's answer to handle Not allowed to navigate top frame to data URL error in Chrome and Edge
if (data == "" || data == undefined) {
// Log Error: PDF data not available
} else {
var byteCharacters = atob(data);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var file = new Blob([byteArray], { type: 'application/pdf;base64' });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// For IE
window.navigator.msSaveOrOpenBlob(file, 'mypdf.pdf');
} else {
// For non-IE
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
}

Categories