如何用C#打印PDF

时间:2012-07-20 12:42:44

标签: c# winforms pdf printing

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

任务:

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

第一个解决方案:

使用Forms.WebBrowser

执行此操作

如果我们安装了Adobe Reader,则有一个插件可以在webbrowser中显示PDF。使用此解决方案,我们有一个很好的预览,使用webbrowserControlName.Print()我们可以触发控件来打印其内容。

问题 - 我们还有PrintDialog。


使用启动参数启动AcroRd32.exe

以下CMD命令让我们使用Adobe Reader打印PDF。

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

问题 - 我们需要AcroRd32.exe的绝对路径有一个Adobe Reader Window打开,必须打开它,直到打印任务准备就绪。


使用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可以满足所有需求。


任何人都有想法从这些PDF或其他方法中获取一些Drawing.Image如何做到这一点?

最诚挚的问候, 最大

12 个答案:

答案 0 :(得分:6)

我能找到的最灵活,最简单,性能最佳的方法是使用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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分: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工作

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

我知道标签有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文件的直接打印,则无法使用。

答案 6 :(得分:0)

如何使用PrintDocument类?

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

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

HTH

答案 7 :(得分:0)

        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();
        }

答案 8 :(得分:0)

如果您对完全符合要求的商业解决方案感兴趣,那么有很多选择。我的公司在名为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);

答案 9 :(得分:0)

我尝试了很多东西,最适合我的是从命令行启动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。请注意,我没有阅读许可协议;你应该自己检查一下。

答案 10 :(得分:0)

截至July 2018,OP仍然没有答案。没有免费的方法来进行以下操作:1)静默打印2)封闭源项目的pdf。

1)您当然可以使用某个流程,即Adobe Acrobat或Foxit Reader

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

如OP所述,如果可以将PDF获取到Drawing.Image,则可以使用.NET方法进行打印。遗憾的是,要执行此操作,软件还需要付款或GPL。

答案 11 :(得分:0)

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

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

还有指向示例代码的链接。

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