Роздрукуйте PDF безпосередньо з JavaScript


93

Я складаю список PDF-файлів у форматі HTML. У список я хотів би включити посилання для завантаження та кнопку / посилання для друку. Чи є спосіб безпосередньо відкрити діалогове вікно Друк для PDF без того, щоб користувач бачив PDF або відкривав переглядач PDF?

Деякі варіанти завантаження PDF-файлу у приховану рамку та ініціювання його друку за допомогою JavaScript?

Відповіді:


56

На основі коментарів нижче, воно більше не працює в сучасних браузерах
Це питання демонструє підхід, який може бути вам корисним: Безшумне друкування вбудованого PDF

Він використовує <embed>тег для вставки PDF в документ:

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

Потім ви викликаєте .print()метод елемента в Javascript під час завантаження PDF:

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

Ви можете помістити вбудований елемент у приховану рамку та надрукувати його звідти, забезпечуючи цілісність роботи.


3
Це рішення не працює ... Я отримую дозвіл на відмову для Chrome, FF
user1428716

8
Це не буде працювати, якщо вбудований документ знаходиться в іншому домені.
визнання недійсним

5
Простіше просто додати javascript до pdf для друку при отриманні. Цим займаються Документи Google. Таким чином, браузер завантажує та друкує його, або плагін Adobe.
Рахлі

2
Можливо, ви могли б погуглити, але все це - новий об’єкт сценарію, доданий до pdf, де javascript - це просто „window.print ()“
Рахлі,

6
Так, у мене проблема у всіх браузерах, де метод print () не визначений. Цей спосіб застарілий? Чи є інші рішення?
Jacob Ensor

38

Ось функція друку PDF-файлу з iframe.

Вам просто потрібно передати URL-адресу PDF функції. Це створить iframe та ініціює друк після завантаження PDF.

Зверніть увагу, що функція не руйнує iframe. Натомість він повторно використовує його кожного разу, коли функція викликається. Важко знищити iframe, оскільки він потрібен до завершення друку, а метод друку не має підтримки зворотного виклику (наскільки мені відомо).

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
Я дякую вам, оскільки ви допомагаєте мені вирішити велику проблему: без setTimeout, функція друку іноді не справляється. Не знаю, чому, і сподіваюся, хтось це дізнається.
Еван Ху,

Метод друку має підтримку зворотного виклику, але він ще не мав широкої підтримки, коли ви писали цю відповідь у 2014 році. підтримуються останні версії всіх основних настільних браузерів onafterprint. Я трохи стурбований тим, що повторне використання iframe може створити умови змагання, коли хтось швидко натискає дві кнопки і закінчує друкувати другий PDF двічі, оскільки URL-адресу iframe було вже замінено до появи першого діалогового вікна друку.
Марк Амері

18

Завантажте Print.js з 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")
});

3
Не друкує PDF-файли в IE, Edge або Firefox.
Річард Коллетт,

Спробував це сьогодні, використовуючи jQuery get, щоб отримати байти pdf з сервера, а потім створити BLOB і 'createOvjectURL', як зазначено вище. У цьому випадку PrintJS не відображає діалогове вікно друку. :)
woohoo

чи можна надрукувати кілька файлів PDF одним клацанням миші?
Суніл Гарг,

12

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

для демонстрації в реальному часі http://mozilla.github.io/pdf.js/

це, мабуть, те, що ви хочете, але я не бачу сенсу в цьому, оскільки сучасні браузери включають таку функціональність, а також він буде працювати дуже повільно на малопотужних пристроях, таких як мобільні пристрої, які, до речі, мають власні оптимізовані плагіни та програми .


Pdf.js також страшенно повільно друкує великі документи, такі як 80 МБ +
Рудольф Дворачек

6

Я використав цю функцію для завантаження PDF-потоку з сервера.

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

4

Рішення для перехресного браузера для друку PDF із рядка base64:

  • Chrome: відкрито вікно друку
  • FF: відкрита нова вкладка з pdf
  • IE11: відкрито підказку про відкриття / збереження

.

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))

БОНУС - Відкриття файлу BLOB в новій вкладці для IE11

Якщо ви можете виконати певну попередню обробку рядка base64 на сервері, ви можете виставити її під деякою URL-адресою та скористатися посиланням у printJS:)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.