餐饮行业,打印池是必要的部件。
实现原理:每一台打印机都有自己的任务队列和处理任务队列的线程。
unit untPrintTask;
interface
uses
System.SysUtils, System.Classes, Datasnap.DBClient, frxclass, System.Generics.Collections;type
TBillContent = record // 小票内容 machineNo: string; // POS机号 skyName: string; // 收款员姓名 saleNo: string; // 小票号 saleTime: TDateTime; // 销售时间 amount: Currency; // 应收 pay: Currency; // 支付 change: Currency; // 找零 prnData: OleVariant; // 小票明细:商品名称、单价、数量、金额。。。。。。 deskNo:string; // 台号 payType: string; // 支付方式 end;type
TPrinterInfo = record // 打印机信息 prnNo: Integer; // 印机编号 prnName: string; // 印机名称 prnType: string; // 结账、厨打 prnWidth: Integer; // 50mm\76mm\80mm remark: string; // 备注 prnModel: string; // 打印模版 end;type
TOneTimePrint = record // 一次打印 printerInfo: TPrinterInfo; // 打印机信息 billContent: TBillContent; // 小票内容 end;type
TPrintTaskThread = class(TThread) // 打印任务线程 private FPrintQueue: TQueue<TOneTimePrint>; // 打印队列 protected procedure Execute; override; public constructor Create; overload; destructor Destroy; override; property PrintQueue: TQueue<TOneTimePrint> read FPrintQueue write FPrintQueue; end;var
g_PrintTasks: TDictionary<string, TPrintTaskThread>; // <打印机名字, TPrintTask>implementation
{ TPrintTask }
uses untFastReport, UntSysConst;
constructor TPrintTaskThread.Create;
begin Create(False); FreeOnTerminate := False; // 创建打印队列 FPrintQueue := TQueue<TOneTimePrint>.Create;end;destructor TPrintTaskThread.Destroy;
begin // 释放打印队列 FreeAndNil(FPrintQueue); inherited;end;procedure TPrintTaskThread.Execute;
var OneTimePrint: TOneTimePrint; dm: TdmFastReport; c: TfrxComponent;begin while not Self.Terminated do begin if Assigned(FPrintQueue) and (FPrintQueue.Count > 0) then begin // 从任务队列中提取一个任务 OneTimePrint := FPrintQueue.Dequeue; dm := TdmFastReport.Create(nil); try try // 小票明细数据 dm.cds.Data := OneTimePrint.billContent.prnData; // 小票模板 dm.report.LoadFromFile(OneTimePrint.printerInfo.prnModel); // 哪个打印机 dm.report.PrintOptions.Printer := OneTimePrint.printerInfo.prnName; // 变量赋值c:=dm.report.FindObject('mmShopName');
if c<>nil then TfrxMemoView(c).Memo.Text := UserInfo.ShopName;c := dm.report.FindObject('mmMachineNo');
if c<>nil then TfrxMemoView(c).Memo.Text := OneTimePrint.billContent.machineNo;c:=dm.report.FindObject('mmSKY');
if c<>nil then TfrxMemoView(c).Memo.Text := OneTimePrint.billContent.skyName;c:= dm.report.FindObject('mmBillNo');
if c<>nil then TfrxMemoView(c).Memo.Text := OneTimePrint.billContent.saleNo;c:=dm.report.FindObject('mmSaleTime');
if c<>nil then TfrxMemoView(c).Memo.Text := FormatDateTime('yyyy-mm-dd hh:nn',OneTimePrint.billContent.saleTime);c:= dm.report.FindObject('mmDeskNo');
if c<>nil then TfrxMemoView(c).Memo.Text := OneTimePrint.billContent.deskNo; // 台号c:= dm.report.FindObject('mmPayType');
if c<>nil then TfrxMemoView(c).Memo.Text := OneTimePrint.billContent.payType;c:= dm.report.FindObject('mmAmount');
if c<> nil then TfrxMemoView(c).Memo.Text := FormatCurr('0.00', OneTimePrint.billContent.amount);c:=dm.report.FindObject('mmPay');
if c<>nil then TfrxMemoView(c).Memo.Text := FormatCurr('0.00', OneTimePrint.billContent.pay);c:= dm.report.FindObject('mmGiveChange');
if c<> nil then TfrxMemoView(c).Memo.Text := FormatCurr('0.00', OneTimePrint.billContent.change);// 开始打印
dm.report.PrepareReport(); dm.report.Print; except // 打印失败,重新加入任务队列 Self.FPrintQueue.Enqueue(OneTimePrint); end; finally FreeAndNil(dm); end; end; Sleep(1); end;end;end.