125 votes

Imprimez des PDF directement à partir de JavaScript

Je suis en train de créer une liste de PDF en HTML. Dans cette liste, j'aimerais inclure un lien de téléchargement et un bouton/lien d'impression. Existe-t-il un moyen d'ouvrir directement la boîte de dialogue d'impression du PDF sans que l'utilisateur ne voie le PDF ou n'ouvre une visionneuse de PDF ?

Une variante consistant à télécharger le PDF dans une iframe cachée et à déclencher l'impression avec JavaScript ?

59voto

nullability Points 4590

D'après les commentaires ci-dessous, il ne fonctionne plus dans les navigateurs modernes.
Cette question illustre une approche qui pourrait vous être utile : Impression silencieuse d'un PDF incorporé

Il utilise le <embed> pour intégrer le PDF dans le document :

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

Ensuite, vous appelez le .print() sur l'élément en Javascript lorsque le PDF est chargé :

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

Vous pourriez placer l'intégration dans une iframe cachée et l'imprimer à partir de là, ce qui vous donnerait une expérience transparente.

59voto

Nicolas BADIA Points 1753

Voici une fonction pour imprimer un PDF à partir d'une iframe.

Il vous suffit de transmettre l'URL du PDF à la fonction. Elle créera une iframe et déclenchera l'impression une fois le PDF chargé.

Notez que la fonction ne détruit pas l'iframe. Au contraire, elle le réutilise à chaque fois que la fonction est appelée. Il est difficile de détruire l'iframe parce qu'il est nécessaire jusqu'à ce que l'impression soit terminée, et la méthode d'impression n'a pas de support de callback (pour autant que je sache).

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

29voto

user1892203 Points 369

Vous pouvez utiliser Print.js ( npm install print-js ). Il pèse 128 Ko sans emballage et vous pouvez trouver la documentation à l'adresse suivante http://printjs.crabbly.com/ .

Il ne s'imprime pas sur IE cependant, dans ces cas vous devrez télécharger le PDF à la place.

$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")
});

13voto

user2311177 Points 44

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

pour une démonstration en direct http://mozilla.github.io/pdf.js/

c'est probablement ce que vous voulez, mais je n'en vois pas l'intérêt puisque les navigateurs modernes intègrent cette fonctionnalité. De plus, elle sera terriblement lente sur les appareils à faible puissance comme les appareils mobiles qui, soit dit en passant, ont leurs propres plugins et applications optimisés.

6voto

Papi Points 311

Solution multi-navigateur pour l'impression de pdf à partir d'une chaîne de caractères base64 :

  • Chrome : la fenêtre d'impression est ouverte
  • FF : un nouvel onglet avec le pdf est ouvert
  • IE11 : l'invite d'ouverture/enregistrement est ouverte

.

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 - Ouverture du fichier blob dans un nouvel onglet pour IE11

Si vous êtes en mesure d'effectuer un prétraitement de la chaîne base64 sur le serveur, vous pouvez l'exposer sous une certaine url et utiliser le lien dans le fichier printJS :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X