0

I have a base64 text of a pdf file, that I need to open the print dialog for.

So what I did for now is to create a new window, embedding that into the window for the user to manually click on the "print" at the embed toolbar.

Embed Toolbar

var windowContent = '<!DOCTYPE html>';
windowContent += '<html>'
windowContent += '<head><title>Print</title></head>';
windowContent += '<body style=\"margin:0; padding:0; height:99.5vh\">'
windowContent += '<embed width=100% height=100% src="data:application/pdf;base64,' + dataUrl + '">';
windowContent += '</body>';
windowContent += '</html>';
var printWin = window.open('','','width=1000,height=1000');
printWin.document.open();
printWin.document.write(windowContent);
printWin.document.close();
printWin.focus();
//printWin.print();

The commented out print is because the embed loads the pdf async and it tries to print a blank page instead.

I cannot use external JS Libraries like "pdf.js" due to internal security reasons.

What I thought is, that if the embed has that "print" button, if it would be possible to trigger that by code?

Is this even possible?


Edited code due to Comment of Jan Pfeifer: This still does not work properly. The Page is being loaded, but the print is not executing.

function myPrint(win) {
  win.print();
}

var windowContent = '<!DOCTYPE html>' +
  '<html>' +
  '<head><title>Print MeasurementJob</title></head>' +
  '<body style="margin:0; padding:0; height:99.5vh">' +
  '<embed width="100%" height="100%" src="data:application/pdf;base64,' + dataUrl + '">' +
  '</body>' +
  '</html>';

var printWin = window.open('', '', 'width=1000,height=1000');
printWin.document.write(windowContent);
printWin.document.close();
printWin.focus();

var embed = printWin.document.querySelector('embed');
embed.addEventListener('load', function() { myPrint(printWin); });
FunnyO
  • 383
  • 2
  • 20
  • Try to bind handler on embed element like here https://stackoverflow.com/questions/740860/load-events-for-embedded-elements and then call `printWin.print()` there. – Jan Pfeifer Feb 10 '23 at 09:18
  • I rebuilt my code, but cannot seem to get that working. The "load" event fires too soon or I get an error due to references. – FunnyO Feb 10 '23 at 10:11
  • Yep, it seems there are many problems with this. When there is embed with PDF all `window.print()` calls are ignored. Even from console. Access to `embed.print` is no longer possible too. Creating BLOB and opening new tab opens and immediately closes print dialog and any subsequent calls results in CORS error. Using iframe instead of embed works partially. It prints page preview too. – Jan Pfeifer Feb 10 '23 at 13:22
  • Is there maybe a workaround to this? For example converting the base64 pdf to an image, displaying that and trying to print the page then? Seems as though only embed and iframe are by nature async html elements. – FunnyO Feb 10 '23 at 13:33
  • Where this Base64 cames from anyway? – Jan Pfeifer Feb 10 '23 at 13:45
  • Its autogenerated from a plugin that creates the pdf in base64 and delivers it to the applicatoin. – FunnyO Feb 14 '23 at 08:41

1 Answers1

1

The only solution that seems to work now is to convert Base64 PDF to the BLOB and open it in new window:

Creating a BLOB from a Base64 string in JavaScript

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;
}

Open a new window and call print

const base64PDF = ""; // Your Base64 PDF data
const contentType = "application/pdf";
const blob = b64toBlob(base64PDF, contentType);
const blobUrl = URL.createObjectURL(blob);
const w = window.open(blobUrl, '', 'width=1000,height=1000');
w.print();
Jan Pfeifer
  • 2,854
  • 25
  • 35