在VB.net中打印外部PDF文档

时间:2014-11-17 10:42:38

标签: vb.net printing

我知道之前已经问过这个问题,但我的情况有点不稳定。

基本上,我正在尝试打印使用以前的Windows窗体生成的PDF文件。我可以找到该文件没问题,我使用了以下代码,我在MSDN的帮助论坛上找到了这些代码:

Dim p As New System.Diagnostics.ProcessStartInfo()
p.Verb = "print"
p.WindowStyle = ProcessWindowStyle.Hidden
p.FileName = "C:\534679.pdf"   'This is the file name
p.UseShellExecute = True
System.Diagnostics.Process.Start(p)

到目前为止一切顺利,但每次按下按钮运行此代码时,它都会一直要求我将其另存为PDF文件,如下所示:

enter image description here

我也尝试将PrintDialog添加到Windows窗体中,让它弹出,我可以从那里选择我想要使用的打印机,但即使选择了打印机,它仍然要求我打印到PDF文档代替。

我做错了什么?

4 个答案:

答案 0 :(得分:2)

首先,为了能够选择打印机,您必须使用 PrintDialog PrintDocument 来发送图形以打印到所选的打印机。< / p>

Imports System.Drawing.Printing

    Private WithEvents p_Document As PrintDocument = Nothing

    Private Sub SelectPrinterThenPrint()
        Dim PrintersDialog As New PrintDialog()

        If PrintersDialog.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK Then
            Try
                p_Document = New PrintDocument()
                PrintersDialog.Document = p_Document
                AddHandler p_Document.PrintPage, AddressOf HandleOnPrintPage

            Catch CurrentException As Exception

            End Try
        End If
    End Sub

    Private Sub HandleOnPrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs) Handles p_Document.PrintPage
        Dim MorePagesPending As Boolean = False

        'e.Graphics.Draw...(....)
        'e.Graphics.DrawString(....)
        ' Draw everything...

        If MorePagesPending Then
            e.HasMorePages = True
        Else
            e.HasMorePages = False
        End If
    End Sub

这就是我正在做的事情,因为我通常要打印自定义对象。


但是要打印PDF文件,你必须明白PDF对dotNet来说意味着绝对没有。与像Bitmaps(.bmp)或Ping图像(.png)这样的常见图像不同,dotNet似乎没有任何内置的解析器/解码器来读取,显示和打印PDF文件。

因此,您必须使用第三方应用,第三方或您自己的自定义PDF解析器/布局生成器才能使用发送要打印到打印机的页面。

这就是为什么您无法使用命令&#34; print&#34;启动隐藏(不可见)的Acrobat Reader过程。您无法选择打印机,但会转而使用默认打印机!

然而,你可以启动Acrobat Reader进程只是为了打开文件,然后在Acrobat Reader中进行打印操作(选择一台打印机) (你现在在dotNet编码之外)


您可以通过打开Acrobat Reader来选择其他默认打印机,并在actual working printer上打印一个空白页面。这应该取消选择你的​​FoxIt的东西,而不是实际的打印机..

答案 1 :(得分:2)

要使用PDF打印大量VB.Net个文档,您可以使用LVBPrint并通过command line运行它:

http://www.lvbprint.de/html/gsbatchprint1.html

例如:

C:\temp\gsbatchprint64\gsbatchprintc.exe -P \\server\printer -N A3 -O Port -F C:\temp\gsbatchprint64\Test*.pdf -I Tray3

我在我的应用程序中使用以下函数:

    ' print a pdf with lvbrint
    Private Function UseLvbPrint(ByVal oPrinter As tb_Printer, fileName As String, portrait As Boolean, sTray As String) As String

        Dim lvbArguments As String
        Dim lvbProcessInfo As ProcessStartInfo
        Dim lvbProcess As Process

        Try

            Dim sPrinterName As String

                If portrait Then
                    lvbArguments = String.Format(" -P ""{0}"" -O Port -N A4 -F ""{1}"" -I ""{2}"" ", sPrinterName, fileName, sTray)
                Else
                    lvbArguments = String.Format(" -P ""{0}"" -O Land -N A4 -F ""{1}"" -I ""{2}"" ", sPrinterName, fileName, sTray)
                End If

            lvbProcessInfo = New ProcessStartInfo()
            lvbProcessInfo.WindowStyle = ProcessWindowStyle.Hidden

            ' location of gsbatchprintc.exe
            lvbProcessInfo.FileName = LvbLocation 
            lvbProcessInfo.Arguments = lvbArguments

            lvbProcessInfo.UseShellExecute = False

            lvbProcessInfo.RedirectStandardOutput = True
            lvbProcessInfo.RedirectStandardError = True


            lvbProcessInfo.CreateNoWindow = False

            lvbProcess = Process.Start(lvbProcessInfo)

            '
            ' Read in all the text from the process with the StreamReader.
            '
            Using reader As StreamReader = lvbProcess.StandardOutput
                Dim result As String = reader.ReadToEnd()
                WriteLog(result)
            End Using

            Using readerErr As StreamReader = lvbProcess.StandardError
                Dim resultErr As String = readerErr.ReadToEnd()
                If resultErr.Trim() > "" Then
                    WriteLog(resultErr)

                    lvbProcess.Close()
                    Return resultErr
                End If
            End Using

            If lvbProcess.HasExited = False Then
                lvbProcess.WaitForExit(3000)
            End If

            lvbProcess.Close()

            Return ""

        Catch ex As Exception
            Return ex.Message 
        End Try
    End Function

我不鼓励使用AcrRd32.exe,因为它不适用于大量打印。

答案 2 :(得分:1)

我使用此代码在VB NET上打印我的PDF文件:

    Dim PrintPDF As New ProcessStartInfo
    PrintPDF.UseShellExecute = True
    PrintPDF.Verb = "print"
    PrintPDF.WindowStyle = ProcessWindowStyle.Hidden
    PrintPDF.FileName = dirName & fileName 'fileName is a string parameter
    Process.Start(PrintPDF)

当您执行此操作时,进程将保持打开状态,用户必须手动关闭Adobe窗口阅读器窗口。我想避免用户的互动,只是希望他们获取他们的文件。所以,我添加了一些代码行来杀死进程:

    Private Sub killProcess(ByVal processName As String)
    Dim procesos As Process()
    procesos = Process.GetProcessesByName(processName) 'I used "AcroRd32" as parameter

        If procesos.Length > 0 Then
            For i = procesos.Length - 1 To 0 Step -1
                procesos(i).Kill()
            Next
        End If

 End Sub

如果您在打印方法之后立即使用kill process方法,则不会打印文档(我想这是因为进程在发送到打印机之前被终止)。所以,在这两种方法之间,我添加了这一行:

   Threading.Thread.Sleep(10000) ' 10000 is the milisecs after the next code line is executed

有了这个,我的代码就像我想要的那样工作。希望它能帮到你!

答案 3 :(得分:0)

此代码可帮助您在特定打印机中进行打印。

样本使用ProcessStartInfo和特定打印机打印文件,您可以更改要在此过程中使用的打印机。

如果10秒后打印过程没有完成,我们就会终止打印过程。

'Declare a printerSettings
Dim defaultPrinterSetting As System.Drawing.Printing.PrinterSettings = Nothing


Private Sub cmdPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdPrint.Click

    Try

        dim fileName As String = "C:\534679.pdf"


        'Get de the default printer in the system
        defaultPrinterSetting = DocumentPrinter.GetDefaultPrinterSetting


        'uncomment if you want to change the default printer before print
        'DocumentPrinter.ChangePrinterSettings(defaultPrinterSetting)


        'print your file 
         If PrintFile(fileName, defaultPrinterSetting) then
             msgbox ("your print file success message")
         else
             msgbox ("your print file failed message")

         end if

    Catch ex As Exception
        mssbox(ex.Message.toString)
    End Try

End Sub


Public NotInheritable Class DocumentPrinter

    Shared Sub New()

    End Sub

    Public Shared Function PrintFile(ByVal fileName As String, printerSetting As System.Drawing.Printing.PrinterSettings) As Boolean

        Dim printProcess As System.Diagnostics.Process = Nothing
        Dim printed As Boolean = False

        Try

            If PrinterSetting IsNot Nothing Then


                Dim startInfo As New ProcessStartInfo()

                startInfo.Verb = "Print"
                startInfo.Arguments = defaultPrinterSetting.PrinterName     ' <----printer to use---- 
                startInfo.FileName = fileName 
                startInfo.UseShellExecute = True
                startInfo.CreateNoWindow = True
                startInfo.WindowStyle = ProcessWindowStyle.Hidden

                Using print As System.Diagnostics.Process = Process.Start(startInfo)

                   'Close the application after X milliseconds with WaitForExit(X)   

                    print.WaitForExit(10000)

                    If print.HasExited = False Then

                        If print.CloseMainWindow() Then
                            printed = True
                        Else
                            printed = True
                        End If

                    Else
                        printed = True

                    End If

                    print.Close()

                End Using


        Else
            Throw New Exception("Printers not found in the system...")
        End If


        Catch ex As Exception
            Throw
        End Try

        Return printed

    End Function


    ''' <summary>
    ''' Change the default printer using a print dialog Box
    ''' </summary>
    ''' <param name="defaultPrinterSetting"></param>
    ''' <remarks></remarks>
    Public Shared Sub ChangePrinterSettings(ByRef defaultPrinterSetting As System.Drawing.Printing.PrinterSettings)

        Dim printDialogBox As New PrintDialog

        If printDialogBox.ShowDialog = Windows.Forms.DialogResult.OK Then

            If printDialogBox.PrinterSettings.IsValid Then
                defaultPrinterSetting = printDialogBox.PrinterSettings
            End If

        End If

    End Sub



    ''' <summary>
    ''' Get the default printer settings in the system
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetDefaultPrinterSetting() As System.Drawing.Printing.PrinterSettings

        Dim defaultPrinterSetting As System.Drawing.Printing.PrinterSettings = Nothing

        For Each printer As String In System.Drawing.Printing.PrinterSettings.InstalledPrinters


            defaultPrinterSetting = New System.Drawing.Printing.PrinterSettings
            defaultPrinterSetting.PrinterName = printer

            If defaultPrinterSetting.IsDefaultPrinter Then
                Return defaultPrinterSetting
            End If

        Next

        Return defaultPrinterSetting

    End Function

End Class