You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Delphi下3英寸POS打印机如何实现指定格式小票打印?

嘿,我刚好在Delphi里做过类似的POS小票打印需求,给你分享一下具体的实现思路和代码,完全贴合你要的格式!

核心思路

首先得抓住两个关键:3英寸纸张的宽度适配总价的右对齐格式化。POS小票打印机基本都支持等宽字体,我们可以利用这一点精准控制每行的内容布局,确保总价完美右对齐。

实现步骤与代码

1. 准备工作:定义常量与打印辅助函数

先定义对应3英寸纸张的字符宽度(一般48列左右,可根据你的打印机微调),还有填充用的短横线。然后写一个通用的打印商品项的函数,统一处理每一项的格式拼接。

const
  PRINT_WIDTH_CHARS = 48; // 3英寸纸张对应的标准字符宽度,可按需调整
  FILL_SEPARATOR = '-';

procedure PrintPOSItem(const ItemDesc: string; Qty: Integer; UnitName: string; UnitPrice, TotalPrice: Double);
var
  LeftSection, TotalText, FillText: string;
  LeftWidth, TotalWidth, FillLength: Integer;
begin
  // 第一步:打印商品描述行
  Printer.Canvas.TextOut(0, Printer.Canvas.PenPos.Y, ItemDesc);
  // 换行(下移一行的高度)
  Printer.Canvas.PenPos.Y := Printer.Canvas.PenPos.Y + Printer.Canvas.TextHeight('A');

  // 第二步:格式化左侧内容(数量+单位+单价)
  LeftSection := Format('%d %s X %.2f', [Qty, UnitName, UnitPrice]);
  // 格式化总价,自动添加千分位
  TotalText := FormatFloat('#,##0.00', TotalPrice);

  // 计算各部分的宽度,确保总价右对齐
  LeftWidth := Printer.Canvas.TextWidth(LeftSection);
  TotalWidth := Printer.Canvas.TextWidth(TotalText);
  // 计算需要填充的短横线长度,保证总宽度符合纸张限制
  FillLength := PRINT_WIDTH_CHARS - (LeftWidth + TotalWidth);
  if FillLength < 1 then FillLength := 1; // 至少保留一个分隔符

  // 生成填充用的短横线字符串
  FillText := StringOfChar(FILL_SEPARATOR, FillLength);

  // 拼接并打印第二行
  Printer.Canvas.TextOut(0, Printer.Canvas.PenPos.Y, LeftSection + FillText + TotalText);
  Printer.Canvas.PenPos.Y := Printer.Canvas.PenPos.Y + Printer.Canvas.TextHeight('A');
end;

2. 主打印流程

在打印触发事件(比如按钮点击)里,初始化打印机,设置等宽字体(这是对齐的关键!),调整纸张宽度,然后调用上面的函数打印商品项。

procedure TMainForm.btnPrintReceiptClick(Sender: TObject);
begin
  Printer.BeginDoc;
  try
    // 关键:设置等宽字体,比如Courier New,确保字符宽度一致,对齐精准
    Printer.Canvas.Font.Name := 'Courier New';
    Printer.Canvas.Font.Size := 10;

    // 适配3英寸纸张:如果打印机支持自定义纸张,可通过PageSettings设置
    // 或者直接发送ESC命令(以EPSON打印机为例,ESC+W+24 表示设置宽度为3英寸,24=3*8)
    Printer.Write(#27#87#24);

    // 打印示例商品
    PrintPOSItem('BOND PAPER 1', 1, 'REAM', 100.00, 100.00);
    PrintPOSItem('BOND PAPER 2', 2, 'REAM', 100.00, 200.00);
    PrintPOSItem('BOND PAPER 3', 1, 'REAM', 1354.00, 1354.00);

    Printer.EndDoc;
  except
    Printer.Abort;
    ShowMessage('打印过程中出现错误,请检查打印机连接!');
  end;
end;
注意事项
  • 必须用等宽字体:如果用非等宽字体(比如宋体),字符宽度不一致,计算出来的填充长度会不准,导致总价对齐混乱。
  • 纸张宽度调整:不同品牌的打印机ESC命令可能不同,比如斑马打印机的纸张设置命令和EPSON不一样,你需要查对应打印机的编程手册。如果用TPrinter的PageSettings,需要在打印机驱动里先添加自定义的3英寸纸张尺寸。
  • 千分位格式化:用FormatFloat('#,##0.00', TotalPrice)可以自动给金额添加千分位,和你的示例格式完全匹配。
  • 错误处理:打印过程中可能出现打印机离线、缺纸等问题,所以一定要加try-except块捕获异常,避免程序崩溃。

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

火山引擎 最新活动