我正在尝试将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文件打印到连接的打印机上?任何人都可以提供一些实施技巧吗?
答案 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。 免责声明:我目前在开发图书馆的公司工作