作者:E4b9a6, 创建:2022-08-28, 字数:4143, 已阅:141, 最后更新:2022-08-28
接到这个需求的时候感觉非常简单,在公司开发的浏览器中识别特定的url然后自动输出到用户一早默认设置好的打印机中,核心点在于PDF如何直接输出到打印机,以为很简单..
对打印的要求就是最简单的傻瓜化打印,不要预览,直接后台输出到对应打印机
安装RawPrint,在控制台输入
Install-Package RawPrint
调用RawPrint的代码如下
IPrinter printer = new Printer();
FileStream file = File.Open(fileFullPath, FileMode.Open);
byte[] array = new byte[file.Length];
file.Read(array, 0, array.Length);
printer.PrintRawStream(printerName, file, fileName);
file.Close();
printer.PrintRawFile(printerName, fileFullPath, fileName);
测试结果:输出到虚拟打印机也正常,但是输出到公司的真实打印机总是大小不正常,问题可能是文件没有包含打印参数,因为部分PDF又打印正常
Spire.Pdf是用C# 写的PDF组件,他并不是一个专门用来打印PDF的软件,但也包含了这个功能
Spire不是免费的,他是一个企业级产品,测试了打印功能没有任何问题,也可以做到“静默打印”,但单单为了这个功能付费..emmm
在引入Spire.License.dll和 Spire.Pdf.dll之后,可以使用下列代码进行打印测试,这两个文件并不免费,这里也不赞同使用破解版本(仅用于测试用途的破解表示理解)
PdfDocument pdf = new PdfDocument(filePath);
//Set the printer
pdf.PrintSettings.PrinterName = "Microsoft Print to PDF";
pdf.Print();
Windows本身也是提供API进行打印的,也可以做到静默打印
但考虑到公司Windows版本复杂,要应用在多个客户端上成功性难以保证以及调试的复杂性,选择放弃
下列代码也可以用于测试打印效果,使用Process来启动打印进程
PrintDocument pd = new PrintDocument();
Process p = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
pd.PrinterSettings.PrinterName = "Microsoft Print to PDF";
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = true;
startInfo.FileName = filePath;
startInfo.Verb = "print";
startInfo.Arguments = @"/p /h \" + filePath + "\"\"" + pd.PrinterSettings.PrinterName + "\"";
p.StartInfo = startInfo;
p.Start();
p.WaitForExit();
上面的Process启动打印进程是可以使用的,但相对不是太友好
PrintDocument本身也提供打印方法的,直接调用的代码如下
PrintDocument doc = new PrintDocument() {
PrinterSettings = new PrinterSettings() {
// set the printer to 'Microsoft Print to PDF'
PrinterName = "Microsoft Print to PDF",
// tell the object this document will print to file
PrintToFile = false,
// set the filename to whatever you like (full path)
PrintFileName = filePath,
}
};
doc.PrintController = new PrintControllerWithStatusDialog(new StandardPrintController());
doc.Print();
该方法一直输出空白pdf..此处仅提供方法,如有兴趣可深入研究下
var file = File.ReadAllBytes(fileFullPath);
var printQueue = LocalPrintServer.GetDefaultPrintQueue();
using (var job = printQueue.AddJob())
using (var stream = job.JobStream) {
stream.Write(file, 0, file.Length);
}
PdfiumViewer是在Github上找到的项目,项目地址PdfiumViewer - github
这个项目已经停止维护了,但测试之后发现是满足“静默打印“的需求,上述其他解决方案并不是不行,多多少少要么有小毛病要么收费
最终采用PdfiumViewer这个方案,经过一段时间的测试在多个Windows版本上的适应性也非常好,没有其他问题
接下来说说安装,打开项目,转到程序包控制台,并安装如下版本(注意,指定版本是必要的)
Install-Package PdfiumViewer -Version 2.10.0
安装完成之后,现在在你的项目中会多出一个x86和x64文件夹,里面会有pdfium.dll文件,右键该文件,选择属性,在属性栏中的复制到输出目录选择为较新则复制或者始终复制
下面是完整的示例代码,该代码在.Net Framework4.5以上版本测试没有问题
public static void PrintPDF(){
var path = @"path\file.pdf";
using (var document = PdfDocument.Load(path))
{
using (var printDocument = document.CreatePrintDocument())
{
printDocument.PrinterSettings.PrintFileName = "pdf路径";
printDocument.PrinterSettings.PrinterName = @"打印机名称";
printDocument.DocumentName = "文档名称";
printDocument.PrinterSettings.PrintFileName = "在队列中显示的文件名称";
printDocument.PrintController = new StandardPrintController();
printDocument.Print();
}
}
}
C# - How to programmatically print an existing PDF file using PrintDocument?