vb.net 以编程方式打印到 pdf 打印机
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/163420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printing to a pdf printer programmatically
提问by Sean
I am trying to print an existing file to PDF programmatically in Visual Basic 2008.
我正在尝试在 Visual Basic 2008 中以编程方式将现有文件打印为 PDF。
Our current relevant assets are: Visual Studio 2008 Professional Adobe Acrobat Professional 8.0
我们目前的相关资产有: Visual Studio 2008 Professional Adobe Acrobat Professional 8.0
I thought about getting a sdk like ITextSharp, but it seem like overkill for what I am trying to do especially since we have the full version of Adobe.
我想过获得像 ITextSharp 这样的 sdk,但对于我想要做的事情来说似乎有点过分,特别是因为我们拥有完整版的 Adobe。
Is there a relatively simple bit of code to print to a PDF printer (and of course assign it to print to a specific location) or will it require a the use of another library to print to pdf?
是否有相对简单的代码可以打印到 PDF 打印机(当然还可以将其分配到特定位置),还是需要使用另一个库来打印到 pdf?
I want to print a previosly created document to a pdf file. In this case it a .snp file that I want to make into a .pdf file, but I think the logic would be the same for any file type.
我想将以前创建的文档打印为 pdf 文件。在这种情况下,它是一个 .snp 文件,我想将其制作成 .pdf 文件,但我认为对于任何文件类型,逻辑都是相同的。
I just tried the above shell execute, and it will not perform the way I want it to. as it prompts me as to where I want to print and still does not print where I want it to (multiple locations), which is crucial as we create a lot of the same named PDF files (with different data within the PDF and placed in corresponding client folders)
我只是尝试了上面的 shell 执行,但它不会按照我想要的方式执行。因为它提示我要打印的位置,但仍然没有打印我想要的位置(多个位置),这很重要,因为我们创建了许多相同命名的 PDF 文件(在 PDF 中具有不同的数据并放置在对应的客户端文件夹)
The current process is:
目前的流程是:
- Go to \\report server\client1
- create pdf files of all the snp documents in the folder by hand
- copy the pdf to \\website reports\client1
- then repeat for all 100+ clients takes roughly two hours to complete and verify
- 转到\\报表服务器\客户端1
- 手动创建文件夹中所有snp文档的pdf文件
- 将 pdf 复制到 \\website reports\client1
- 然后对所有 100 多个客户重复大约需要两个小时才能完成和验证
I know this can be done better but I have only been here three months and there were other pressing concerns that were a lot more immediate. I also was not expecting something that looks this trivial to be that hard to code.
我知道这可以做得更好,但我才来这里三个月,还有其他更紧迫的问题。我也没想到看起来如此微不足道的东西很难编码。
采纳答案by Coderer
The big takeaway point here is that PDF IS HARD. If there is anything you can do to avoid creating or editing PDF documents directly, I strongly advise that you do so. It sounds like what you actually want is a batch SNP to PDF converter. You can probably do this with an off-the-shelf product, without even opening Visual Studio at all. Somebody mentioned Adobe Distiller Server -- check your docs for Acrobat, I know it comes with basic Distiller, and you may be able to set up Distiller to run in a similar mode, where it watches Directory A and spits out PDF versions of any files that show up in Directory B.
这里的重点是 PDF 很难。如果您可以采取任何措施避免直接创建或编辑 PDF 文档,我强烈建议您这样做。听起来您真正想要的是批量 SNP 到 PDF 转换器。您可能可以使用现成的产品来做到这一点,甚至根本不需要打开 Visual Studio。有人提到了 Adobe Distiller Server——检查你的 Acrobat 文档,我知道它带有基本的 Distiller,你可以设置 Distiller 以类似的模式运行,它监视目录 A 并吐出任何文件的 PDF 版本出现在目录 B 中。
An alternative: since you're working with Access snapshots, you might be better off writing a VBA script that iterates through all the SNPs in a directory and prints them to the installed PDF printer.
替代方法:由于您正在使用 Access 快照,因此最好编写一个 VBA 脚本,该脚本遍历目录中的所有 SNP 并将它们打印到已安装的 PDF 打印机。
ETA: if you need to specify the output of the PDF printer, that might be harder. I'd suggest having the PDF distiller configured to output to a temp directory, so you can print one, move the result, then print another, and so on.
ETA:如果您需要指定 PDF 打印机的输出,那可能会更难。我建议将 PDF 蒸馏器配置为输出到临时目录,这样您就可以打印一个,移动结果,然后打印另一个,依此类推。
回答by Joe Phillips
This is how I do it in VBScript. Might not be very useful for you but might get you started. You need to have a PDF maker (adobe acrobat) as a printer named "Adobe PDF".
这就是我在 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
回答by Chris Marasti-Georg
What you want to do is find a good free PDF Printer driver. These are installed as printers, but instead of printing to a physical device, render the printer commands as a PDF. Then, you can either ShellExecute as stated above, or use the built in .net PrintDocument, referring the the PDF "printer" by name. I found a couple free ones, including products from Primoand BullZip (freedom limited to 10 users)pretty quickly.
您想要做的是找到一个好的免费 PDF 打印机驱动程序。它们作为打印机安装,但不是打印到物理设备,而是将打印机命令呈现为 PDF。然后,您可以如上所述使用 ShellExecute,也可以使用内置的 .net PrintDocument,按名称引用 PDF“打印机”。我很快就找到了几个免费的,包括来自Primo和BullZip(自由限制为 10 个用户)的产品。
It looks like SNP files are Microsoft Access Snapshots. You will have to look for a command line interface to either Access or the Snapshot Viewer that will let you specify the printer destination.
看起来 SNP 文件是 Microsoft Access 快照。您必须寻找 Access 或 Snapshot Viewer 的命令行界面,以便您指定打印机目标。
I also saw that there is an ActiveX control included in the SnapshotViewer download. You could try using that in your program to load the snp file, and then tell it where to print it to, if it supports that functionality.
我还看到 SnapshotViewer 下载中包含一个 ActiveX 控件。您可以尝试在程序中使用它来加载 snp 文件,然后告诉它打印到哪里,如果它支持该功能。
回答by gimel
PDFforgeoffers PDFCreator. It will create PDFs from any program that is able to print, even existing programs. Note that it's based on GhostScript, so maybe not a good fit to your Acrobat license.
PDFforge提供 PDFCreator。它将从任何能够打印的程序创建 PDF,甚至是现有程序。请注意,它基于 GhostScript,因此可能不适合您的 Acrobat 许可证。
Have you looked into Adobe Distiller Server? You can generate PostScript files using any printer driver and have it translated into PDF. (Actually, PDFCreator does a similar thing.)
您是否研究过Adobe Distiller Server?您可以使用任何打印机驱动程序生成 PostScript 文件并将其翻译成 PDF。(实际上,PDFCreator 做了类似的事情。)
回答by Roberto
I had the same challenge. The solution I've made was buying a component called PDFTron. It has an API to send pdf documents to a printer from an unattended service. I posted some information in my blog about that. Take a look!
我遇到了同样的挑战。我所做的解决方案是购买一个名为 PDFTron 的组件。它有一个 API,可以将 pdf 文档从无人值守的服务发送到打印机。我在我的博客中发布了一些关于这方面的信息。看一看!
回答by Makhi Ngubane
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
回答by tim.baker
Similar to other answers, but much simpler. I finally got it down to 4 lines of code, no external libraries (although you must have Adobe Acrobat installed and configured as Default for PDF).
与其他答案类似,但要简单得多。我最终将其缩减为 4 行代码,没有外部库(尽管您必须安装 Adobe Acrobat 并将其配置为 PDF 的默认值)。
Dim psi As New ProcessStartInfo
psi.FileName = "C:\Users\User\file_to_print.pdf"
psi.Verb = "print"
Process.Start(psi)
This will open the file, print it with default settings and then close.
这将打开文件,使用默认设置打印它,然后关闭。
Adapted from this C# answer
回答by Dan Hewett
If you are trying to hand generated the PDF (with and SDK or a PDF printer driver) it's not very easy. The PDF format reference is available from Adobe.
如果您尝试手动生成 PDF(使用 SDK 或 PDF 打印机驱动程序),这并不容易。PDF 格式参考可从 Adobe 获得。
The problem is that the file is a mix of ASCII and tables that have binary offsets within the file to reference objects. It is an interesting format, and very extensible, but it is difficult to write a simple file.
问题是该文件是 ASCII 和表的混合,这些表在文件中具有用于引用对象的二进制偏移量。这是一种有趣的格式,并且具有很强的可扩展性,但是很难编写一个简单的文件。
It's doable if you need to. I looked at the examples in the Adobe PDF reference, hand typed them in and worked them over till I could get them to work as I needed. If you will be doing this a lot it might be worth it, otherwise look at an SDK.
如果需要,这是可行的。我查看了 Adobe PDF 参考中的示例,手动输入并修改它们,直到我可以让它们按照我的需要工作。如果您经常这样做,那可能是值得的,否则请查看 SDK。
回答by Ken
Try using ShellExecute with the Print Verb.
尝试将 ShellExecute 与 Print Verb 一起使用。
Here is a blog I found with Google.
这是我在 Google 上找到的博客。
回答by Wyatt
I encountered a similar problem in a C# ASP.NET app. My solution was to fire a LaTeX compiler at the command line with some generated code. It's not exactly a simple solution but it generates some really beautiful .pdfs.
我在 C# ASP.NET 应用程序中遇到了类似的问题。我的解决方案是在命令行中使用一些生成的代码启动 LaTeX 编译器。这不是一个简单的解决方案,但它生成了一些非常漂亮的 .pdf。