3

I'm trying to print a PDF file from my Windows 8 app to connected printer. I'm coding with WinJS, and know that I have to create a print task to initiate printing from a Windows 8 app. So, after reviewing the documentation, I have this code:

 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 accepts a specific set of data types. As stated in the documentation:

This can be the root document, the document in an IFrame, a document fragment, or a SVG document. Be aware that htmlDoc must be a document, not an element.

Apparently I cannot simply set the argument for getHtmlPrintDocumentSource to a .PDF or .PNG binary. So, I'm curious: does the WinJS library offer a method for printing so that I can implement the printing of a PDF file to a connected printer? Can anybody offer some tips to implement?

4

2 回答 2

3

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

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

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

<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 打印媒体声明,以便<body>隐藏除 canvas 元素之外的所有元素。这是仅打印 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 中已经存在的画布上。

于 2013-07-11T19:01:56.623 回答
0

据我所知,MSApp.getHtmlPrintDocumentSource(document)它旨在与 HTML 文档对象一起使用,仅此而已。

如果您可以使用 Windows 8.1,您可以尝试通过使用PdfPage.RenderToStreamAsync将每个页面导出为光栅图像,从 PDF 文件中组装一个新的 HTML 文档。MSDN 中有一个用于 PDF 查看器的示例项目,它使用这个新的 API,您可以在其中学习如何使用此方法。

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

例如Amyuni PDF Creator for WinRT可以为您打印免责声明:我目前在开发图书馆的公司工作

于 2013-07-08T19:28:29.783 回答