3

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

我们当前的相关资产有: Visual Studio 2008 Professional Adob​​e 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 多个客户重复此操作大约需要两个小时才能完成和验证

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

4

10 回答 10

3

这就是我在 VBScript 中的做法。可能对您不是很有用,但可能会让您入门。您需要一个 PDF 制作器 (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
于 2008-10-02T20:07:30.980 回答
3

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

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

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

于 2008-10-09T19:58:01.480 回答
1

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

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

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

于 2008-10-02T16:56:45.320 回答
1

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

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

于 2008-10-02T17:37:39.247 回答
1

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

如何以编程方式打印 PDF 文件???

于 2010-11-17T15:22:41.407 回答
0

尝试使用带有 Print Verb 的 ShellExecute。

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

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

于 2008-10-02T17:14:22.847 回答
0

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

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

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

于 2008-10-02T18:12:10.273 回答
0

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

于 2008-10-09T20:04:12.667 回答
-1
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
于 2016-02-10T08:22:17.107 回答
-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)

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

改编自这个 C# 答案

于 2017-06-26T14:27:39.973 回答