Imprimer le PDF directement à partir de JavaScript

93

Je construis une liste de PDF en HTML. Dans la 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 Imprimer pour le PDF sans que l'utilisateur ne voie le PDF ou n'ouvre une visionneuse PDF?

Une variante du téléchargement du PDF dans une iframe cachée et du déclenchement de son impression avec JavaScript?

Craig Celeste
la source

Réponses:

56

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

Il utilise la <embed>balise pour incorporer le PDF dans le document:

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

Ensuite, vous appelez la .print()méthode 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 pouvez placer l'intégration dans une iframe cachée et l'imprimer à partir de là, vous offrant une expérience transparente.

nullité
la source
3
Cette solution ne fonctionne pas ... Je reçois l'autorisation refusée pour Chrome, FF
user1428716
8
Cela ne fonctionnera pas si le document incorporé se trouve sur un domaine différent.
nullabilité
5
Il est plus facile d'ajouter simplement du javascript au pdf à imprimer lors du rendu. C'est ce que fait Google Docs. De cette façon, soit le navigateur le charge et l'imprime, soit le plugin Adobe.
Rahly
2
Vous pourriez probablement chercher sur Google, mais tout ce qu'il est, c'est un nouvel objet de script ajouté au pdf, où le javascript est juste "window.print ()"
Rahly
6
Ouais, j'ai le problème sur tous les navigateurs où la méthode print () n'est pas définie. Cette méthode est-elle obsolète? Y a-t-il d'autres solutions?
Jacob Ensor
38

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

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

Notez que la fonction ne détruit pas l'iframe. Au lieu de cela, il le réutilise chaque fois que la fonction est appelée. Il est difficile de détruire l'iframe car il est nécessaire jusqu'à ce que l'impression soit terminée, et la méthode d'impression n'a pas de support de rappel (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;
}
Nicolas BADIA
la source
3
Je vous remercie, car vous m'aidez à résoudre un gros problème: sans setTimeout, la fonction d'impression échouera parfois. Je ne sais pas pourquoi et j'espère que quelqu'un le découvrira.
Evan Hu
La méthode d'impression prend en charge le rappel, mais elle n'était pas encore largement prise en charge lorsque vous avez écrit cette réponse en 2014. C'est maintenant le cas; les dernières versions de tous les principaux navigateurs de bureau prennent en charge onafterprint. Je crains un peu que la réutilisation d'une iframe puisse introduire des conditions de concurrence où quelqu'un clique rapidement sur deux boutons et finit par imprimer le deuxième PDF deux fois car l'URL de l'iframe avait déjà été échangée avant l'apparition de la première boîte de dialogue d'impression.
Mark Amery
18

Téléchargez Print.js depuis 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")
});
user1892203
la source
3
N'imprime pas les PDF sur IE, Edge ou Firefox.
Richard Collette
J'ai essayé cela aujourd'hui en utilisant jQuery get pour obtenir les octets du pdf du serveur, puis en créant le blob et 'createOvjectURL' comme ci-dessus. PrintJS n'affiche pas la boîte de dialogue d'impression dans ce cas. :)
woohoo
puis-je imprimer plusieurs fichiers pdf en un seul clic?
Sunil Garg
12

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

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

c'est probablement ce que vous voulez, mais je ne peux pas voir l'intérêt de cela puisque les navigateurs modernes incluent une telle fonctionnalité, aussi cela fonctionnera terriblement lent sur les appareils de faible puissance comme les appareils mobiles qui, en passant, ont leurs propres plugins et applications optimisés .

utilisateur2311177
la source
Pdf.js est également terriblement lent lors de l'impression de gros documents, comme 80 Mo +
Rudolf Dvoracek
6

J'ai utilisé cette fonction pour télécharger le flux pdf du serveur.

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
la source
4

Solution de navigateur croisé pour l'impression de pdf à partir de la chaîne base64:

  • Chrome: la fenêtre d'impression est ouverte
  • FF: un nouvel onglet avec pdf est ouvert
  • IE11: l'invite open / save 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 capable de faire un prétraitement de la chaîne base64 sur le serveur, vous pouvez l'exposer sous une URL et utiliser le lien dans printJS:)

Papi
la source