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

时间:2008-10-02 16:55:22

标签: vb.net pdf

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

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

我想过像ITextSharp那样获得一个sdk,但是因为我们有完整版的Adobe,所以我觉得这样做有点过分。

是否有相对简单的代码要打印到PDF打印机(当然还要将其分配到特定位置打印),还是需要使用其他库来打印到pdf?


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


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


目前的流程是:

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

我知道这可以做得更好,但我只在这里待了三个月,还有其他紧迫的问题更直接。我也没想到看起来很难做到难以编码的东西。

11 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

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

How to print a PDF file programmatically???

答案 5 :(得分:0)

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

以下是我在Google上发现的一个博客。

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

答案 6 :(得分:0)

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

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

如果你需要,这是可行的。我查看了Adobe PDF参考中的示例,手工输入并进行了处理,直到我可以让它们按需要工作。如果你要做很多事情,那么它可能是值得的,否则看一下SDK。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

最好的Java库是iText,但从过去一年左右开始观看邮件列表这根本不是一项简单的任务

答案 9 :(得分:0)

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

答案 10 :(得分:0)

与其他答案类似,但更为简单。我最终将其归结为4行代码,没有外部库(尽管您必须安装Adobe 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