以编程方式打印到pdf打印机

时间:2020-03-06 15:02:15  来源:igfitidea点击:

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

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

我曾考虑过要使用像ITextSharp这样的sdk,但是对于我正在尝试做的事情似乎有些过头了,尤其是因为我们拥有完整版的Adobe。

是否有一些相对简单的代码可以打印到PDF打印机(当然还要将其分配给特定位置打印),还是需要使用另一个库才能打印到pdf?

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

我只是尝试了上面的shell执行,它不会按照我想要的方式执行。因为它会提示我要打印的位置,但仍然不打印我要打印的位置(多个位置),这一点至关重要,因为我们创建了很多相同名称的PDF文件(PDF中包含不同的数据,并放置在相应的客户端文件夹)

当前过程是:

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

我知道可以做得更好,但我来这里只有三个月,还有其他紧迫的问题要立即解决。我也没想到看起来如此琐碎的东西很难编写。

解决方案

我们要做的是找到一个不错的免费PDF打印机驱动程序。它们是作为打印机安装的,但不是将其打印到物理设备,而是将打印机命令呈现为PDF。然后,我们可以如上所述执行ShellExecute,也可以使用内置的.net PrintDocument,通过名称引用PDF"打印机"。我很快找到了几个免费的产品,包括Primo和BullZip的产品(自由限制为10个用户)。

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

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

尝试将ShellExecute与Print Verb一起使用。

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

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

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

我们是否看过Adobe Distiller Server?我们可以使用任何打印机驱动程序生成PostScript文件,并将其转换为PDF。 (实际上,PDFCreator做类似的事情。)

如果我们尝试手动生成PDF(使用SDK和SDK或者PDF打印机驱动程序),则并非易事。可从Adobe获得PDF格式参考。

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

如果需要的话,这是可行的。我查看了Adobe PDF参考资料中的示例,然后手动键入它们并进行处理,直到我可以根据需要使它们工作为止。如果我们将大量执行此操作,那可能是值得的,否则请查看SDK。

这就是我在VBScript中所做的。可能对我们不是很有用,但可能会让我们入门。我们需要具有PDF制造商(adobe acrobat)作为名为" Adob​​e 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

这里最大的要点是PDF很难。如果有什么可以避免直接创建或者编辑PDF文档的方法,强烈建议我们这样做。听起来我们真正想要的是批处理SNP至PDF转换器。我们可能可以使用现成的产品来执行此操作,甚至根本不需要打开Visual Studio。有人提到过Adobe Distiller Server-检查Acrobat文档,我知道它是基本的Distiller附带的,我们也许可以将Distiller设置为以类似的模式运行,在该模式下,它可以监视目录A并吐出所有文件的PDF版本显示在目录B中。

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

预计到达时间:如果我们需要指定PDF打印机的输出,则可能会更难。我建议我们将PDF分配器配置为输出到临时目录,以便我们可以打印其中一个,移动结果,然后打印另一个,依此类推。

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

最好的Java库是iText,但是从去年开始观看邮件列表并不是一件容易的事

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

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