在C#中打印现有的PDF(或其他文件)

26
从我正在构建的应用程序中,我需要打印现有的PDF文件(由另一个应用程序创建)。 如何在C#中实现这一目标并提供机制让用户选择不同的打印机或其他属性。
我查看了PrintDialog,但不确定它尝试打印哪个文件(如果有的话),因为输出总是一张空白纸。也许我只是漏掉了什么。
我需要使用“iTextSharp”吗(正如其他地方建议的)?这对我来说似乎很奇怪,因为我可以“将文件发送到打印机”,只是没有漂亮的对话框来设置打印机等,而且我真的不想从头开始编写打印对话框,但似乎我通过搜索找到的许多示例都是这样做的。
任何建议、示例或样本代码都将是极好的!
此外,如果PDF是问题,那么文件可以由另一个应用程序以不同的格式(例如位图或png)创建。

这里有谁知道如何打印随机文件,而不仅仅是PDF文件吗? Tobi - Tobias
3
随机文件会与随机应用程序相关联。即使是.doc 文件也可以与 WordPad、Word 或 OpenOffice 相关联。每个应用程序都有自己的渲染方式。因此,唯一有用的方法是利用 Windows 对所涉及文件类型的文件关联性。 - Ruben Bartelink
相关问题:https://dev59.com/h2gu5IYBdhLWcg3wGjZF - yms
6个回答

23

显示一个小对话框,其中的下拉列表框的项是由PrinterSettings.InstalledPrinters返回的字符串集合设置。

如果您可以要求在机器上安装GSView,那么您就可以静默打印PDF文档。这可能有点慢和绕远路,但至少您不必弹出Acrobat。

这是我用来打印从UPS Web服务返回的一些PDF文档的代码:

    private void PrintFormPdfData(byte[] formPdfData)
    {
        string tempFile;

        tempFile = Path.GetTempFileName();

        using (FileStream fs = new FileStream(tempFile, FileMode.Create))
        {
            fs.Write(formPdfData, 0, formPdfData.Length);
            fs.Flush();
        }

        try
        {
            string gsArguments;
            string gsLocation;
            ProcessStartInfo gsProcessInfo;
            Process gsProcess;

            gsArguments = string.Format("-grey -noquery -printer \"HP LaserJet 5M\" \"{0}\"", tempFile);
            gsLocation = @"C:\Program Files\Ghostgum\gsview\gsprint.exe";

            gsProcessInfo = new ProcessStartInfo();
            gsProcessInfo.WindowStyle = ProcessWindowStyle.Hidden;
            gsProcessInfo.FileName = gsLocation;
            gsProcessInfo.Arguments = gsArguments;

            gsProcess = Process.Start(gsProcessInfo);
            gsProcess.WaitForExit();
        }
        finally
        {
            File.Delete(tempFile);
        }
    }

正如您所看到的,它将PDF数据作为字节数组进行处理,将其写入临时文件,并启动gsprint.exe以静默方式将文件打印到指定的打印机(“HP Laserjet 5M”)。您可以将打印机名称替换为用户在对话框中选择的任何内容。

打印PNG或GIF会更容易--只需扩展PrintDocument类并使用Windows Forms提供的普通打印对话框即可。

祝你好运!


这对我帮助很大。我有一个内部网站应用程序,需要无人值守地将文档打印到网络打印机。所有其他方法都失败了,但这个方法可行! - Aaron

2

虽然这段代码是用VB编写的,但你可以很容易地将其翻译成其他语言。顺便说一下,Adobe并不会弹出窗口,它只会打印PDF文件然后关闭。

''' <summary>
''' Start Adobe Process to print document
''' </summary>
''' <param name="p"></param>
''' <remarks></remarks>
Private Function printDoc(ByVal p As PrintObj) As PrintObj
    Dim myProcess As New Process()
    Dim myProcessStartInfo As New ProcessStartInfo(adobePath)
    Dim errMsg As String = String.Empty
    Dim outFile As String = String.Empty
    myProcessStartInfo.UseShellExecute = False
    myProcessStartInfo.RedirectStandardOutput = True
    myProcessStartInfo.RedirectStandardError = True

    Try

        If canIprintFile(p.sourceFolder & p.sourceFileName) Then
            isAdobeRunning(p)'Make sure Adobe is not running; wait till it's done
            Try
                myProcessStartInfo.Arguments = " /t " & """" & p.sourceFolder & p.sourceFileName & """" & " " & """" & p.destination & """"
                myProcess.StartInfo = myProcessStartInfo
                myProcess.Start()
                myProcess.CloseMainWindow()
                isAdobeRunning(p)
                myProcess.Dispose()
            Catch ex As Exception
            End Try
            p.result = "OK"
        Else
            p.result = "The file that the Document Printer is tryng to print is missing."
            sendMailNotification("The file that the Document Printer is tryng to print" & vbCrLf & _
            "is missing. The file in question is: " & vbCrLf & _
            p.sourceFolder & p.sourceFileName, p)
        End If
    Catch ex As Exception
        p.result = ex.Message
        sendMailNotification(ex.Message, p)
    Finally
        myProcess.Dispose()
    End Try
    Return p
End Function

Sumatra PDF还具有静默打印命令行参数,如果您不喜欢gsview的话。http://blog.kowalczyk.info/software/sumatrapdf/manual.html - jmmr
也许Adobe曾经默默地打印过,但现在不再这样了。因此而投反对票! - HK1

1

我在我的项目中也做了同样的事情,而且它对我起作用了。

看看它是否能帮到你...

Process p = new Process();
p.EnableRaisingEvents = true; //Important line of code
p.StartInfo = new ProcessStartInfo()
{
    CreateNoWindow = true,
    Verb = "print",
    FileName = file,
    Arguments = "/d:"+printDialog1.PrinterSettings.PrinterName
};   
try
{
    p.Start();
} 
catch 
{ 
    /* your fallback code */ 
}

您还可以尝试不同的窗口选项

使用PRINT命令获取所需的输出...参考链接


1

经过大量的研究和搜索,微软发布了一个很棒的KB来打印PDF文件,无需任何其他应用程序。无需调用Adobe或Ghostprint。它可以在不保存文件到磁盘的情况下进行打印,使生活变得非常容易。

http://support2.microsoft.com/?kbid=322091


它可以在一些打印机上工作。打印机需要能够自己处理PDF文件。如果不能,PDF文件将会像文本文件一样打印。 - Jeff Cuscutis
2
以上链接被重定向到 https://support.microsoft.com/?kbid=322091,但是什么也没有。 - Syed Irfan Ahmad

1

7
请注意,PDFSharp使用Adobe Reader进行打印。Adobe不支持使用静默打印的功能,这种做法有些折衷。甚至作者在源代码中也指出了这一点。http://pdfsharp.codeplex.com/SourceControl/changeset/view/51421#707803 - jmmr

1

您需要Acrobat或其他能够打印PDF的应用程序。从那里,您可以使用P/Invoke调用ShellExecute来打印文档。


1
你能在那个调用中传递打印机选择和其他参数吗? - Aaron Fischer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接