代码实现热敏打印:打印长度被截断至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); } }
代码说明
- 自定义纸张:在构造函数中创建适配8cm宽的自定义纸张,高度设为1000mm(足够容纳长收据),同时取消打印边距。
- 分页控制:通过
MeasureString计算单页可容纳的字符数,打印后更新起始索引,设置HasMorePages标记来触发后续页面打印。 - 资源管理:使用
using语句和重写Dispose方法释放字体资源,避免内存泄漏。
此外,需确保打印机驱动已设置为连续纸模式,部分热敏打印机需要在驱动中手动选择连续纸类型,才能实现持续走纸直到打印完成。
内容的提问来源于stack exchange,提问作者AzulShiva
相关产品推荐
相关产品推荐

