【发布时间】:2018-02-11 05:29:55
【问题描述】:
我目前正在构建一个电子应用程序。我的本地文件系统上有一个 PDF,我需要静默打印出来(在默认打印机上)。我遇到了节点打印机库,但它似乎对我不起作用。有没有简单的解决方案来实现这一点?
【问题讨论】:
我目前正在构建一个电子应用程序。我的本地文件系统上有一个 PDF,我需要静默打印出来(在默认打印机上)。我遇到了节点打印机库,但它似乎对我不起作用。有没有简单的解决方案来实现这一点?
【问题讨论】:
我最近发布了 NPM 包,用于从 Node.js 和 Electron 打印 PDF 文件。您可以将 PDF 文件发送到默认打印机或特定打印机。在 Windows 和类 Unix 操作系统上运行良好:https://github.com/artiebits/pdf-to-printer。
它很容易安装,只是(如果使用 yarn):
yarn add pdf-to-printer
或(如果使用 npm):
npm install --save pdf-to-printer
然后,将文件静默打印到默认打印机:
import { print } from "pdf-to-printer";
print("assets/pdf-sample.pdf")
.then(console.log)
.catch(console.error);
【讨论】:
据我所知,目前无法直接使用 Electron 执行此操作,因为虽然使用 contents.print([]) 确实允许“静默”打印 HTML 文件,但它无法打印 PDF 视图。目前这是一个开放的功能请求:https://github.com/electron/electron/issues/9029
编辑:我设法通过将 PDF 转换为 PNG,然后使用 Electron 的打印功能(能够打印 PNG)来打印基于图像的视图来解决这个问题。这样做的主要缺点之一是 NodeJS 的所有 PDF 到 PNG/JPEG 转换库都有许多依赖项,这意味着我必须在 Express 服务器中实现它们,然后让我的 Electron 应用程序将所有 PDF 发送到服务器转换。这不是一个很好的选择,但它确实有效。
【讨论】:
首先,几乎不可能理解“无声”打印的含义。因为一旦您向系统打印机发送打印订单,您将无法完全保持沉默。例如,在 Windows 上,一旦下达订单,至少系统托盘图标将指示正在发生的事情。也就是说,电子打印有很好的描述功能,甚至“无声”也是其中之一:
如果您不想使用默认打印机,则需要获取all system printers:
contents.getPrinters()
这将返回一个PrinterInfo[] 对象。
下面是electron PrtinerInfo Docs 中对象的外观示例:
{
name: 'Zebra_LP2844',
description: 'Zebra LP2844',
status: 3,
isDefault: false,
options: {
copies: '1',
'device-uri': 'usb://Zebra/LP2844?location=14200000',
finishings: '3',
'job-cancel-after': '10800',
'job-hold-until': 'no-hold',
'job-priority': '50',
'job-sheets': 'none,none',
'marker-change-time': '0',
'number-up': '1',
'printer-commands': 'none',
'printer-info': 'Zebra LP2844',
'printer-is-accepting-jobs': 'true',
'printer-is-shared': 'true',
'printer-location': '',
'printer-make-and-model': 'Zebra EPL2 Label Printer',
'printer-state': '3',
'printer-state-change-time': '1484872644',
'printer-state-reasons': 'offline-report',
'printer-type': '36932',
'printer-uri-supported': 'ipp://localhost/printers/Zebra_LP2844',
system_driverinfo: 'Z'
}
}
要打印您的文件,您可以使用
contents.print([options])
选项描述在docs for contents.print():
打印窗口的网页。当silent 设置为true 时,如果deviceName 为空且默认设置为打印,Electron 将选择系统的默认打印机。
在网页中调用window.print()相当于调用webContents.print({silent: false, printBackground: false, deviceName: ''})。
使用page-break-before: always; CSS 样式强制打印到新页面。
因此,您只需将 PDF 加载到隐藏窗口中,然后触发在电子中实现的打印方法,并将标志设置为静默。
// In the main process.
const {app, BrowserWindow} = require('electron');
let win = null;
app.on('ready', () => {
// Create window
win = new BrowserWindow({width: 800, height: 600, show: false });
// Could be redundant, try if you need this.
win.once('ready-to-show', () => win.hide())
// load PDF.
win.loadURL(`file://directory/to/pdf/document.pdf`);
// if pdf is loaded start printing.
win.webContents.on('did-finish-load', () => {
win.webContents.print({silent: true});
// close window after print order.
win = null;
});
});
不过,让我给你一点警告:
一旦你开始打印,它就会变得令人沮丧,因为那里有驱动程序会以稍微不同的方式解释数据。这意味着可以忽略边距等等。由于您已经拥有 PDF,因此这个问题很可能不会发生。但是如果你想使用this method for examplecontents.printToPDF(options, callback),请记住这一点。那beeing说有很多选择可以避免像使用这个问题中描述的预定义样式表一样感到沮丧:Print: How to stick footer on every page to the bottom?
如果您想在 electron 中搜索功能,但不知道它们可以隐藏在哪里,您只需转到“所有”文档并使用您的搜索功能:https://electron.atom.io/docs/all/
问候, 大金
【讨论】:
win.hide()。而已。如果对您有帮助,请考虑接受我的回答
BrowserWindow