Flutter应用中如何实现热敏打印机长文本多行换行打印?
解决热敏打印长文本自动换行并对齐列的问题
问题分析
当前使用print_bluetooth_thermal和esc_pos_utils包打印订单时,Order列的长文本会被截断,无法自动换行并保持列对齐。需要实现长文本换行后,第一列仅在首行显示数量,后续行留空,同时维持两列的宽度比例。
解决方案
1. 编写文本分割函数
实现按单词分割的函数,避免截断单词,保证文本可读性:
List<String> splitTextToFit(String text, int maxChars) { List<String> lines = []; String currentLine = ''; for (String word in text.split(' ')) { // 检查当前行加新单词是否超过最大长度 int nextLength = currentLine.isEmpty ? word.length : currentLine.length + 1 + word.length; if (nextLength <= maxChars) { currentLine += currentLine.isEmpty ? word : ' $word'; } else { if (currentLine.isNotEmpty) { lines.add(currentLine); } // 处理单个单词过长的情况 if (word.length > maxChars) { for (int i = 0; i < word.length; i += maxChars) { int end = i + maxChars; lines.add(word.substring(i, end > word.length ? word.length : end)); } } else { currentLine = word; } } } if (currentLine.isNotEmpty) { lines.add(currentLine); } return lines; }
2. 调整打印逻辑
在生成打印指令时,先分割长文本,再循环生成每行内容:
final Generator ticket = Generator(paper, profile); List<int> bytes = []; String product = _cleanText(detail['product'].toString()); String amount = detail['amount'].toString(); // 计算Order列可容纳的最大字符数(适配不同纸型) int paperWidthPixels = paper.width; // 80mm纸为576,58mm纸为420 int availablePixels = (paperWidthPixels * 11 / 12).floor(); double charWidth = profile.fonts[FontType.a]!.width; int maxCharsPerLine = availablePixels ~/ charWidth; // 分割长文本为多行 List<String> productLines = splitTextToFit(product, maxCharsPerLine); // 循环生成每行打印指令 for (int i = 0; i < productLines.length; i++) { bytes += ticket.row([ PosColumn( text: i == 0 ? amount : '', width: 1, align: PosAlign.center, // 保持数量居中对齐 ), PosColumn( text: productLines[i], width: 11, ), ]); }
说明
- 字符数计算:通过纸宽像素和字体宽度自动计算最大可容纳字符数,适配58mm/80mm等不同纸型,比手动设置更准确。
- 文本分割:优先按单词分割避免截断,单个单词过长时强制拆分,确保所有内容都能打印。
- 打印对齐:首行显示数量,后续行第一列留空,维持两列宽度比例,实现预期的打印格式。
内容的提问来源于stack exchange,提问作者jholkin
相关产品推荐
相关产品推荐

