如何用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动词的代码略有不同。 我没试过,但也许它可以帮到你:

http://vbcity.com/forums/t/149141.aspx

我知道标签有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.NETWindows 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); 

这有很多优点:

  1. SumatraPDF比Adobe Acrobat Reader快得多。
  2. 用户界面无法加载。 它只是打印。
  3. 您可以将SumatraPDF用作独立应用程序,以便将其包含在您的应用程序中,以便您可以使用自己的pa。 请注意,我没有阅读许可协议; 你应该自己检查一下。

截至July 2018 ,OP仍然没有答案。 没有免费的方法1)默默地打印您的pdf用于闭源项目。

1)你当然可以使用一个过程,即Adobe Acrobat或Foxit Reader

2)免费解决方案有GPL(GNU的通用公共许可证)。 这意味着如果向公司外的任何人提供软件(即使是免费的),也必须打开源代码。

正如OP所说,如果你可以获得一个PDF到Drawing.Image,你可以用.NET方法打印它。 遗憾的是,执行此操作的软件还需要付款或GPL。