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

能否通过端口与IP地址,使用e.Graphics.DrawString方法直连打印?

当然可以!你完全可以沿用现有的e.Graphics.DrawString绘图逻辑,直接把输出通过IP和端口发送到网络打印机,不用先保存文件,也不用碰PCL语言。下面是具体实现思路和代码:

核心思路

PrintDocument结合GDI+生成的是**EMF(增强元文件)**格式的打印数据,大多数现代网络打印机支持直接接收这种格式(通过Raw打印协议,默认端口9100)。我们只需要捕获这个EMF数据,然后通过TCP连接直接发送到打印机的IP和端口即可。

步骤1:捕获PrintDocument的打印数据

我们可以自定义一个PrintController,把PrintDocument的输出重定向到内存流,而不是发送到系统打印队列。这样就能在内存中获取到完整的打印数据:

public class MemoryStreamPrintController : StandardPrintController
{
    private MemoryStream _printStream;

    public MemoryStream PrintStream => _printStream;

    protected override void OnStartPrint(PrintDocument document, PrintEventArgs e)
    {
        _printStream = new MemoryStream();
        base.OnStartPrint(document, e);
    }

    protected override Graphics OnStartPage(PrintDocument document, PrintPageEventArgs e)
    {
        // 将绘图内容写入内存流的Metafile
        return Graphics.FromImage(new Metafile(_printStream, e.PageSettings.PrintableArea));
    }

    protected override void OnEndPrint(PrintDocument document, PrintEventArgs e)
    {
        base.OnEndPrint(document, e);
        _printStream.Position = 0; // 将流指针重置到起始位置,方便后续发送
    }
}

步骤2:通过TCP发送数据到网络打印机

拿到内存中的打印数据后,建立TCP连接到打印机的IP和默认Raw端口(9100),把数据发送过去即可:

public static void SendPrintDataToNetworkPrinter(string printerIp, int port, PrintDocument printDoc)
{
    // 使用自定义控制器捕获打印数据
    var memoryController = new MemoryStreamPrintController();
    printDoc.PrintController = memoryController;

    // 执行"打印"(实际是把内容写入内存流)
    printDoc.Print();

    // 建立TCP连接并发送数据
    using (var tcpClient = new TcpClient())
    {
        tcpClient.Connect(printerIp, port);
        using (var networkStream = tcpClient.GetStream())
        {
            memoryController.PrintStream.CopyTo(networkStream);
            networkStream.Flush();
        }
    }
}

调用示例(沿用你的原有绘图代码)

// 创建PrintDocument实例
var packingSlipDoc = new PrintDocument();
packingSlipDoc.PrintPage += (sender, e) =>
{
    // 这里完全保留你原来的绘图逻辑
    var umFont = new Font("Arial", 12);
    var brush = Brushes.Black;
    float defaultX = 10f;
    float headerBodyY = 10f;
    
    e.Graphics.DrawString("Packing Slip", umFont, brush, defaultX, headerBodyY);
    e.Graphics.DrawString("ORDER NO", umFont, brush, defaultX + 727, headerBodyY);
};

// 发送到IP为192.168.1.100、端口9100的打印机
SendPrintDataToNetworkPrinter("192.168.1.100", 9100, packingSlipDoc);

关键注意事项

  • 端口确认:绝大多数网络打印机默认使用9100端口作为Raw打印端口,如果你的打印机用了其他端口,需要先确认(可以在打印机管理界面查看)。
  • 打印机兼容性:不是所有打印机都支持直接接收EMF格式。如果测试后无法打印,可能你的打印机只支持PostScript或XPS,这时候可以考虑把PrintDocument的输出转换为XPS(内存中处理,不用保存文件)再发送,或者检查打印机是否有EMF支持的配置选项。
  • 字体与权限:确保打印机支持你使用的字体(避免乱码),同时程序需要有建立TCP连接的权限(比如防火墙允许出站连接到9100端口)。

内容的提问来源于stack exchange,提问作者accidentalprogrammer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:42:33