Drucken Sie PDF direkt aus JavaScript

92

Ich erstelle eine Liste von PDFs in HTML. In die Liste möchte ich einen Download-Link und einen Druck-Button / Link einfügen. Gibt es eine Möglichkeit, den Druckdialog für die PDF-Datei direkt zu öffnen, ohne dass der Benutzer die PDF-Datei sieht oder einen PDF-Viewer öffnet?

Eine Variante, das PDF in einen versteckten Iframe herunterzuladen und zum Drucken mit JavaScript auszulösen?

Craig Celeste
quelle

Antworten:

56

Basierend auf den Kommentaren unten funktioniert es in modernen Browsern nicht mehr.
Diese Frage zeigt einen Ansatz, der für Sie hilfreich sein könnte: Stummes Drucken einer eingebetteten PDF-Datei

Es verwendet das <embed>Tag, um das PDF in das Dokument einzubetten:

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

Anschließend rufen Sie die .print()Methode für das Element in Javascript auf, wenn die PDF-Datei geladen wird:

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

Sie können die Einbettung in einem versteckten Iframe platzieren und von dort aus drucken, um eine nahtlose Erfahrung zu erzielen.

Nullfähigkeit
quelle
3
Diese Lösung funktioniert nicht ... Ich
erhalte
8
Dies funktioniert nicht, wenn sich das eingebettete Dokument in einer anderen Domäne befindet.
Nichtigkeit
5
Es ist einfacher, einfach Javascript zum PDF hinzuzufügen, um es beim Rendern zu drucken. Dies ist, was Google Text & Tabellen tut. Auf diese Weise lädt und druckt es entweder der Browser oder das Adobe-Plugin.
Rahly
2
Sie könnten es wahrscheinlich googeln, aber alles, was es ist, ist ein neues Skriptobjekt, das dem PDF hinzugefügt wurde, wobei das Javascript nur "window.print ()" ist
Rahly
6
Ja, ich habe das Problem in allen Browsern, in denen die print () -Methode undefiniert ist. Ist diese Methode veraltet? Gibt es noch andere Lösungen?
Jacob Ensor
38

Hier ist eine Funktion zum Drucken einer PDF-Datei aus einem Iframe.

Sie müssen nur die URL der PDF an die Funktion übergeben. Sobald das PDF geladen ist, wird ein Iframe erstellt und der Druck ausgelöst.

Beachten Sie, dass die Funktion den Iframe nicht zerstört. Stattdessen wird es bei jedem Aufruf der Funktion wiederverwendet. Es ist schwierig, den Iframe zu zerstören, da er benötigt wird, bis der Druckvorgang abgeschlossen ist und die Druckmethode keine Rückrufunterstützung bietet (soweit ich weiß).

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;
}
Nicolas BADIA
quelle
2
Ich danke Ihnen, da Sie mir bei der Lösung eines großen Problems helfen: Ohne setTimeoutfunktioniert die Druckfunktion manchmal nicht. Keine Ahnung warum und hoffe jemand wird es herausfinden.
Evan Hu
Die Druckmethode unterstützt zwar Rückrufe, wurde jedoch noch nicht allgemein unterstützt, als Sie diese Antwort 2014 geschrieben haben. Die neuesten Versionen aller gängigen Desktop-Browser unterstützen onafterprint. Ich bin ein wenig besorgt darüber, dass die Wiederverwendung eines Iframes zu Rennbedingungen führen kann, bei denen jemand schnell auf zwei Schaltflächen klickt und das zweite PDF zweimal druckt, da die Iframe-URL bereits vor dem Erscheinen des ersten Druckdialogs ausgetauscht wurde.
Mark Amery
18

Laden Sie die Print.js von http://printjs.crabbly.com/ herunter.

$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")
});
user1892203
quelle
3
Druckt keine PDFs in IE, Edge oder Firefox.
Richard Collette
Versuchte dies heute mit jQuery get, um die Bytes des PDF vom Server abzurufen, dann den Blob und 'createOvjectURL' wie oben zu erstellen. PrintJS zeigt in diesem Fall den Druckdialog nicht an. :)
woohoo
Kann ich mehrere PDF-Dateien mit einem Klick drucken?
Sunil Garg
12

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

für eine Live-Demo http://mozilla.github.io/pdf.js/

Es ist wahrscheinlich das, was Sie wollen, aber ich kann den Sinn davon nicht erkennen, da moderne Browser solche Funktionen enthalten. Außerdem läuft es auf Geräten mit geringem Stromverbrauch wie Mobilgeräten, die übrigens über eigene optimierte Plugins und Apps verfügen, furchtbar langsam .

user2311177
quelle
Pdf.js ist auch furchtbar langsam beim Drucken großer Dokumente, wie 80 MB +
Rudolf Dvoracek
6

Ich habe diese Funktion verwendet, um den PDF-Stream vom Server herunterzuladen.

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)
    }
Adnan shah
quelle
4

Browserübergreifende Lösung zum Drucken von PDF-Dateien aus base64-Zeichenfolgen:

  • Chrome: Das Druckfenster wird geöffnet
  • FF: Neue Registerkarte mit PDF wird geöffnet
  • IE11: Die Eingabeaufforderung zum Öffnen / Speichern wird geöffnet

.

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 - Blob-Datei in neuem Tab für IE11 öffnen

Wenn Sie in der Lage sind, die base64-Zeichenfolge auf dem Server vorzuverarbeiten, können Sie sie unter einer URL verfügbar machen und den Link in printJS:) verwenden

Papi
quelle