从Windows 8应用程序打印PDF文档

从Windows 8应用程序打印PDF文档,pdf,windows-8,winjs,windows-8.1,Pdf,Windows 8,Winjs,Windows 8.1,我正在尝试将Windows 8应用程序中的PDF文件打印到连接的打印机。我正在用WinJS编码,我知道我必须创建一个打印任务才能从Windows8应用程序启动打印。因此,在查看文档后,我有以下代码: onPrintTaskRequested: function (e) { var self = Application.navigator.pageControl, printTask = e.request.createPrintTask("Print T

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

 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;
            });
    }
接受一组特定的数据类型。如文件所述:

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


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

据我所知,
MSApp.getHtmlPrintDocumentSource(document)
用于HTML文档对象,而不是其他

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

如果无法假定Windows 8.1并且需要支持普通Windows 8或Windows RT(ARM),则可能需要使用第三方库来创建光栅图像或同时进行打印


比如说。免责声明:我目前为开发该库的公司工作

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

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

default.html
文件中创建一个新的
元素。将其放置在图元的打开标记的正后方。像这样:

<body role="application" class="app">
    <canvas id="pdf-render-output"></canvas>
    . 
    .
    .
</body>
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打印介质声明,以便隐藏
下的所有元素,但画布元素除外。以下是仅打印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数据流的函数,该流在全局
pdfPrintData
对象的
.Base64
属性上设置。由于某些原因,我无法使用pdf.js将pdf呈现到动态创建文档中的动态创建画布。我必须将pdf.js render方法的输出渲染到DOM中已经存在的画布上。

谢谢提示。我在谷歌搜索中找到了Amyuni PDF创建者。使用该软件是否有免费试用?此外,您还提到“您可能需要使用第三方库来创建光栅图像”。你是说像PDF.js这样的东西吗?@ariestav有一个30天的免费试用和免费支持。关于“第三方库”,我的意思是你不能单独使用WinRT API打印,所以我实际上指的是任何第三方库,商业的或开源的。我尽量公平地回答SO中的问题。关于PDF.js,我或多或少知道它的功能,但我从未使用过它,所以我不知道它是否可以用于打印或光栅化。Amyuni针对不同的体系结构有不同的文件。我的构建在VS2012的配置管理器中设置为“AnyCPU”。鉴于我的构建过程,我将如何包含它?@yms pdf.js可能无法正常工作。我之前尝试过用这种方法来渲染PDF,但遇到了字体无法加载的问题。它尝试插入不能与winjs一起使用的
标记。如果你尝试在pdf.js上使用你的手-将很好地分享你的发现。