2014-11-17 2 views
2

Я знаю, что этот вопрос задавали раньше, но моя ситуация немного завораживает.Печать внешнего документа PDF в VB.net

В принципе, я пытаюсь распечатать файл PDF, который я сгенерировал, используя предыдущую форму Windows. Я могу найти файл не проблема, и я использовал следующий код, который я нашел от справочных форумах 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-документе.

Что я делаю неправильно?

+2

Это происходит, потому что ваш принтер по умолчанию - это принтер PDF Foxit Reader, который ничего не печатает, а создает файл PDF. Попробуйте установить по умолчанию настоящий принтер. – Steve

ответ

2

Во-первых, чтобы иметь возможность выбрать принтер, вы должны будете использовать PrintDialog и PrintDocument отправить графики для печати на выбранном принтере.

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. В отличие от обычных изображений, таких как растровые изображения (.bmp) или изображения Ping (.png), dotNet не имеет встроенного анализатора/декодера для чтения, отображения и печати PDF-файлов.

Таким образом, вы должны использовать третьему лицу приложение, thrid партии библиотека или собственный пользовательских PDF парсер генератор/макет для того, чтобы иметь возможность отправлять страницы для печати на принтере.

Вот почему вы не можете запустить скрытый (не видимый) процесс Acrobat Reader с помощью команды «print». Вы не сможете выбрать принтер, но будете перенаправлять его по умолчанию!

Однако вы можете запустить процесс Acrobat Reader просто открыть файл и сделать печатные манипуляции (выбрать принтер) в Acrobat Reader (вы вне Dotnet кодирования сейчас)


A обходной путь для вашего может также выбрать другой принтер по умолчанию, открыв Acrobat Reader и напечатать одну пустую страницу на actual working printer. Это должно отменить выбор вашей FoxIt в пользу фактического принтера.

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 
+0

Код его текущей формы не работает, к сожалению. –

1

Я использовал этот код, чтобы напечатать мои PDF файлы на 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) 

Когда вы сделаете это, процесс остается открытым с окном читателя самана, что пользователи должны закрыть вручную. Я хотел избежать взаимодействия с пользователем, просто хочу, чтобы они получили свои документы. Таким образом, я добавил несколько строк кода, чтобы убить процесс:

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 

Если поставить метод обработки убить сразу после метода печати вы не получите ваш документ напечатанной (я предполагаю, что это происходит потому, что процесс был убит перед ним отправляется на принтер). Итак, между этими двумя методами я добавил эту строку:

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

И с этим мой код работал так, как я хотел. Надеюсь, это поможет вам!

1

Для печати массивных 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, как он не работает с массивными тиражами.

Смежные вопросы