Ответ 1
Firefox: разрешение запрещено для доступа к свойству "print"
Это ошибка в firefox. Локально его можно отключить, перейдя в about:config
и установите для свойства pdfjs.disabled
значение true. Возможным обходным путем является использование серверной версии script и изменение формата PDF. Используя php, вы можете использовать fpdf и встраивать расширения в реализовать js (включая функцию print()
) или просто преобразовать PDF в изображение, вернуть URL-адрес и распечатать его. Вы можете использовать FPDI, чтобы изменить существующий pdf. Я приведу вам пример того, как я получил его для работы с PHP.
Создание PDF файла с встроенным javascript (autoprint) с помощью FPDI и PDF_JS
require_once('fpdf.php');
require_once('fpdi.php');
class PDF_JavaScript extends FPDI {
var $javascript;
var $n_js;
function IncludeJS($script) {
$this->javascript=$script;
}
function _putjavascript() {
$this->_newobj();
$this->n_js=$this->n;
$this->_out('<<');
$this->_out('/Names [(EmbeddedJS) '.($this->n+1).' 0 R]');
$this->_out('>>');
$this->_out('endobj');
$this->_newobj();
$this->_out('<<');
$this->_out('/S /JavaScript');
$this->_out('/JS '.$this->_textstring($this->javascript));
$this->_out('>>');
$this->_out('endobj');
}
function _putresources() {
parent::_putresources();
if (!empty($this->javascript)) {
$this->_putjavascript();
}
}
function _putcatalog() {
parent::_putcatalog();
if (!empty($this->javascript)) {
$this->_out('/Names <</JavaScript '.($this->n_js).' 0 R>>');
}
}
}
class PDF_AutoPrint extends PDF_JavaScript
{
function AutoPrint($dialog=false)
{
//Open the print dialog or start printing immediately on the standard printer
$param=($dialog ? 'true' : 'false');
$script="print($param);";
$this->IncludeJS($script);
}
function AutoPrintToPrinter($server, $printer, $dialog=false)
{
$script = "document.contentWindow.print();";
$this->IncludeJS($script);
}
}
$pdf=new PDF_AutoPrint();
$pdf->setSourceFile("mozilla.pdf");
//Open the print dialog
$tplIdx = $pdf->importPage(1, '/MediaBox');
$pdf->addPage();
$pdf->useTemplate($tplIdx, 10, 10, 90);
$pdf->AutoPrint(true);
$pdf->Output('generated.pdf', 'F');
Теперь вы можете просто добавить сгенерированный PDF файл на свою страницу, а включенный javascript вызовет функцию print()
. Вам даже не нужно называть это вручную. Однако в firefox это будет работать только с visibility: hidden
, а не с display: none
.
function print_pdf(url){
var iFrameJQueryObject = $('<iframe id="iframe" src="'+url+'" style="visibility: hidden"></iframe>');
$('#foo').append(iFrameJQueryObject);
}
print_pdf('mozilla_generated.pdf');
Chrome: ошибка безопасности (кросс-начало)
PDF должен быть расположен на том же хосте. Firefox был в порядке с другими доменами в моих тестах, но хром дал мне ошибки с перекрестными ошибками.
Firefox: печатная страница включает только about:blank
Вы получите пустую страницу в firefox (jsfiddle), потому что она выведет iframe, прежде чем загрузит любой контент. Упомянутые методы, такие как $(document).onload()
, не помогут, поскольку они ожидают загрузки DOM, а setTimeout()
все равно могут привести к ошибкам, поскольку вы не знаете, сколько времени требуется загрузить iFrame.
Вы можете просто решить эту проблему, используя jQuery load()
. (doc) Это даст вам возможность использовать функцию обратного вызова в качестве параметра.
если предоставляется "полный" обратный вызов, он выполняется после постобработки и вставки HTML. Обратный вызов запускается один раз для каждого элемента в коллекции jQuery, а
this
устанавливается поочередно по каждому элементу DOM.
Пример кода 1
function print_pdf(url){
var id = 'iframe', html = '<iframe id="'+id+'" src="'+url+'" style="display:none"></iframe>';
$('body').append(html);
// wait for the iFrame to fully load and call the print() function afterwards
$('#' + id).load(function () {
document.getElementById(id).contentWindow.print();
});
}
В качестве альтернативы вы можете напрямую создать объект jQuery и использовать jQuery on()
(doc) для присоединения любого обработчика событий.
Пример кода 2 (jsfiddle)
function print_pdf(url){
var iFrameJQueryObject = $('<iframe id="iframe" src="'+url+'" style="display:none"></iframe>');
$('body').append(iFrameJQueryObject);
iFrameJQueryObject.on('load', function(){
$(this).get(0).contentWindow.print();
});
}