Imprimir PDF embedded desde el browser con Javascript, HTML5, AngularJS

Estoy cargando un pdf codificado en Base64 como una cadena en mi Javascript desde mi server. Mi aplicación cliente está usando AngularJS, HTML5.

Mi HTML se ve así:

<div id="printablePdfContainer"> <iframe id="printablePdf" width="100%" height="100%"></iframe> </div> 

Mi Javascript se ve así:

 var pdfName = 'data:application/pdf;base64,' + data[0].PrintImage; var embeddedPdf = document.getElementById('printablePdf'); embeddedPdf.setAttribute('src', pdfName); $scope.printDocument(embeddedPdf); 

Mi function printDocument se ve así:

 $scope.printDocument = function() { var test = document.getElementById('printablePdf'); if (typeof document.getElementById('printablePdf').print === 'undefined') { setTimeout(function(){$scope.printDocument();}, 1000); } else { var x = document.getElementById('printablePdf'); x.print(); } }; 

La function printDocument se ha tomado de una pregunta preexistente en desbordamiento de stack ( printing silenciosa de un PDF embedded ) que da como respuesta para imprimir un pdf embedded. Sin embargo, esto parece no funcionar más. Siempre me estoy "indefinido" por el

 typeof document.getElementById('printablePdf').print === 'undefined' 

comprobar. Parece que .print no existe o algo así.

Por lo tanto, mi pregunta es esta: ¿cómo puedo imprimir un PDF embedded en HTML5, utilizando Javascript y sin abrir una window emergente?

Saludos, Phil

También se responde aquí: Imprimir PDF desde la label javascript embed

Voy a publicar lo que aprendí aquí después de una gran cantidad de investigaciones para cualquier persona en el futuro que pueda encontrar esto.

Los PDF se muestran de forma diferente en function del browser, la versión del browser, la configuration del browser y el sistema operativo. Hay muchas variables, así que hablaré sobre las situaciones más comunes aquí.

  • En todos los browseres no pude llamar a ningún tipo de método print () a través de Javascript, solo pude usar las PdfActions. La OPENACTION llamaría imprimir. Integré esto en el PDF usando iText.

  • Chrome utiliza el visor de Adobe, que no da acceso a ningún tipo de método de printing (), pero sí ejecuta las PdfActions incrustadas en el PDF. De modo que puede insert una 'OpenAction' en un PDF y hacer que la llamada PDF se imprima cada vez que se abre desde cualquier aplicación que observe esas acciones.

  • Firefox (por encima de una cierta versión, todas las versiones recientes) utiliza el visor de Adobe en Windows, que también reconoce las PdfActions. Sin embargo, en OSX pierde soporte para el visor de Adobe y cambia al escaneado en el visor de Firefox (pdf.js). Lo cual no es compatible con las PdfActions.

  • IE: Realmente no probé mucho en IE. Principalmente porque abandoné la printing de PDF desde Javascript después de que Firefox no funcionó en OSX (una necesidad para mí).

Mis PDF estaban siendo generados por un server que yo controlé, así que terminé haciendo cambios de service en mi server y agregué un service de obtención de PNG que generaba un PNG basado en el mismo marcado que usa la generación de PDF. Los browseres manejan las imágenes mucho mejor que los files PDF, que sabía que iban a entrar, pero esperaba poder volver a utilizar el service de generación de PDF, ya que se usa en otros lugares de mi código.

No responde la pregunta, pero es toda la información que tengo. Mi sugerencia para cualquiera que pueda encontrar esto en el futuro: si es posible, abandone PDF en este caso y sea más simple. De lo contrario, actualice esta pregunta si sabe cómo llamar a print () a través de Javascript en FF preview pdf viewer en OSX.

-Phil

Para imprimir un pdf de base64, necesita evitar el hecho de que los URI de datos no tienen origen y, por lo tanto, están bloqueados por los browseres modernos.

Consulte la nota en la página URL de date en MDN: URL de datos .

Para evitar esto, debe hacer reference directamente al mismo pdf, que es un no-no en este caso, o convertir el pdf a un object / blob url.

Ver notas MDN sobre la creación de un object / blob URL

 function b64toBlob(b64Data, contentType) { var byteCharacters = atob(b64Data) var byteArrays = [] for (let offset = 0; offset < byteCharacters.length; offset += 512) { var slice = byteCharacters.slice(offset, offset + 512), byteNumbers = new Array(slice.length) for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i) } var byteArray = new Uint8Array(byteNumbers) byteArrays.push(byteArray) } var blob = new Blob(byteArrays, { type: contentType }) return blob } var pdfObjectUrl = URL.createObjectURL(b64toBlob(data[0].PrintImage, 'application/pdf')) var embeddedPdf = document.getElementById('printablePdf') embeddedPdf.setAttribute('src', pdfObjectUrl) // Then to print embeddedPdf.contentWindow.print()