Printing a PDF file with Electron JS

后端 未结 5 1847
执笔经年
执笔经年 2021-02-04 00:37

I am trying to create an Electron JS app that has the purpose to print letter size PDFs.

This is my snippet of code for printing:

win = new BrowserWindow         


        
5条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-04 01:08

    I'm facing the same issue. It appears the PDF printing to a printer is just not implemented in Electron, despite it's been requested since 2017. Here is another related question on SO and the feature request on GitHub:

    • Silent printing in electron
    • Support printing in native PDF rendering

    One possible solution might be to use Google PDFium and a wrapping NodeJS library which appears to allow conversion from PDF to a set of EMFs, so the EMFs can be printed to a local/network printer, at least on Windows.

    As another viable option, this answer provides a simple C# solution for PDF printing using PdfiumViewer, which is a PDFium wrapper library for .NET.

    I'm sill looking at any other options. Utilizing a locally installed instance of Acrobat Reader for printing is not an acceptable solution for us.


    UPDATED. For now, PDF.js solves the problem with rendering/previewing individual pages, but as to printing itself, it appears Electron (at the time of this posting) just lacks the proper printing APIs. E.g., you can't set paper size/landscape portrait mode etc. Moreover, when printing, PDF.js produces rasterized printouts - thanks to how HTML5 canvas work - unlike how Chrome PDF Viewer does it. Here is a discussion of some other PDF.js shortcomings.

    So for now I think we might go on with a combination of PDF.js (for UI in the Electron's Renderer process) and PDFium (for actual printing from the Main process).

    Based on Tim's answer, here's a version of the PDF.js renderer using ES8 async/await (supported as of the current version of Electron):

    async function renderPDF(url, canvasContainer, options) {
        options = options || { scale: 1 };
    
        async function renderPage(page) {
            let viewport = page.getViewport(options.scale);
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d');
            let renderContext = {
                canvasContext: ctx,
                viewport: viewport
            };
    
            canvas.height = viewport.height;
            canvas.width = viewport.width;
            canvasContainer.appendChild(canvas);
    
            await page.render(renderContext);
        }
    
        let pdfDoc = await pdfjsLib.getDocument(url);
    
        for (let num = 1; num <= pdfDoc.numPages; num++)
        {
            if (num > 1)
            {
                // page separator
                canvasContainer.appendChild(document.createElement('hr'));
            }
            let page = await pdfDoc.getPage(num);
            await renderPage(page);
        }
    }
    

提交回复
热议问题