Печать PDF прямо из JavaScript

94

Я создаю список PDF-файлов в HTML. В список я хотел бы включить ссылку для скачивания и кнопку / ссылку для печати. Есть ли способ напрямую открыть диалоговое окно «Печать» для PDF-файла, чтобы пользователь не видел PDF-файл или не открывал программу просмотра PDF-файлов?

Какой-то вариант загрузки PDF-файла в скрытый iframe и запуск его для печати с помощью JavaScript?

Крейг Селеста
источник

Ответы:

57

Основываясь на комментариях ниже, он больше не работает в современных браузерах.
Этот вопрос демонстрирует подход, который может быть вам полезен: Автоматическая печать встроенного 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();
    }
}

Вы можете поместить встраивание в скрытый iframe и распечатать его оттуда, что обеспечит вам удобство работы.

обнуление
источник
3
Это решение не работает ... Я получаю отказ в разрешении для Chrome, FF
user1428716
8
Это не сработает, если встроенный документ находится в другом домене.
Обнуление
5
Проще просто добавить javascript в PDF для печати при визуализации. Это то, что делает Google Docs. Таким образом, либо браузер загрузит и распечатает его, либо плагин Adobe.
Rahly
2
Вы могли бы, вероятно, погуглить, но все, что это было, - это новый объект скрипта, добавленный в pdf, где javascript - это просто "window.print ()"
Рахли
6
Да, у меня проблема во всех браузерах, в которых метод print () не определен. Этот метод устарел? Есть ли другие решения?
Jacob Ensor
40

Вот функция для печати 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")
});
user1892203
источник
4
Не печатает PDF-файлы в IE, Edge или Firefox.
Ричард Коллетт
Пробовал это сегодня, используя jQuery, чтобы получить байты pdf с сервера, а затем создать blob и createOvjectURL, как указано выше. PrintJS в этом случае не отображает диалоговое окно печати. :)
woohoo
Могу ли я распечатать несколько файлов PDF одним щелчком мыши?
Сунил Гарг,
12

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

для живой демонстрации http://mozilla.github.io/pdf.js/

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

user2311177
источник
Pdf.js также ужасно медленен при печати больших документов, например 80MB +
Рудольф Дворачек
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)
    }
Аднан шах
источник
5

Кроссбраузерное решение для печати 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:)

Папи
источник