Страницы

Поиск по вопросам

пятница, 12 июля 2019 г.

Как PDF, полученный в Base64-строке открыть и распечатать?

Создаю на стороне сервера уже готовый отчёт PDF со средствами Jasperreports, и кодирую в Base64. Дальше передаю всё это клиенту.
В клиенте:

$.ajax({url: "reports/pdfCurStateByOwner", data: {p: document.getElementsByClassName('active')[0].dataset.idrju}, success: function (data) { console.log(data); //window.print(atob(data)); }, dataType: "text" })
Что я получаю: и сервер и console.log(data) выдают одинаковую строку, и с помощью онлайн декодеров base64 тоже проверил получил желанный pdf файл.
Теперь мне надо этот полученный байт-код распечатать и вот тут получаю не то, что получил в качестве данных, а всю страницу... Что делаю не так?


Ответ

Во-первых, вы совсем не «байт-код» с сервера отдаёте, а PDF, закодированный в BASE64-СТРОКУ. Во-вторых, вы получаете при распечатке именно то, что вызвали – а именно распечатку текущего окна. В-третьих, в функцию window.print() нельзя передать НИЧЕГО, т.к. она ничего не ожидает. Учитесь пользоваться документацией, пожалуйста.
РЕШЕНИЕ:
Современные обозреватели сети имеют ограничения безопасности на открытие всплывающих окон.
Для IE:
Согласно документации IE не поддерживает data:URL protocol для PDF. Поэтому в отличии от остальных для него следующий код работать не будет:
var newWin = window.open('data:application/pdf;base64,' + pdfInBase64, '_blank', 'width=500,height=300,menubar=yes,scrollbars=yes');
Также в IE действуют ограничения безопасности на открытие всплывающих окон. Обойти их очень непросто и поэтому для IE отдельное решение через navigator.msSaveOrOpenBlob
Для остальных обозревателей сети:
Для того, чтобы всплывающие окна открывались надо в адресной строке нажать на кнопку-оповещении о всплывающих окнах и выбрать выпадающее меню "Всегда разрешать всплывающие окна с «адрес в сети»". Такая кнопка появляется лишь тогда, если вы ещё такую кнопку для данной страницы не нажимали.
ИТАК РЕШЕНИЕ:
//pdfInBase64 соответствует «data» в строке «success: function (data)» var pdfInBase64 = 'JVBERi0xLjMKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291cmNlcyAyIDAgUgovQ29udGVudHMgNCAwIFI+PgplbmRvYmoKNCAwIG9iago8PC9GaWx0ZXIgL0ZsYXRlRGVjb2RlIC9MZW5ndGggMzQ0Pj4Kc3RyZWFtCnicdZI7buRADERznaJOQDT/3VfYY9jBJrOJE1/fRQ1geIB1IomNalY9UoY/15JsfPIVrXg+VdZa+Ph72WmpQLXKVvy7/KRsR2mKGh5XrBBVlB2JQqwjmqhIiUAoOx9UqRzH+xVqsqbXlrBbu6llw+W4+xz088o7fbakoa2moe9zV7HENrx7wnSy762tmgxdLnXgc7zRbdIL7jVmTU8vat+un4DP7/9g6qGA0d0n3IM1Mzex2TRhqhIHOdEXzLaUIjfvjoWRvgNZW9pgDGfJas2h7ZYuZO6n1jkEm7oms/uakSQHZg2PM3zJTBY3Jocbt48RbOcMMw/5HK9rGcyfgL9ivk7ncbnWWPS+CexwJ82qRTesXXSxMkkdzOQ25y6XQa3b0Hb10Jr2/A7fG7Jlk7lp144ZLgfWIzLoJjszEcSTWqUB6atzdq3bhdkrXVzxupbB/ALY/Id+CmVuZHN0cmVhbQplbmRvYmoKMSAwIG9iago8PC9UeXBlIC9QYWdlcwovS2lkcyBbMyAwIFIgXQovQ291bnQgMQovTWVkaWFCb3ggWzAgMCA1OTUuMjggODQxLjg5XQo+PgplbmRvYmoKMiAwIG9iago8PAovUHJvY1NldCBbL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSV0KL0ZvbnQgPDwKPj4KL1hPYmplY3QgPDwKPj4KPj4KZW5kb2JqCjUgMCBvYmoKPDwKL1Byb2R1Y2VyIChGUERGIDEuNikKL0NyZWF0aW9uRGF0ZSAoRDoyMDA5MDUwODEyMjkxMSkKPj4KZW5kb2JqCjYgMCBvYmoKPDwKL1R5cGUgL0NhdGFsb2cKL1BhZ2VzIDEgMCBSCi9PcGVuQWN0aW9uIFszIDAgUiAvRml0SCBudWxsXQovUGFnZUxheW91dCAvT25lQ29sdW1uCj4+CmVuZG9iagp4cmVmCjAgNwowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDA1MDEgMDAwMDAgbiAKMDAwMDAwMDU4OCAwMDAwMCBuIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwODcgMDAwMDAgbiAKMDAwMDAwMDY4MiAwMDAwMCBuIAowMDAwMDAwNzU3IDAwMDAwIG4gCnRyYWlsZXIKPDwKL1NpemUgNwovUm9vdCA2IDAgUgovSW5mbyA1IDAgUgo+PgpzdGFydHhyZWYKODYwCiUlRU9GCg==';
var URL = window.URL || window.webkitURL, byteChars = atob(pdfInBase64), bytes = [], i = 0;
for (; i < byteChars.length; i++) bytes[i] = byteChars.charCodeAt(i);
var blob = new Blob([new Uint8Array(bytes)], {type: 'application/pdf'}); // создаём object URL из Blob var downloadUrl = URL.createObjectURL(blob);
if(window.navigator && window.navigator.msSaveOrOpenBlob) window.navigator.msSaveOrOpenBlob(blob); else { var newWin = window.open(downloadUrl, '_blank', 'width=500,height=300,menubar=yes,scrollbars=yes,status=yes,resizable=yes'); newWin.focus(); newWin.print();//чтобы эта строка сработала страница должна быть в сети, т.е. НЕ локально. URL.revokeObjectURL(downloadUrl); }
Этот код здесь через snippet не работает из-за ограничений в snippet. Пользователь @Other поделился поэтому ссылкой на этот пример на jsfiddle.net
Обратите внимание на то, что открытие в текущем окне при помощи перемены window.location или с помощью window.open вам не подойдёт, т.к. распечатать в этих окнах уже не получится, т.к. они в этом случае перезаписываются открываемой страницей.
Можете также посмотреть: PDF Reader на JavaScript от Мozilla. Но для этого нужен уже отдельный вопрос.

Комментариев нет:

Отправить комментарий