【问题标题】:How to print a PDF with C#如何使用 C# 打印 PDF
【发布时间】:2012-07-19 17:54:50
【问题描述】:

我试图解决这个问题将近 2 天。网上有很多或多或少的好解决方案,但没有一个完全适合我的任务。

任务:

  • 以编程方式打印 PDF
  • 使用固定打印机进行操作
  • 不要让用户执行多次 Button_Click
  • 保持沉默 - 越多越好
  • 做客户端

第一个解决方案:

使用 Forms.WebBrowser 进行操作

如果我们安装了 Adob​​e Reader,有一个插件可以在网络浏览器中显示 PDF。有了这个解决方案,我们有一个很好的预览,并且有了 webbrowserControlName.Print(),我们可以触发控件来打印它的内容。

问题 - 我们还有一个 PrintDialog。


使用启动参数启动 AcroRd32.exe

下面的 CMD 命令让我们使用 Adob​​e Reader 来打印我们的 PDF。

InsertPathTo..\AcroRd32.exe /t "C:\sample.pdf" "\printerNetwork\printerName"

问题 - 我们需要 AcroRd32.exe 的绝对路径 |有一个 Adob​​e Reader 窗口打开,必须打开它,直到打印任务准备好。


使用 Windows 预设

Process process = new Process();

process.StartInfo.FileName = pathToPdf; 
process.StartInfo.Verb = "printto";
process.StartInfo.Arguments = "\"" + printerName + "\""; 
process.Start();

process.WaitForInputIdle();
process.Kill();

问题 - 仍然会弹出一个 Adob​​e Reader 窗口,但打印完成后它通常会自行关闭。

解决方案 - 说服客户使用 Foxit Reader(不要使用最后两行代码)。


将 PDF 页面转换为 Drawing.Image

我不知道如何使用代码来完成,但是当我让它工作时,剩下的只是小菜一碟。 Printing.PrintDocument 可以满足所有需求。


有人想从那些 PDF 中获取一些 Drawing.Image 或其他方法吗?

最好的问候, 最大

【问题讨论】:

  • 要获取 Drawing.Image,您可以查看此示例:ghostscriptnet.codeplex.com/SourceControl/…
  • 这是几年后的事了……你能弄清楚Drawing.Image 路线吗?
  • @B.K.可悲的是没有 - 但今天可能有更好的方法
  • @Max 我已经找了好几个月了,但我还没有找到一个不涉及在客户端机器上安装东西的解决方案......在我的情况下这不是一个选项.

标签: c# winforms pdf printing


【解决方案1】:

我能找到的最灵活、最简单、性能最好的方法是使用 GhostScript。它可以通过打印机名称直接打印到windows打印机。

"C:\Program Files\gs\gs9.07\bin\gswin64c.exe" -dPrinted -dBATCH -dNOPAUSE -sDEVICE=mswinpr2 -dNoCancel -sOutputFile="%printer%打印机名称 " "pdfdocument.pdf"

添加这些开关可将文档缩小为 A4 页面。

-sPAPERSIZE=a4 -dPDFFitPage

【讨论】:

  • 我建议为此使用 Ghostscript 包装器。比如:ghostscriptnet.codeplex.com
  • @HABJAN 感谢您的建议,看起来确实很有用。
  • 我使用了 Ghostscript.NET(可通过 NuGet 获得)。当我尝试最新版本的ghostscript(9.18)时,我收到了内存访问异常。我卸载了 9.18,发现 Ghostscript.NET 上次构建之前的最新版本是 9.15。一旦我安装了它,一切似乎都开始工作了。您可以在downloads.ghostscript.com/public 获取先前版本的 ghostscript
  • Ghostscript 的 mswinpr2 质量相当差 - 它将输入的 PDF 文件转换为光栅文件并打印出来。更好的方法是使用 3rd 方组件或尝试自己实现某些东西,尤其是打印机众所周知的 PDF/PS。在这里我找到了简单而漂亮的命令行工具effisoft.pl/rawfileprinter
【解决方案2】:

另一种方法是使用 .NET 中的假脱机功能将预先格式化的打印机数据发送到打印机。但不幸的是,您需要使用 win32 spooler API

你可以看看How to send raw data to a printer by using Visual C# .NET

只有当打印机本身支持 PDF 文档时,才能使用此方法。

【讨论】:

  • 我在回答中没有提到的好点。我会更新答案,但可能是 OP 需要的?
  • 好点,但我不能确定所有打印机都支持它。即使目前所有的打印机都支持它,如果他们购买没有此功能的其他产品也会有问题。
  • 链接现在转到 404。
【解决方案3】:

如果可以选择商业库,您可以尝试使用Amyuni PDF Creator. Net.

直接使用库打印:
要打开 PDF 文件并直接发送打印,您可以使用方法IacDocument.Print。 C# 中的代码将如下所示:

// Open PDF document from file<br>
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:您可以使用方法 IacDocument.DrawCurrentPage 和方法 System.Drawing.Graphics.FromImage 将每个页面绘制成位图。 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 工作

【讨论】:

    【解决方案4】:

    您可以使用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();
    }
    

    如果您更喜欢使用 Adob​​e Reader,您可以隐藏它的窗口:

    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    

    【讨论】:

      【解决方案5】:

      我发现使用 printto 动词的代码版本略有不同。我没试过,但也许对你有帮助:

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

      【讨论】:

      • 好的,刚刚看到这行不通:Adobe 的论坛说,新版本的 Adob​​e Reader 不允许您打印“静默”、“出于安全原因”(当然,Adobe)...总会有一个窗口。
      【解决方案6】:

      我知道标签有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 文件,这将不起作用。

      【讨论】:

        【解决方案7】:

        我尝试了很多方法,最适合我的方法是从命令行启动 SumatraPDF:

        // Launch SumatraPDF Reader to print
        String arguments = "-print-to-default -silent \"" + fileName + "\"";
        System.Diagnostics.Process.Start("SumatraPDF.exe", arguments);
        

        这样做有很多好处:

        1. SumatraPDF 比 Adob​​e Acrobat Reader 快得多。
        2. UI 未加载。它只是打印。
        3. 您可以将 SumatraPDF 作为一个独立的应用程序使用,这样您就可以将它包含在您的应用程序中,这样您就可以使用自己的 pa。请注意,我没有阅读许可协议;你应该自己去看看。

        【讨论】:

          【解决方案8】:

          我公司提供 Docotic.Pdf 库,可以render and print PDF documents。链接后面的文章包含有关以下主题的详细信息:

          • 直接在 Windows 窗体或 WPF 应用程序中打印 PDF
          • 通过中间图像打印 PDF
          • 在图形上渲染 PDF

          也有示例代码的链接。

          我在公司工作,所以请阅读这篇文章并自己尝试建议的解决方案。

          【讨论】:

            【解决方案9】:

            使用PrintDocument 类怎么样?

            http://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument.aspx

            您只需要传递您要打印的文件的文件名(基于示例)。

            HTH

            【讨论】:

            • 正如我所描述的,这可以与 Drawing.Image 一起使用。它不适用于 .pdf。检查 pd_PrintPage(object sender, PrintPageEventArgs ev) 事件。 .txt 文件中的每一行都转换为打印输出。
            • 请参阅daniweb.com/software-development/csharp/threads/90272/… 以获得可能的解决方案。
            【解决方案10】:
                    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();
                    }
            

            【讨论】:

              【解决方案11】:

              如果您对完全符合您要求的商业解决方案感兴趣,那么有很多选择。我的公司在名为 Debenu Quick PDF Library 的开发人员工具包中提供了其中一个选项。

              这是一个代码示例(关键函数是PrintOptionsPrintDocument):

              /* 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);
              

              【讨论】:

                【解决方案12】:

                截至July 2018,OP 仍然没有答案。没有免费的方法可以 1) 为 2) 闭源项目静默打印您的 pdf。

                1) 您当然可以使用 Adob​​e Acrobat 或 Foxit Reader 等进程

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

                正如 OP 所说,如果您可以将 PDF 转换为 Drawing.Image,则可以使用 .NET 方法打印它。遗憾的是,执行此操作的软件还需要付费或 GPL。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-11-07
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-09-09
                  • 2020-04-28
                  相关资源
                  最近更新 更多