You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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中通过命令行调用:

  1. 下载对应系统版本的GhostPCL工具包,提取核心执行文件(如gpcl6win64.exe)到程序目录
  2. 编写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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 02:24:10