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?

Craig Celeste
sumber

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.

nullability
sumber
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;
}
Nicolas BADIA
sumber
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")
});
pengguna1892203
sumber
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 .

pengguna2311177
sumber
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)
    }
Adnan shah
sumber
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:)

ayah
sumber