从Windows 8 App打印PDF文档

时间:2013-07-08 18:34:52

标签: pdf windows-8 winjs windows-8.1

我正在尝试将Windows 8应用程序中的PDF文件打印到连接的打印机。我正在使用WinJS进行编码,并且知道我必须创建一个打印任务以从Windows 8应用程序启动打印。因此,在查看文档后,我有以下代码:

 onPrintTaskRequested: function (e) {
        var self = Application.navigator.pageControl,
            printTask = e.request.createPrintTask("Print Test Doc", function (args) {
                args.setSource(MSApp.getHtmlPrintDocumentSource(document));

                // Register the handler for print task completion event
                printTask.oncompleted = self.onPrintTaskCompleted;
            });
    }

According to the documentation, the MSApp.getHhtmlPrintDocumentSource method接受一组特定的数据类型。如文档中所述:

  

这可以是根文档,IFrame中的文档,文档   片段或SVG文档。请注意,htmlDoc必须是文档,   不是元素。

显然我不能简单地将getHtmlPrintDocumentSource的参数设置为.PDF或.PNG二进制文件。所以,我很好奇:WinJS库是否提供了一种打印方法,以便我可以将PDF文件打印到连接的打印机上?任何人都可以提供一些实施技巧吗?

2 个答案:

答案 0 :(得分:3)

经过反复试验,我终于能够实现从Windows 8应用程序打印代表PDF二进制文件的Base64流。

我正在用HTML / CSS / WinJS编写应用程序。基本上这里是对如何完成的简要说明:

<canvas>文件中创建新的default.html元素。将它放在元素的开放标记之后。像这样:

<body role="application" class="app">
    <canvas id="pdf-render-output"></canvas>
    . 
    .
    .
</body>

然后在default.css文件中,设置一些规则以及打印媒体查询。像这样:

body > canvas {
    display: none;
}

.
. /* all your app's default css styles */
.

@media print {

    body > * {
       display:none;
       max-width: 100%;
    }

    html {
       max-width: 100%;
       border-top-color: none;
       border-top: 0;
    }

    body > canvas {
        display: block;
        border: none;
        max-width: 100%;
        width: 100%;
        height: 100%;
        position: relative;
    }
}

值得注意的是CSS中声明规则的顺序。在声明默认CSS规则后放置打印介质查询很重要。

设置完成后,javascript将处理其余部分。基本思想是将PDF.js输出呈现给DOM中的“隐藏”画布。当文档对象被发送到打印时,将查询CSS打印介质声明,以便除了canvas元素之外隐藏<body>下的所有元素。以下是仅打印PDF中第一页的JavaScript:

 //Define a container for the Base64 data we'll use with PDF.js
 var pdfPrintData = {};

 //Function to render PDF to canvas and begin printing contract with Windows 8 OS
 printPrescription: function () {

        var self = Application.navigator.pageControl,
            printManager = Windows.Graphics.Printing.PrintManager.getForCurrentView();

        self.getPDF().done(function () {
            var pdfStream = pdfPrintData.base64,
                pdfFile = convertDataURIToBinary(pdfStream);

            PDFJS.disableWorker = true;
            PDFJS.getDocument(pdfFile).then(function (pdf) {

                var numPages = pdf.numPages,
                    renderCanvas = $('#pdf-render-output')[0];

                //setup canvas
                renderCanvas.height = pdf.getPage(1).data.getViewport(1).height;
                renderCanvas.width = pdf.getPage(1).data.getViewport(1).width;

                //Setup a render context for pdf.js to out a pdf file to the canvas.
                var renderContext = {
                        canvasContext: renderCanvas.getContext('2d'),
                        viewport: pdf.getPage(1).data.getViewport(1)
                    };

                //Bring up Windows 8 OS print after PDF is rendered to render context.
                pdf.getPage(1).data.render(renderContext).then(function () {
                    printManager.onprinttaskrequested = self.onPrintTaskRequested;
                    Windows.Graphics.Printing.PrintManager.showPrintUIAsync();
                });

            })

        });

},
onPrintTaskRequested: function (e) {
        var self = Application.navigator.pageControl,
            printTask = e.request.createPrintTask("Print Prescription", function (args) {
                args.setSource(MSApp.getHtmlPrintDocumentSource(document));
                printTask.oncompleted = self.onPrintTaskCompleted;
            });

},
onPrintTaskCompleted: function (e) {
        if (e.completion === Windows.Graphics.Printing.PrintTaskCompletion.failed) {
            console.log("[ERX]  :   Failed to print!");
        }
    }

self.getPDF方法只是一个检索Base64数据流的函数,并且该流在全局.base64对象的pdfPrintData属性上设置。出于某种原因,我无法使用pdf.js将pdf呈现为动态创建的文档中的动态创建画布。我必须将pdf.js渲染方法的输出渲染到DOM中已存在的画布。

答案 1 :(得分:0)

据我所知,MSApp.getHtmlPrintDocumentSource(document)旨在与HTML文档对象一起使用,而不是其他任何内容。

如果您可以使用Windows 8.1,则可以尝试使用PdfPage.RenderToStreamAsync将每个页面导出为光栅图像,从PDF文件中组合新的HTML文档。对于使用此新API的PDF查看器,有一个sample project in MSDN,您可以在其中学习如何使用此方法。

如果您不能使用Windows 8.1并且需要支持普通的Windows 8或Windows RT(ARM),则可能需要使用第三方库来创建光栅图像或一起进行打印。

Amyuni PDF Creator for WinRT例如can do the printing for you免责声明:我目前在开发图书馆的公司工作