Imprimir um documento PDF externo em VB.net

Sei que esta pergunta já foi feita antes, mas a minha situação é um pouco complicada.

basicamente, estou a tentar imprimir um ficheiro PDF que criei usando um formulário anterior do Windows. Eu posso encontrar o arquivo sem problema, e eu usei o seguinte código que eu encontrei nos fóruns de ajuda do 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)

até agora tudo bem, mas toda vez que eu pressiono o botão para executar este código, ele continua me pedindo para salvá-lo como um arquivo PDF em vez disso, como mostrado abaixo:

enter image description here

Eu também tentei. adicionando um PrintDialog ao formulário do Windows, fazendo com que ele apareça, e eu posso selecionar a impressora que eu quero usar de lá, mas mesmo depois de selecionar a impressora, ele ainda me pede para imprimir para o documento PDF em vez disso.

O que estou a fazer de errado?

Author: Wakka02, 2014-11-17

4 answers

Primeiro, para poder seleccionar uma impressora, terá de usar um PrintDialog e PrintDocument para enviar gráficos para imprimir para a impressora seleccionada.

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
É o que estou a fazer, já que normalmente tenho objectos personalizados para imprimir.

Mas para imprimir arquivos PDF, você deve entender que PDF significa absolutamente nada para dotNet. Ao contrário de imagens comuns como Bitmaps (.BMP) ou Ping imagens (.png) a dotNet não parece ter nenhum analisador / descodificador incorporado para ler, exibir e imprimir arquivos PDF.

Por isso, deve usar uma aplicação , thrid party library ou a sua própria custom PDF parser/layout generator para poder enviar Páginas para imprimir para a sua impressora.

É por isso que não pode lançar um processo escondido (não visível) do leitor Acrobat com o comando "Imprimir". Você não será capaz de selecionar uma impressora, mas vai direto para o padrão em vez disso !

Pode, no entanto, lançar o Acrobat Reader process just to open the file, and do the printing manipulations (select a printer) inside Acrobat Reader (you're outside dotNet coding now)

A workaround for your may aslo to select another default printer by opening Acrobat Reader, and print one blank page on an actual working printer. Isto deve deseleccionar a tua coisa FoxIt a favor de uma impressora a sério..

 2
Author: Karl Stephen, 2014-11-17 11:59:56

Usei este código para imprimir os meus ficheiros PDF na vb NET:

    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)

Quando fizer isto, o processo permanece aberto com uma janela de leitura adobe que os utilizadores têm de fechar manualmente. Eu queria evitar a interação do Usuário, só queria que eles pegassem seus documentos. Então, eu adicionei algumas linhas de código para matar o processo:

    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

Se colocar o método kill process logo a seguir ao método de impressão, não conseguirá imprimir o seu documento (penso que isto se deve ao facto de o processo ser morto antes de ser enviado para a impressora). Então, entre estes dois métodos, adicionei esta linha:

   Threading.Thread.Sleep(10000) ' 10000 is the milisecs after the next code line is executed
E com isto o meu código funcionou como eu queria. Espero que te ajude!
 1
Author: Brenda Montiel, 2015-11-11 22:52:09

Para imprimir documentos maciços PDF com VB.Net pode usar LVBPrint e executá-los através command line:

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

Por Exemplo:

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

Uso a seguinte função na minha aplicação:

    ' 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
Desencoraja-me a usar AcrRd32.exe porque não funciona com grandes impressões.
 1
Author: depoip, 2017-09-18 08:41:28

Este código ajudá-lo-á a imprimir numa impressora específica.

A amostra imprime um ficheiro usando um ProcessStartInfo e uma impressora específica pode alterar a impressora a usar no processo.

Se o processo de impressão não estiver terminado após 10 segundos, matamos o processo de impressão.

'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
 0
Author: Harval, 2014-11-17 15:54:20