2016-07-28 267 views
24

我想要構建的東西是通過單擊按鈕我想觸發PDF文件的打印,但不打開它。打印PDF時不用肉眼打開它

+-----------+ 
| Print PDF | 
+-----------+ 
    ^Click *---------> printPdf(pdfUrl) 

我第一次嘗試它的方法是使用iframe:

var $iframe = null; 

// This is supposed to fix the onload bug on IE, but it's not fired 
window.printIframeOnLoad = function() { 
    if (!$iframe.attr("src")) { return; } 
    var PDF = $iframe.get(0); 
    PDF.focus(); 

    try { 
    // This doesn't work on IE anyways 
    PDF.contentWindow.print(); 

    // I think on IE we can do something like this: 
    // PDF.document.execCommand("print", false, null); 
    } catch (e) { 
    // If we can't print it, we just open it in the current window 
    window.location = url; 
    } 
}; 

function printPdf(url) { 

    if ($iframe) { 
    $iframe.remove(); 
    } 

    $iframe = $('<iframe>', { 
    class: "hide", 
    id: "idPdf", 
    // Supposed to be a fix for IE 
    onload: "window.printIframeOnLoad()", 
    src: url 
    }); 

    $("body").prepend($iframe); 
} 

此作品在Safari(桌面& iOS版)和Chrome(我們可以概括它也許到WebKit的?)。

在Firefox上,PDF.contentWindow.print()permission denied錯誤結尾(即使PDF是從同一個域加載的)。

在IE(11)上,onload處理程序無法正常工作。


現在,我的問題是:是否有另一種更好的方式來打印PDF,而不需要視覺上打開它給用戶?

跨瀏覽器的東西在這裏很關鍵。我們應該支持儘可能多的瀏覽器。

達到此目的的最佳方法是什麼?我的開局是好的嗎?如何完成它?

我們現在在2016年,我覺得這在整個瀏覽器中實現仍然很痛苦。

+0

所以,如果我理解正確,你不想顯示PDF,但仍然打印它...所以只需用其他詞下載?或者按照正常方式進行操作並隱藏該部分。 – Jorrex

+0

打開PDF時,不能將PDF設置爲自動打印? – epascarello

+0

@Jorrex不,在隱藏的iframe中打開它,並在該iframe的上下文中打開打印對話框。 iframe不是要求,但這是我的第一次嘗試。我不確定是否有其他方法可以做到這一點......簡而言之:當我點擊按鈕時,打印對話框應該打開並打印該pdf。 –

回答

9

UPDATE:這link詳細介紹了涉及編輯頁面屬性爲第一頁和添加的頁面打開一個動作一個完美的解決方案。適用於所有瀏覽器(因爲瀏覽器將執行位於操作部分的JavaScript)。需要Adobe Acrobat Pro。


看來2016對印刷問題沒有任何新的進展。有一個類似的問題,並使打印跨瀏覽器我解決了它使用PDF.JS,但不得不作出一個單一的補充來源(他們要求你建立在任何方面)。

的想法:

  • https://mozilla.github.io/pdf.js/getting_started/#download下載預構建的穩定版,並添加了「構建」和「網絡」文件夾到項目中。
  • viewer.html文件是使用豐富的界面呈現PDF幷包含打印功能。我在該文件中添加了一個鏈接到我自己的JavaScript,它在延遲之後簡單地觸發window.print()。

的鏈接添加到瀏覽器:

<script src="viewer.js"></script> 
    <!-- this autoPrint.js was added below viewer.js --> 
    <script src="autoPrint.js"></script> 
</head> 

autoPrint.js的javascript:

(function() { 
    function printWhenReady() { 
     if (PDFViewerApplication.initialized) { 
      window.print(); 
     } 
     else { 
      window.setTimeout(printWhenReady, 3000); 
     } 
    }; 

    printWhenReady(); 
})(); 
  • 然後我可以把呼叫viewer.html?file=中的iframe src和隱藏。不得不使用可視性,不顯示因爲火狐的樣式:

    <iframe src="web/viewer.html?file=abcde.pdf" style="visibility: hidden"> 
    

結果:打印對話框與PDF在短暫的延遲從用戶被隱藏後顯示。

經過Chrome,IE,Firefox的測試。

+0

Pdf.js絕對是一件事情。現代瀏覽器,令人討厭的部分是它有印刷錯誤(像素化輸出,錯誤字體等),我也嘗試過這種做法 –

+0

沒錯,爲了讓事情繼續下去,我承認並儘可能在Pdf.js中解決了缺陷。這些年來,pdf打印將變得簡單... – Balah

+0

您可以在您的答案中添加[此解決方案](http://nvision.co/blog/tips-and-tricks/auto-print-pdf-file-打開/)工作?瀏覽器執行js放在那裏,所以通過在pdf中添加'window.print()'解決了這個問題。 –

5

花費過去幾個小時試圖找出這一個和很多在這裏搜索後是我決定...

HTML5 Web API spec for Printing表明printing steps中的一個必須火beforeprint,一個簡單的事件(一個不可取消的事件),打印到正在打印的文檔的窗口對象(以及任何嵌套的瀏覽上下文,這涉及到iframe),以便在打印之前更改文檔。這一步是瀏覽器內部的,而不是你可以調整的。在這個過程中,瀏覽器的打印對話框有時會顯示文件的預覽(Chrome會這樣做)...所以如果您的目標是永遠不會向查看器顯示文件,您可能會被卡住。

最接近實現這一目標的是創建了一個index.html文件,該文件具有包含提供上下文的data- *屬性的按鈕。將data-print-resource-uri屬性中的路徑/ filename.ext更改爲您自己的本地文件。

<!DOCTYPE html> 
<html> 
    <head> 
     <title>Express</title> 
     <link rel="stylesheet" href="/stylesheets/style.css"> 
    </head> 
    <body> 
     <h1>Express</h1> 
     <p>Welcome to Express</p> 
     <button name="printFile" id="printFile" data-print-resource-uri="/binary/paycheckStub.pdf" data-print-resource-type="application/pdf">Print File</button> 
     <iframe name="printf" id="printf" frameborder="0"></iframe> 
     <script src="/javascripts/print.js"></script> 
    </body> 
</html> 

然後在print.js文件,我嘗試了一些東西,但從來沒有完全得到它的工作(留下我曾在評論與扮演不同的東西)。

// Reference vars 
var printButton = document.getElementById('printFile'); 
var printFrame = document.getElementById('printf'); 

// onClick handler 
printButton.onclick = function(evt) { 
    console.log('evt: ', evt); 
    printBlob('printf', printButton.getAttribute('data-print-resource-uri'), printButton.getAttribute('data-print-resource-type')); 
} 

// Fetch the file from the server 
function getFile(fileUri, fileType, callback) { 
    var xhr = new XMLHttpRequest(); 
    xhr.open('GET', fileUri); 
    xhr.responseType = 'blob'; 
    xhr.onload = function(e) { 
     // Success 
     if(200 === this.status) { 
      // Store as a Blob 
      var blob = new Blob([this.response], {type: fileType}); 
      // Hang a URL to it 
      blob = URL.createObjectURL(blob); 
      callback(blob); 
     } else { 
      console.log('Error Status: ', this.status); 
     } 
    }; 
    xhr.send(); 
} 

function printBlob(printFrame, fileUri, fileType) { 
    // Debugging 
    console.log('inside of printBlob'); 
    console.log('file URI: ', fileUri); 
    console.log('file TYPE: ', fileType); 

    // Get the file 
    getFile(fileUri, fileType, function(data) { 
     loadAndPrint(printFrame, data, fileType); 
    }); 
} 

function loadAndPrint(printFrame, file, type) { 
    // Debugging 
    console.log('printFrame: ', printFrame); 
    console.log('file: ', file); 

    window.frames[printFrame].src = file; 
    window.frames[printFrame].print(); 

    /* 
    // Setup the print window content 
    var windowContent = '<!DOCTYPE html>'; 
    windowContent += '<html>' 
    windowContent += '<head><title>Print canvas</title></head>'; 
    windowContent += '<body>' 
    windowContent += '<embed src="' + file + '" type="' + type + '">'; 
    windowContent += '</body>'; 
    windowContent += '</html>'; 

    // Setup the print window 
    var printWin = window.open('','','width=340,height=260'); 
    printWin.document.open(); 
    printWin.document.write(windowContent); 
    printWin.document.close(); 
    printWin.focus(); 
    printWin.print(); 
    printWin.close(); 
    */ 
} 

我認爲,如果你能得到它工作正常使用Blob可能工作最好在你想要的跨瀏覽器的方法。

我發現這個話題,這可能是一些實用的參考文獻:

+0

有趣的方法,但我沒有看到將src設置爲blob url或只設置文件url直到至少,在解決了代碼中的小問題之後,我在Firefox中遇到了同樣的錯誤:'拒絕訪問屬性的權限'print'' –