如何用C#打印PDF
我试图解决这个问题将近2天。 网上有很多或更少的好解决方案,但没有一个完美适合我的任务。
任务:
- 以编程方式打印PDF
- 使用固定打印机进行操作
- 不要让用户做多个Button_Click
- 做到沉默 – 越多越好
- 做客户端
第一解决方案
使用Forms.WebBrowser执行此操作
如果我们安装了Adobe Reader,则有一个插件可以在webbrowser中显示PDF。 有了这个解决方案,我们有一个很好的预览和webbrowserControlName.Print()我们可以触发控件来打印其内容。
问题 – 我们还有一个PrintDialog。
使用start参数启动AcroRd32.exe
以下CMD命令让我们使用Adobe Reader打印PDF。
InsertPathTo .. \ AcroRd32.exe / t“C:\ sample.pdf”“\ printerNetwork \ printerName”
问题 – 我们需要AcroRd32.exe的绝对路径 有一个Adobe Reader窗口打开,必须打开它,直到打印任务准备就绪。
使用Windows预设
Process process = new Process(); process.StartInfo.FileName = pathToPdf; process.StartInfo.Verb = "printto"; process.StartInfo.Arguments = "\"" + printerName + "\""; process.Start(); process.WaitForInputIdle(); process.Kill();
问题 – 仍然有一个Adobe Reader窗口弹出,但在打印完成后它通常会自动关闭。
解决方案 – 说服客户使用福昕阅读器(不要使用最后两行代码)。
将PDF页面转换为Drawing.Image
我不知道怎么用代码来做,但是当我让它工作时剩下的只是小菜一碟。 Printing.PrintDocument可以满足所有需求。
任何人都想要获得一些Drawing.Image来自那些PDF或其他方法如何做到这一点?
最诚挚的问候,马克斯
我能找到的最灵活,最简单和最佳性能的方法是使用GhostScript。 它可以通过打印机名称直接打印到Windows打印机。
“C:\ Program Files \ gs \ gs9.07 \ bin \ gswin64c.exe”-dPrinted -dBATCH -dNOPAUSE -sDEVICE = mswinpr2 -dNoCancel -sOutputFile =“%printer% printer name ”“ pdfdocument.pdf ”
添加这些开关以将文档缩小到A4页面。
-sPAPERSIZE = a4 -dPDFFitPage
另一种方法是在.NET中使用假脱机程序function将预先格式化的打印机数据发送到打印机。 但不幸的是,您需要使用win32假脱机程序API
您可以查看如何使用Visual C#.NET将原始数据发送到打印机
当打印机本身支持PDF文档时,您只能使用此方法。
如果您可以选择商业图书馆,可以尝试使用Amyuni PDF Creator。 净。
直接使用库打印:
要打开PDF文件并将其直接发送到打印,您可以使用方法IacDocument.Print 。 C#中的代码如下所示:
// Open PDF document from file
FileStream file1 = new FileStream ("test.pdf", FileMode.Open, FileAccess.Read); IacDocument doc1 = new IacDocument (null); doc1.Open (file1, "" ); // print document to a specified printer with no prompt doc1.Print ("My Laser Printer", false);
导出到图像(如果需要,然后打印):
选择1:您可以使用方法IacDocument.ExportToJPeg将PDF中的所有页面转换为可以使用Drawing.Image打印或显示的JPG图像
选择2:您可以使用方法System.Drawing.Graphics.FromImage使用方法IacDocument.DrawCurrentPage将每个页面绘制成位图。 C#中的代码应如下所示:
FileStream myFile = new FileStream ("test.pdf", FileMode.Open, FileAccess.Read); IacDocument doc = new IacDocument(null); doc.Open(myFile); doc.CurrentPage = 1; Image img = new Bitmap(100,100); Graphics gph = Graphics.FromImage(img); IntPtr hdc = gph.GetHDC(); doc.DrawCurrentPage(hdc, false); gph.ReleaseHdc( hdc );
免责声明:我为Amyuni Technologies工作
您可以使用ghostscript将PDF转换为图像格式。
以下示例将单个PDF转换为PNG文件序列:
private static void ExecuteGhostscript(string input, string tempDirectory) { // %d will be replaced by ghostscript with a number for each page string filename = Path.GetFileNameWithoutExtension(input) + "-%d.png"; string output = Path.Combine(tempDirectory, filename); Process ghostscript = new Process(); ghostscript.StartInfo.FileName = _pathToGhostscript; ghostscript.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; ghostscript.StartInfo.Arguments = string.Format( "-dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r300 -sOutputFile=\"{0}\" \"{1}\"", output, input); ghostscript.Start(); ghostscript.WaitForExit(); }
如果您更喜欢使用Adobe Reader,则可以隐藏其窗口:
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
我发现使用printto动词的代码略有不同。 我没试过,但也许它可以帮到你:
我知道标签有Windows Forms
; 然而,由于一般标题,有些人可能想知道他们是否可以在WPF
应用程序中使用该命名空间 – 他们可能。
这是代码:
var file = File.ReadAllBytes(pdfFilePath); var printQueue = LocalPrintServer.GetDefaultPrintQueue(); using (var job = printQueue.AddJob()) using (var stream = job.JobStream) { stream.Write(file, 0, file.Length); }
现在,此命名空间必须与WPF
应用程序一起使用。 它与ASP.NET
或Windows Service
不兼容。 它不应该与Windows Forms
一起使用,因为它具有System.Drawing.Printing
。 使用上面的代码我的PDF打印没有任何问题。
请注意,如果您的打印机不支持PDF文件的直接打印,则无法使用。
那么使用PrintDocument
类呢?
http://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument.aspx
您只需要传递要打印的文件的文件名(基于示例)。
HTH
Process proc = new Process(); proc.StartInfo.FileName = @"C:\Program Files\Adobe\Acrobat 7.0\Reader\AcroRd32.exe"; proc.StartInfo.Arguments = @"/p /h C:\Documents and Settings\brendal\Desktop\Test.pdf"; proc.StartInfo.UseShellExecute = false; proc.StartInfo.CreateNoWindow = true; proc.Start(); for (int i = 0; i < 5; i++) { if (!proc.HasExited) { proc.Refresh(); Thread.Sleep(2000); } else break; } if (!proc.HasExited) { proc.CloseMainWindow(); }
如果您对能够满足您需求的商业解决方案感兴趣,那么有很多选择。 我公司在名为Debenu Quick PDF Library的开发人员工具包中提供了其中一个选项。
这是一个代码示例(关键function是PrintOptions和PrintDocument ):
/* Print a document */ // Load a local sample file from the input folder DPL.LoadFromFile("Test.pdf", ""); // Configure print options iPrintOptions = DPL.PrintOptions(0, 0, "Printing Sample") // Print the current document to the default // printing using the options as configured above. // You can also specify the specific printer. DPL.PrintDocument(DPL.GetDefaultPrinterName(), 1, 1, iPrintOptions);
我尝试了很多东西,最适合我的是从命令行启动SumatraPDF:
// Launch SumatraPDF Reader to print String arguments = "-print-to-default -silent \"" + fileName + "\""; System.Diagnostics.Process.Start("SumatraPDF.exe", arguments);
这有很多优点:
- SumatraPDF比Adobe Acrobat Reader快得多。
- 用户界面无法加载。 它只是打印。
- 您可以将SumatraPDF用作独立应用程序,以便将其包含在您的应用程序中,以便您可以使用自己的pa。 请注意,我没有阅读许可协议; 你应该自己检查一下。
截至July 2018
,OP仍然没有答案。 没有免费的方法1)默默地打印您的pdf用于闭源项目。
1)你当然可以使用一个过程,即Adobe Acrobat或Foxit Reader
2)免费解决方案有GPL(GNU的通用公共许可证)。 这意味着如果向公司外的任何人提供软件(即使是免费的),也必须打开源代码。
正如OP所说,如果你可以获得一个PDF到Drawing.Image,你可以用.NET方法打印它。 遗憾的是,执行此操作的软件还需要付款或GPL。
- 使用GC.Collect()是否正确; GC.WaitForPendingFinalizers();?
- 每个请求缓存entity frameworkDbContexts
- 如何在Windows Phone中使用XDocument解析OPML
- 创建自定义全尺寸日历控件
- ASP.NET MVC GetFullHtmlFieldId没有返回有效的id
- 在Visual Studio中添加 – 如何检索文本选择对象的属性(Visual Commander)
- 使用smtpClient.send显示进度条
- C#/ EF和存储库模式:将ObjectContext放在具有多个存储库的解决方案中的位置?
- 如何在maskedtextbox中仅允许强制数值?