Imprimir um documento PDF externo em VB.net
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:
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?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..
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!
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.
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