【问题标题】:Printing to a pdf printer programmatically以编程方式打印到 pdf 打印机
【发布时间】:2010-09-14 20:57:30
【问题描述】:

我正在尝试在 Visual Basic 2008 中以编程方式将现有文件打印为 PDF。

我们目前的相关资产是: Visual Studio 2008 专业版 Adobe Acrobat Professional 8.0

我曾想过获得一个像 ITextSharp 这样的 sdk,但对于我正在尝试做的事情来说,这似乎有点矫枉过正,尤其是因为我们拥有完整版的 Adob​​e。

是否有一段相对简单的代码可以打印到 PDF 打印机(当然也可以指定它打印到特定位置)还是需要使用另一个库才能打印到 pdf?


我想将以前创建的文档打印为 pdf 文件。在这种情况下,它是一个 .snp 文件,我想将其制作成 .pdf 文件,但我认为任何文件类型的逻辑都是相同的。


我刚刚尝试了上面的 shell 执行,它不会按照我想要的方式执行。因为它提示我要打印的位置,但仍然没有打印到我想要​​的位置(多个位置),这对于我们创建许多相同命名的 PDF 文件(在 PDF 中具有不同的数据并放置在对应的客户端文件夹)


当前进程是:

  • 转到 \\report server\client1
  • 手动创建文件夹中所有snp文档的pdf文件
  • 将 pdf 复制到 \\website reports\client1
  • 然后对所有 100 多个客户重复此操作大约需要两个小时才能完成和验证

我知道这可以做得更好,但我才来这里三个月,还有其他更紧迫的紧迫问题。我也没想到看起来如此微不足道的东西却如此难以编码。

【问题讨论】:

    标签: vb.net pdf


    【解决方案1】:

    与其他答案类似,但要简单得多。我终于把它缩减为 4 行代码,没有外部库(尽管您必须安装 Adob​​e Acrobat 并将其配置为 PDF 的默认值)。

        Dim psi As New ProcessStartInfo
        psi.FileName = "C:\Users\User\file_to_print.pdf"
        psi.Verb = "print"
        Process.Start(psi)
    

    这将打开文件,使用默认设置打印,然后关闭。

    改编自from this C# answer

    【讨论】:

      【解决方案2】:
      Imports System.Drawing.Printing
      Imports System.Reflection
      Imports System.Runtime.InteropServices
      Public Class Form1
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
          Dim pkInstalledPrinters As String
      
          ' Find all printers installed
          For Each pkInstalledPrinters In _
              PrinterSettings.InstalledPrinters
              printList.Items.Add(pkInstalledPrinters)
          Next pkInstalledPrinters
      
          ' Set the combo to the first printer in the list
          If printList.Items.Count > 0 Then
              printList.SelectedItem = 0
          End If
          End Sub
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
          Try
      
              Dim pathToExecutable As String = "AcroRd32.exe"
              Dim sReport = " " 'pdf file that you want to print
              'Dim SPrinter = "HP9F77AW (HP Officejet 7610 series)" 'Name Of printer
              Dim SPrinter As String
              SPrinter = printList.SelectedItem
              'MessageBox.Show(SPrinter)
              Dim starter As New ProcessStartInfo(pathToExecutable, "/t """ + sReport + """ """ + SPrinter + """")
              Dim Process As New Process()
              Process.StartInfo = starter
              Process.Start()
              Process.WaitForExit(10000)
              Process.Kill()
              Process.Close()
          Catch ex As Exception
              MessageBox.Show(ex.Message) 'just in case if something goes wrong then we can suppress the programm and investigate
          End Try
      End Sub
      End Class
      

      【讨论】:

      • 上面的这段代码直接打印到选定的打印机上,我决定发布这段代码以防万一有人需要它......我花了很长时间才弄清楚这个解决方案......
      【解决方案3】:

      我也有同样的挑战。我所做的解决方案是购买一个名为 PDFTron 的组件。它有一个 API 可以将 pdf 文档从无人值守的服务发送到打印机。 我在我的博客中发布了一些关于此的信息。看看吧!

      How to print a PDF file programmatically???

      【讨论】:

      • 感谢您告诉我。我去看看。
      • 嘿“briddums”,我刚刚更新了链接。请看一下,如果有任何问题,请告诉我。谢谢!罗伯。
      【解决方案4】:

      我在 C# ASP.NET 应用程序中遇到了类似的问题。我的解决方案是在命令行使用一些生成的代码启动 LaTeX 编译器。这不是一个简单的解决方案,但它会生成一些非常漂亮的 .pdf。

      【讨论】:

        【解决方案5】:

        这里最重要的一点是 PDF 很难。如果您可以采取任何措施避免直接创建或编辑 PDF 文档,我强烈建议您这样做。听起来您真正想要的是批量 SNP 到 PDF 转换器。您可以使用现成的产品来完成此操作,甚至根本不需要打开 Visual Studio。有人提到了 Adob​​e Distiller Server——检查你的 Acrobat 文档,我知道它带有基本的 Distiller,你可以设置 Distiller 以类似的模式运行,它会监视目录 A 并吐出任何文件的 PDF 版本显示在目录 B 中。

        另一种选择:由于您使用的是 Access 快照,最好编写一个 VBA 脚本,该脚本遍历目录中的所有 SNP 并将它们打印到安装的 PDF 打印机。

        ETA:如果您需要指定 PDF 打印机的输出,那可能会更难。我建议将 PDF 蒸馏器配置为输出到临时目录,这样您就可以打印一个,移动结果,然后打印另一个,等等。

        【讨论】:

        • 使用 PDF 打印机的唯一缺点是您必须指定一个静态路径来打印文件。这成为处理大批量流程的问题。
        【解决方案6】:

        这就是我在 VBScript 中的做法。可能对您不是很有用,但可能会让您入门。您需要有一个 PDF maker (adobe acrobat) 作为名为“Adobe PDF”的打印机。

        'PDF_WILDCARD = "*.pdf"
        'PrnName = "Adobe PDF"
        Sub PrintToPDF(ReportName As String, TempPath As String, _
                       OutputName As String, OutputDir As String, _
                       Optional RPTOrientation As Integer = 1)
        
          Dim rpt As Report
          Dim NewFileName As String, TempFileName As String
        
          '--- Printer Set Up ---
          DoCmd.OpenReport ReportName, View:=acViewPreview, WindowMode:=acHidden
          Set rpt = Reports(ReportName)
          Set rpt.Printer = Application.Printers(PrnName)
        
          'Set up orientation
          If RPTOrientation = 1 Then
            rpt.Printer.Orientation = acPRORPortrait
          Else
            rpt.Printer.Orientation = acPRORLandscape
          End If
        
          '--- Print ---
          'Print (open) and close the actual report without saving changes
          DoCmd.OpenReport ReportName, View:=acViewNormal, WindowMode:=acHidden
        
          ' Wait until file is fully created
          Call waitForFile(TempPath, ReportName & PDF_EXT)
        
          'DoCmd.Close acReport, ReportName, acSaveNo
          DoCmd.Close acReport, ReportName
        
          TempFileName = TempPath & ReportName & PDF_EXT 'default pdf file name
          NewFileName = OutputDir & OutputName & PDF_EXT 'new file name
        
          'Trap errors caused by COM interface
          On Error GoTo Err_File
          FileCopy TempFileName, NewFileName
        
          'Delete all PDFs in the TempPath
          '(which is why you should assign it to a pdf directory)
          On Error GoTo Err_File
          Kill TempPath & PDF_WILDCARD
        
        Exit_pdfTest:
          Set rpt = Nothing
          Exit Sub
        
        Err_File:    ' Error-handling routine while copying file
          Select Case Err.Number    ' Evaluate error number.
              Case 53, 70   ' "Permission denied" and "File Not Found" msgs
                  ' Wait 3 seconds.
                  Debug.Print "Error " & Err.Number & ": " & Err.Description & vbCr & "Please wait a few seconds and click OK", vbInformation, "Copy File Command"
                  Call sleep(2, False)
                  Resume
              Case Else
                  MsgBox Err.Number & ": " & Err.Description
                  Resume Exit_pdfTest
          End Select
        
          Resume
        
        End Sub
        
        
        
        Sub waitForFile(ByVal pathName As String, ByVal tempfile As String)
            With Application.FileSearch
                .NewSearch
                .LookIn = pathName
                .SearchSubFolders = True
                .filename = tempfile
                .MatchTextExactly = True
                '.FileType = msoFileTypeAllFiles
            End With
            Do While True
               With Application.FileSearch
                   If .Execute() > 0 Then
                       Exit Do
                   End If
               End With
            Loop
        End Sub
        
        
        
        Public Sub sleep(seconds As Single, EventEnable As Boolean)
            On Error GoTo errSleep
            Dim oldTimer As Single
        
            oldTimer = Timer
            Do While (Timer - oldTimer) < seconds
               If EventEnable Then DoEvents
            Loop
        
        errSleep:
               Err.Clear
        End Sub
        

        【讨论】:

          【解决方案7】:

          您要做的是找到一个好的免费 PDF 打印机驱动程序。这些作为打印机安装,但不是打印到物理设备,而是将打印机命令呈现为 PDF。然后,您可以按照上述方式执行 ShellExecute,或者使用内置的 .net PrintDocument,按名称引用 PDF“打印机”。我很快找到了一对free ones,包括来自PrimoBullZip (freedom limited to 10 users) 的产品。

          看起来 SNP 文件是 Microsoft Access 快照。您将不得不寻找 Access 或 Snapshot Viewer 的命令行界面,以便您指定打印机目标。

          我还看到 SnapshotViewer 下载中包含一个 ActiveX 控件。你可以尝试在你的程序中使用它来加载 snp 文件,然后告诉它在哪里打印它,如果它支持该功能。

          【讨论】:

            【解决方案8】:

            如果您尝试手动生成 PDF(使用 SDK 或 PDF 打印机驱动程序),这并不容易。 PDF 格式参考可从 Adob​​e 获得。

            问题在于该文件是 ASCII 和表的混合,这些表在文件中具有二进制偏移量以引用对象。这是一种有趣的格式,并且非常可扩展,但是很难编写一个简单的文件。

            如果你需要,它是可行的。我查看了 Adob​​e PDF 参考中的示例,将它们手动输入并进行了修改,直到我可以让它们按照我的需要工作。如果您经常这样做,那可能是值得的,否则请查看 SDK。

            【讨论】:

              【解决方案9】:

              PDFforge 提供 PDFCreator。它将从任何能够打印的程序(甚至是现有程序)创建 PDF。请注意,它基于 GhostScript,因此可能不适合您的 Acrobat 许可证。

              你看过Adobe Distiller Server 吗?您可以使用任何打印机驱动程序生成 PostScript 文件并将其翻译成 PDF。 (其实PDFCreator也做了类似的事情。)

              【讨论】:

                【解决方案10】:

                尝试使用带有 Print Verb 的 ShellExecute。

                这是我在 Google 上找到的博客。

                http://www.vbforums.com/showthread.php?t=508684

                【讨论】:

                  猜你喜欢
                  • 2012-12-19
                  • 1970-01-01
                  • 2011-02-22
                  • 1970-01-01
                  • 2013-04-29
                  • 2011-07-24
                  • 1970-01-01
                  • 2014-05-07
                  • 1970-01-01
                  相关资源
                  最近更新 更多