Cetak PDF langsung dari JavaScript


94

Saya sedang membuat daftar PDF dalam HTML. Dalam daftar, saya ingin menyertakan tautan unduhan dan tombol / tautan cetak. Apakah ada cara untuk langsung membuka dialog Cetak untuk PDF tanpa pengguna melihat PDF atau membuka penampil PDF?

Beberapa variasi mengunduh PDF ke dalam iframe tersembunyi dan memicunya untuk mencetak dengan JavaScript?

Jawaban:


57

Berdasarkan komentar di bawah, ini tidak lagi berfungsi di browser modern.
Pertanyaan ini menunjukkan pendekatan yang mungkin berguna bagi Anda: Cetak diam-diam PDF yang disematkan

Ini menggunakan <embed>tag untuk menyematkan PDF di dokumen:

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

Kemudian Anda memanggil .print()metode pada elemen di Javascript saat PDF dimuat:

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

Anda dapat menempatkan sematan di iframe tersembunyi dan mencetaknya dari sana, memberi Anda pengalaman yang mulus.


3
Solusi ini tidak berfungsi ... Saya mendapatkan izin ditolak untuk Chrome, FF
user1428716

8
Ini tidak akan berfungsi jika dokumen yang disematkan berada di domain yang berbeda.
nullability

5
Lebih mudah menambahkan javascript ke pdf untuk dicetak saat dirender. Inilah yang dilakukan Google Docs. Dengan cara ini browser memuat dan mencetaknya, atau plugin adobe.
Rahly

2
Anda mungkin bisa mencari di Google, tapi itu semua, adalah objek skrip baru yang ditambahkan ke pdf, di mana javascript-nya hanya "window.print ()"
Rahly

6
Ya, saya mengalami masalah di semua browser di mana metode print () tidak ditentukan. Apakah metode ini sudah ketinggalan zaman? Apakah ada solusi lain?
Jacob Ensor

40

Berikut adalah fungsi untuk mencetak PDF dari iframe.

Anda hanya perlu meneruskan URL PDF ke fungsi tersebut. Ini akan membuat iframe dan memicu pencetakan setelah PDF dimuat.

Perhatikan bahwa fungsi tersebut tidak merusak iframe. Sebaliknya, ia menggunakannya kembali setiap kali fungsinya dipanggil. Sulit untuk menghancurkan iframe karena diperlukan hingga pencetakan selesai, dan metode cetak tidak memiliki dukungan panggilan balik (sejauh yang saya tahu).

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
Saya mengucapkan terima kasih kepada Anda, karena Anda membantu saya memecahkan masalah besar: tanpa setTimeout, fungsi cetak terkadang akan gagal. Tidak tahu mengapa dan berharap seseorang akan menemukannya.
Evan Hu

Metode cetak memang memiliki dukungan panggilan balik, tetapi belum didukung secara luas ketika Anda menulis jawaban ini pada tahun 2014. Namun sekarang; versi terbaru dari semua dukungan browser desktop utama onafterprint. Saya sedikit khawatir bahwa menggunakan kembali iframe dapat menyebabkan kondisi balapan di mana seseorang mengklik dua tombol dengan cepat dan akhirnya mencetak PDF kedua dua kali karena URL iframe telah ditukar sebelum dialog cetak pertama muncul.
Mark Amery

18

Unduh Print.js dari 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")
});

4
Tidak mencetak PDF di IE, Edge, atau Firefox.
Richard Collette

Mencoba hari ini menggunakan jQuery untuk mendapatkan byte pdf dari server, lalu membuat blob dan 'createOvjectURL' seperti di atas. PrintJS tidak menampilkan dialog cetak dalam kasus ini. :)
woohoo

dapatkah saya mencetak beberapa file pdf dengan sekali klik?
Sunil Garg

12

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

untuk demo langsung http://mozilla.github.io/pdf.js/

mungkin itu yang Anda inginkan, tetapi saya tidak mengerti maksudnya karena browser modern menyertakan fungsionalitas seperti itu, juga akan berjalan sangat lambat pada perangkat berdaya rendah seperti perangkat seluler yang, omong-omong, memiliki plugin dan aplikasi yang dioptimalkan sendiri .


Pdf.js juga sangat lambat saat mencetak dokumen besar, seperti 80MB +
Rudolf Dvoracek

6

Saya menggunakan fungsi ini untuk mengunduh aliran pdf dari 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)
    }

5

Solusi lintas browser untuk mencetak pdf dari string base64:

  • Chrome: jendela cetak dibuka
  • FF: tab baru dengan pdf dibuka
  • IE11: prompt buka / simpan dibuka

.

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 - Membuka file blob di tab baru untuk IE11

Jika Anda dapat melakukan beberapa pemrosesan awal dari string base64 di server, Anda dapat mengeksposnya di bawah beberapa url dan menggunakan tautan di printJS:)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.