PDF'yi doğrudan JavaScript'ten yazdırın


94

HTML'de bir PDF listesi oluşturuyorum. Listeye bir indirme bağlantısı ve bir yazdırma düğmesi / bağlantısı eklemek istiyorum. Kullanıcı PDF'yi görmeden veya bir PDF görüntüleyiciyi açmadan PDF için Yazdır iletişim kutusunu doğrudan açmanın bir yolu var mı?

PDF'yi gizli bir iframe'e indirmenin ve onu JavaScript ile yazdırmak üzere tetiklemenin bazı varyasyonları?

Yanıtlar:


57

Aşağıdaki yorumlara göre, artık modern tarayıcılarda çalışmamaktadır
Bu soru size yardımcı olabilecek bir yaklaşımı göstermektedir: Sessiz gömülü bir PDF yazdırma

<embed>PDF'yi belgeye gömmek için etiketini kullanır :

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

Daha sonra .print(), PDF yüklendiğinde Javascript'teki öğe üzerindeki yöntemi çağırırsınız :

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

Yerleştirmeyi gizli bir iframe'e yerleştirebilir ve oradan yazdırarak size kusursuz bir deneyim sunabilirsiniz.


3
Bu çözüm çalışmıyor ... Chrome, FF için izin reddedildi
user1428716

8
Gömülü belge farklı bir etki alanında ise bu işe yaramaz.
nullability

5
Oluşturulduğunda yazdırmak için pdf'ye javascript eklemek daha kolaydır. Google Dokümanlar'ın yaptığı budur. Bu şekilde ya tarayıcı yükler ve yazdırır, ya da adobe eklentisi.
Rahly

2
Muhtemelen onu google'da
aratabilirsin

6
Evet, print () yönteminin tanımsız olduğu tüm tarayıcılarda bu sorunu yaşıyorum. Bu yöntem modası geçmiş mi? Başka çözümler var mı?
Jacob Ensor

40

Bir iframe'den bir PDF yazdırmak için bir işlev.

PDF'nin URL'sini işleve iletmeniz yeterlidir. Bir iframe oluşturur ve PDF yüklendikten sonra baskıyı tetikler.

İşlevin iframe'i yok etmediğini unutmayın. Bunun yerine, işlev her çağrıldığında onu yeniden kullanır. İframe'i yok etmek zor çünkü yazdırma tamamlanana kadar gerekli ve yazdırma yöntemi geri arama desteğine sahip değil (bildiğim kadarıyla).

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
Büyük bir sorunu çözmeme yardım ettiğiniz için size teşekkür ediyorum: yoksa setTimeoutyazdırma işlevi bazen başarısız olur. Neden olduğuna dair hiçbir fikrim yok ve birinin bunu bulacağını umuyorum.
Evan Hu

Baskı yönteminin geri arama desteği var, ancak bu cevabı 2014'te yazdığınızda henüz geniş çapta desteklenmiyordu. Ama şimdi öyle; tüm büyük masaüstü tarayıcılarının en son sürümleri desteklenir onafterprint. Bir iframe'i yeniden kullanmanın, birinin iki düğmeyi hızlı bir şekilde tıkladığı ve ikinci PDF'yi iki kez yazdırdığı yarış koşullarını ortaya çıkarabileceği konusunda biraz endişeliyim, çünkü iframe URL'si ilk yazdırma iletişim kutusu görünmeden önce değiştirilmişti.
Mark Amery

18

Print.js'yi http://printjs.crabbly.com/ adresinden indirin.

$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
PDF'leri IE, Edge veya Firefox'ta yazdırmaz.
Richard Collette

Bunu bugün, jQuery kullanarak pdf baytlarını sunucudan almak için denedim, ardından blob ve yukarıdaki gibi 'createOvjectURL' oluşturduk. PrintJS bu durumda yazdırma iletişim kutusunu göstermez. :)
woohoo

tek tıklama ile birden fazla pdf dosyası yazdırabilir miyim?
Sunil Garg

12

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

canlı bir demo için http://mozilla.github.io/pdf.js/

Muhtemelen istediğiniz şey budur, ancak modern tarayıcılar bu tür bir işlevsellik içerdiğinden bunun amacını göremiyorum, aynı zamanda, kendi optimize edilmiş eklentileri ve uygulamaları olan mobil cihazlar gibi düşük güçlü cihazlarda çok yavaş çalışacaktır. .


Pdf.js, 80MB + gibi büyük belgeleri yazdırırken de son derece yavaştır
Rudolf Dvoracek

6

Bu işlevi sunucudan pdf akışını indirmek için kullandım.

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

Base64 dizesinden pdf yazdırmak için çapraz tarayıcı çözümü:

  • Chrome: yazdırma penceresi açılır
  • FF: pdf içeren yeni sekme açıldı
  • IE11: aç / kaydet istemi açıldı

.

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 dosyasını IE11 için yeni sekmede açma

Sunucuda base64 dizesinin ön işlemesini yapabiliyorsanız, onu bir url altında açığa çıkarabilir ve içindeki bağlantıyı kullanabilirsiniz printJS:)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.