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

代码实现热敏打印:打印长度被截断至30cm问题求助

解决热敏打印机打印长度被截断的问题

你的问题根源在于PrintDocument默认使用标准纸张尺寸(比如A4),即便你设置了大的RectangleF,超过单页的内容也会被自动截断。而记事本、Word这类软件会自动适配热敏打印机的连续纸模式,处理长内容的分页逻辑。下面是具体修复方案:

核心修复要点

  • 自定义连续纸规格:给打印机指定热敏纸的实际宽度,高度设为足够大的值以适配长收据。
  • 手动处理文本分页:计算每页可容纳的文本量,分批次打印剩余内容,直到所有文本输出完成。

修改后的代码

private void print(string printString)
{
    using (PCPrint printer = new PCPrint())
    {
        printer.TextToPrint = printString;
        printer.Print();
    }
}

public class PCPrint : System.Drawing.Printing.PrintDocument
{
    private string _printText;
    private int _currentPrintIndex;
    private readonly Font _printFont = new Font("Verdana", 8);

    public string TextToPrint
    {
        get => _printText;
        set => _printText = value;
    }

    public PCPrint()
    {
        // 适配8cm宽的热敏纸,设置自定义纸张尺寸
        if (PrinterSettings.IsValid)
        {
            // 转换单位:1mm ≈ 3.937 hundredths of an inch(打印机API要求的单位)
            var customPaper = new PaperSize("Custom", MillimetersToHundredthsInch(80), MillimetersToHundredthsInch(1000));
            PrinterSettings.DefaultPageSettings.PaperSize = customPaper;
            DefaultPageSettings.Margins = new Margins(0, 0, 0, 0); // 取消边距,最大化打印区域
        }
    }

    private int MillimetersToHundredthsInch(int mm)
    {
        return (int)(mm * 3.937);
    }

    protected override void OnBeginPrint(PrintEventArgs e)
    {
        base.OnBeginPrint(e);
        _currentPrintIndex = 0; // 初始化打印起始位置
    }

    protected override void OnPrintPage(PrintPageEventArgs e)
    {
        base.OnPrintPage(e);

        var printAreaWidth = e.PageBounds.Width - e.MarginBounds.Left - e.MarginBounds.Right;
        var printAreaHeight = e.PageBounds.Height - e.MarginBounds.Top - e.MarginBounds.Bottom;
        float currentY = e.MarginBounds.Top;

        var stringFormat = new StringFormat(StringFormatFlags.LineLimit);
        int charsFitted, linesFilled;

        // 循环打印直到当前页填满或文本全部打印完成
        while (_currentPrintIndex < _printText.Length)
        {
            // 计算当前页能容纳的字符数量
            e.Graphics.MeasureString(
                _printText.Substring(_currentPrintIndex),
                _printFont,
                new SizeF(printAreaWidth, printAreaHeight),
                stringFormat,
                out charsFitted,
                out linesFilled
            );

            // 打印当前页的文本片段
            e.Graphics.DrawString(
                _printText.Substring(_currentPrintIndex, charsFitted),
                _printFont,
                Brushes.Black,
                e.MarginBounds.Left,
                currentY,
                stringFormat
            );

            // 更新已打印的字符索引
            _currentPrintIndex += charsFitted;

            // 判断是否需要继续打印下一页
            if (_currentPrintIndex < _printText.Length)
            {
                e.HasMorePages = true;
                return;
            }
            e.HasMorePages = false;
        }
    }

    protected override void Dispose(bool disposing)
    {
        _printFont.Dispose();
        base.Dispose(disposing);
    }
}

代码说明

  1. 自定义纸张:在构造函数中创建适配8cm宽的自定义纸张,高度设为1000mm(足够容纳长收据),同时取消打印边距。
  2. 分页控制:通过MeasureString计算单页可容纳的字符数,打印后更新起始索引,设置HasMorePages标记来触发后续页面打印。
  3. 资源管理:使用using语句和重写Dispose方法释放字体资源,避免内存泄漏。

此外,需确保打印机驱动已设置为连续纸模式,部分热敏打印机需要在驱动中手动选择连续纸类型,才能实现持续走纸直到打印完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 18:55:08