如何在VB.NET中将ASCII文件输出至虚拟PDF打印机
VB.NET中ASCII文件输出至虚拟PDF打印机的解决方案
问题背景
需要在VB.NET程序中将ASCII文件输出到虚拟PDF打印机,尝试使用「Microsoft Print to PDF」未成功;找到GhostPCL工具但不确定能否集成;已知DosPrinter试用版可生成与针式打印机一致的输出,确认存在可行方案,寻求最优实现方式。
测试资源
- 测试用ASCII文件
- 目标效果示例PDF(DosPrinter生成)
现有测试代码
Public Shared Function SendFileToPrinter(ByVal szPrinterName As String, ByVal szFileName As String) As Boolean ' Open the file. 'FileStream and BinaryReader are disposable objects. Hence you need to dispose of these objects Better if you declare them with a Using statement, so there's a very good chance they're disposed even when an exception is generated in the meanwhile. -- Disposing of disposable objects is not exactly optional. Using fs As New FileStream(szFileName, FileMode.Open) ' Create a BinaryReader on the file. Dim br As New BinaryReader(fs) ' Dim an array of bytes big enough to hold the file's contents. Dim bytes(fs.Length - 1) As Byte Dim bSuccess As Boolean = False ' Your unmanaged pointer. Dim pUnmanagedBytes As New IntPtr(0) Dim nLength As Integer nLength = Convert.ToInt32(fs.Length) ' Read the contents of the file into the array. bytes = br.ReadBytes(nLength) ' Allocate some unmanaged memory for those bytes. pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength) ' Copy the managed byte array into the unmanaged array. Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength) ' Send the unmanaged bytes to the printer. bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength) ' Free the unmanaged memory that you allocated earlier. Marshal.FreeCoTaskMem(pUnmanagedBytes) Return bSuccess End Using End Function Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim printer As String = "Microsoft Print to PDF" For i As Integer = 1 To 1 SendFileToPrinter(printer, "C:\vDos\#LPT1.asc") Next i Me.Close() End Sub
测试结果截图
- 「Microsoft Print to PDF」输出失败结果1
- 「Microsoft Print to PDF」输出失败结果2
- ASCII文件内容预览
- DosPrinter生成的目标PDF效果
- 当前错误输出的PDF效果
最优解决方案
方案1:GhostPCL工具集成(推荐)
GhostPCL原生支持处理ASCII/PCL格式内容并生成PDF,可在VB.NET中通过命令行调用:
- 下载对应系统版本的GhostPCL工具包,提取核心执行文件(如
gpcl6win64.exe)到程序目录 - 编写VB.NET调用代码:
Imports System.Diagnostics Imports System.IO Public Sub ConvertAsciiToPdf(inputFilePath As String, outputPdfPath As String) Dim ghostPclExePath As String = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "gpcl6win64.exe") Dim startInfo As New ProcessStartInfo With { .FileName = ghostPclExePath, .Arguments = $"-dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=""{outputPdfPath}"" ""{inputFilePath}""", .WindowStyle = ProcessWindowStyle.Hidden, .CreateNoWindow = True, .UseShellExecute = False } Using proc As Process = Process.Start(startInfo) proc.WaitForExit() ' 可根据ExitCode判断是否成功 If proc.ExitCode <> 0 Then Throw New Exception("GhostPCL转换失败") End If End Using End Sub
该方案能完美还原针式打印机的输出格式,无需额外处理文本渲染逻辑。
方案2:改进文本渲染打印方式
「Microsoft Print to PDF」不支持直接接收原始字节流,需通过PrintDocument渲染ASCII内容:
Imports System.Drawing.Printing Imports System.IO Public Sub PrintAsciiToPdf(inputFilePath As String, outputPdfPath As String) Dim originalDefaultPrinter As String = PrinterSettings.DefaultPrinterName Dim printDoc As New PrintDocument() Try ' 设置打印目标为Microsoft Print to PDF printDoc.PrinterSettings.PrinterName = "Microsoft Print to PDF" printDoc.PrinterSettings.PrintToFile = True printDoc.PrinterSettings.PrintFileName = outputPdfPath ' 绑定打印事件,渲染ASCII内容 AddHandler printDoc.PrintPage, Sub(sender, e) Dim asciiContent As String = File.ReadAllText(inputFilePath) ' 使用等宽字体模拟针式打印机效果 Dim printFont As New Font("Courier New", 10, FontStyle.Regular) ' 逐行渲染避免内容超出页面 Dim lines() As String = asciiContent.Split(vbCrLf) Dim yPos As Single = 20 ' 页面顶部偏移 Dim lineHeight As Single = printFont.GetHeight(e.Graphics) For Each line In lines If yPos + lineHeight > e.MarginBounds.Bottom Then e.HasMorePages = True Return End If e.Graphics.DrawString(line, printFont, Brushes.Black, 20, yPos) yPos += lineHeight Next e.HasMorePages = False End Sub printDoc.Print() Finally ' 恢复原默认打印机 PrinterSettings.DefaultPrinterName = originalDefaultPrinter printDoc.Dispose() End Try End Sub
注意:此方案适合纯文本格式的ASCII文件,复杂格式(如控制字符)可能无法精准还原。
方案3:第三方组件(DosPrinter授权版)
若DosPrinter试用版的输出完全符合需求,可购买授权版,其提供官方API直接在VB.NET中调用,集成更便捷,无需自行处理格式转换逻辑。
内容的提问来源于stack exchange,提问作者roy
相关产品推荐
相关产品推荐

