Print a pdf without visually opening it

前端 未结 2 489
一向
一向 2021-01-31 03:40

The thing I want to build is that by clicking a button I want to trigger the print of a PDF file, but without opening it.

+-----------+
| Print PDF |
+----------         


        
相关标签:
2条回答
  • 2021-01-31 04:12

    UPDATE: This link details an elegant solution that involves editing the page properties for the first page and adding an action on Page Open. Works across all browsers (as browsers will execute the JavaScript placed in the actions section). Requires Adobe Acrobat Pro.


    It seems 2016 brings no new advancements to the printing problem. Had a similar issue and to make the printing cross-browser I solved it using PDF.JS but had to make a one-liner addition to the source (they ask you to build upon it in anyways).

    The idea:

    • Download the pre-built stable release from https://mozilla.github.io/pdf.js/getting_started/#download and add the "build" and "web" folders to the project.
    • The viewer.html file is what renders out PDFs with a rich interface and contains print functionality. I added a link in that file to my own JavaScript that simply triggers window.print() after a delay.

    The link added to viewer:

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

    The autoPrint.js javascript:

    (function () {
        function printWhenReady() {
            if (PDFViewerApplication.initialized) {
                window.print();
            }
            else {
                window.setTimeout(printWhenReady, 3000);
            }
        };
    
        printWhenReady();
    })();
    
    • I could then put calls to viewer.html?file= in the src of an iframe and hide it. Had to use visibility, not display styles because of Firefox:

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

    The result: the print dialog showed after a short delay with the PDF being hidden from the user.

    Tested in Chrome, IE, Firefox.

    0 讨论(0)
  • 2021-01-31 04:17

    After spending the past couple of hours trying to figure this one out and lots of searching here is what I have determined...

    The HTML5 Web API spec for Printing indicates that one of the printing steps must fire beforeprint, a simple event (an event that is non-cancelable), to the window object of the Document being printed (as well as any nested browsing contexts, this relates to iframes) to allow for changes to the Document prior to printing. This step is internal to the browser and not something you'll be able to adjust. During this process, the browser's print dialog sometimes shows a preview of the file (Chrome does this)...so if your goal is to never display the file to the viewer you might be stuck.

    The closest to achieving this I came was by creating an index.html file which has a button containing data-* attributes which provided context. Change the path/filename.ext in the data-print-resource-uri attribute to a local file of your own.

    <!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>
    

    Then in the print.js file, I tried a few things, but never quite got it working (leaving different things I had played with in the comments).

    // 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();
        */
    }
    

    I think that if you can get it working properly using the Blob might work the best in the cross-browser method you wanted.

    I found a few references about this topic which might be helpful:

    • How to send a pdf file directly to the printer using JavaScript?

    • https://www.w3.org/TR/html5/webappapis.html#printing

    • https://developer.mozilla.org/en-US/docs/Web/Guide/Printing#Print_an_external_page_without_opening_it

    • Printing a web page using just url and without opening new window?

    0 讨论(0)
提交回复
热议问题