Создаю на стороне сервера уже готовый отчёт 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. Но для этого нужен уже отдельный вопрос.
Комментариев нет:
Отправить комментарий