Stampa PDF direttamente da JavaScript


93

Sto creando un elenco di PDF in HTML. Nell'elenco vorrei includere un collegamento per il download e un pulsante / collegamento di stampa. C'è un modo per aprire direttamente la finestra di dialogo Stampa per il PDF senza che l'utente veda il PDF o apra un visualizzatore di PDF?

Qualche variazione del download del PDF in un iframe nascosto e l'attivazione della stampa con JavaScript?

Risposte:


56

In base ai commenti di seguito, non funziona più nei browser moderni
Questa domanda dimostra un approccio che potrebbe esserti utile: Stampa silenziosa di un PDF incorporato

Utilizza il <embed>tag per incorporare il PDF nel documento:

<embed
    type="application/pdf"
    src="path_to_pdf_document.pdf"
    id="pdfDocument"
    width="100%"
    height="100%" />

Quindi chiami il .print()metodo sull'elemento in Javascript quando il PDF viene caricato:

function printDocument(documentId) {
    var doc = document.getElementById(documentId);

    //Wait until PDF is ready to print    
    if (typeof doc.print === 'undefined') {    
        setTimeout(function(){printDocument(documentId);}, 1000);
    } else {
        doc.print();
    }
}

Puoi posizionare l'incorporamento in un iframe nascosto e stamparlo da lì, offrendoti un'esperienza senza interruzioni.


3
Questa soluzione non funziona ... Ricevo l'autorizzazione negata per Chrome, FF
user1428716

8
Questo non funzionerà se il documento incorporato si trova su un dominio diverso.
nullability

5
È più facile aggiungere javascript al pdf da stampare durante il rendering. Questo è ciò che fa Google Docs. In questo modo il browser lo carica e lo stampa o il plugin adobe.
Rahly

2
Probabilmente potresti cercarlo su google, ma tutto ciò che è, è un nuovo oggetto script aggiunto al pdf, dove il javascript è solo "window.print ()"
Rahly

6
Sì, sto riscontrando il problema su tutti i browser in cui il metodo print () non è definito. Questo metodo è obsoleto? ci sono altre soluzioni?
Jacob Ensor

38

Ecco una funzione per stampare un PDF da un iframe.

Devi solo passare l'URL del PDF alla funzione. Creerà un iframe e attiverà la stampa una volta caricato il PDF.

Nota che la funzione non distrugge l'iframe. Invece, lo riutilizza ogni volta che viene chiamata la funzione. È difficile distruggere l'iframe perché è necessario fino al termine della stampa e il metodo di stampa non ha il supporto di callback (per quanto ne so).

printPdf = function (url) {
  var iframe = this._printIframe;
  if (!this._printIframe) {
    iframe = this._printIframe = document.createElement('iframe');
    document.body.appendChild(iframe);

    iframe.style.display = 'none';
    iframe.onload = function() {
      setTimeout(function() {
        iframe.focus();
        iframe.contentWindow.print();
      }, 1);
    };
  }

  iframe.src = url;
}

3
Ti ringrazio perché mi aiuti a risolvere un grosso problema: senza setTimeout, la funzione di stampa a volte fallisce. Non ho idea del perché e spero che qualcuno lo scoprirà.
Evan Hu

Il metodo di stampa ha il supporto per la richiamata, ma non era ancora ampiamente supportato quando hai scritto questa risposta nel 2014. Ora lo è, però; supportano le ultime versioni di tutti i principali browser desktop onafterprint. Sono un po 'preoccupato che il riutilizzo di un iframe possa introdurre condizioni di gara in cui qualcuno fa clic su due pulsanti rapidamente e finisce per stampare il secondo PDF due volte perché l'URL dell'iframe era già stato sostituito prima che apparisse la prima finestra di dialogo di stampa.
Mark Amery

18

Scarica Print.js da http://printjs.crabbly.com/

$http({
    url: "",
    method: "GET",
    headers: {
        "Content-type": "application/pdf"
    },
    responseType: "arraybuffer"
}).success(function (data, status, headers, config) {
    var pdfFile = new Blob([data], {
        type: "application/pdf"
    });
    var pdfUrl = URL.createObjectURL(pdfFile);
    //window.open(pdfUrl);
    printJS(pdfUrl);
    //var printwWindow = $window.open(pdfUrl);
    //printwWindow.print();
}).error(function (data, status, headers, config) {
    alert("Sorry, something went wrong")
});

3
Non stampa PDF su IE, Edge o Firefox.
Richard Collette

Ho provato oggi usando jQuery get per ottenere i byte del pdf dal server, quindi creando il blob e 'createOvjectURL' come sopra. PrintJS non mostra la finestra di dialogo di stampa in questo caso. :)
woohoo

posso stampare più file pdf con un solo clic?
Sunil Garg

12

https://github.com/mozilla/pdf.js/

per una demo live http://mozilla.github.io/pdf.js/

probabilmente è quello che vuoi, ma non riesco a vedere il senso di questo dato che i browser moderni includono tale funzionalità, inoltre funzionerà terribilmente lento su dispositivi a bassa potenza come i dispositivi mobili che, tra l'altro, hanno i propri plug-in e app ottimizzati .


Pdf.js è anche terribilmente lento quando si stampano documenti di grandi dimensioni, come 80 MB +
Rudolf Dvoracek

6

Ho usato questa funzione per scaricare il flusso PDF dal server.

function printPdf(url) {
        var iframe = document.createElement('iframe');
        // iframe.id = 'pdfIframe'
        iframe.className='pdfIframe'
        document.body.appendChild(iframe);
        iframe.style.display = 'none';
        iframe.onload = function () {
            setTimeout(function () {
                iframe.focus();
                iframe.contentWindow.print();
                URL.revokeObjectURL(url)
                // document.body.removeChild(iframe)
            }, 1);
        };
        iframe.src = url;
        // URL.revokeObjectURL(url)
    }

4

Soluzione cross browser per la stampa di pdf dalla stringa base64:

  • Chrome: si apre la finestra di stampa
  • FF: si apre una nuova scheda con pdf
  • IE11: viene aperto il prompt di apertura / salvataggio

.

const blobPdfFromBase64String = base64String => {
   const byteArray = Uint8Array.from(
     atob(base64String)
       .split('')
       .map(char => char.charCodeAt(0))
   );
  return new Blob([byteArray], { type: 'application/pdf' });
};

const isIE11 = !!(window.navigator && window.navigator.msSaveOrOpenBlob); // or however you want to check it

const printPDF = blob => {
   try {
     isIE11
       ? window.navigator.msSaveOrOpenBlob(blob, 'documents.pdf')
       : printJS(URL.createObjectURL(blob)); // http://printjs.crabbly.com/
   } catch (e) {
     throw PDFError;
   }
};

printPDF(blobPdfFromBase64String(base64String))

BONUS - Apertura del file BLOB in una nuova scheda per IE11

Se sei in grado di eseguire una preelaborazione della stringa base64 sul server, puoi esporla sotto un URL e utilizzare il link in printJS:)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.