餐饮软件,特别是中厨的出品打印机数量非常多,整个酒店可能有N个出品部门,一个出品部门可能有N台出品打印机。
打印队列的功用:
(1)打印不掉单,打印任务缓存于队列中,如果某个打印任务失败,则重新加入队列;
(2)各台打印机都是并行作业,一台打印机发生故障不会影响其它打印机的正常工作。
打印队列实现方法之一:
为每一台打印机建立自己专属的打印任务队列和打印任务处理线程。
// 单元功用:处理打印任务的线程
// 单元设计:cxg
// 设计日期:2014-05-12
unit untPrintTask;
interface
uses
 System.SysUtils, System.Classes, Vcl.Dialogs,
 Datasnap.DBClient, Vcl.Forms, frxclass, System.Variants,
 System.Generics.Collections;
type
 TBillContent = record // 小票内容
 machineNo: string; // POS机 
 skyName: string; // 收款员姓名
 saleNo: string; // 小票 
 saleTime: TDateTime; // 销售时间
 amount: Currency; // 应收
 pay: Currency; // 支付
 change: Currency; // 找零
 prnData: OleVariant; // 商品名称、单价、数量、金额
 end;
type
 TPrinterInfo = record // 打印机信息
 prnNo: Integer; // 印机编 
 prnName: string; // 印机名称
 prnType: string; // 结账、厨打
 prnWidth: Integer; // 50mm76mm80mm
 remark: string; // 备注
 prnModel: string; // 打印模版
 end;
type
 TOneTimePrint = record // 一次打印
 printerInfo: TPrinterInfo; // 打印机信息
 billContent: TBillContent; // 小票内容
 end;
type
 TPrintTask = 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
 PrintTaskArray: array of TPrintTask;
implementation
{ TPrintTask }
uses untFastReport;
constructor TPrintTask.Create;
begin
 Create(False);
 FPrintQueue := TQueue<TOneTimePrint>.Create;
end;
destructor TPrintTask.Destroy;
begin
 FreeAndNil(FPrintQueue);
 inherited;
end;
procedure TPrintTask.Execute;
var
 OneTimePrint: TOneTimePrint;
 dm: TdmFastReport;
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;
 TfrxMemoView(dm.report.FindObject(‘mmMachineNo’)).Memo.Text :=
 OneTimePrint.billContent.machineNo;
 TfrxMemoView(dm.report.FindObject(‘mmSKY’)).Memo.Text :=
 OneTimePrint.billContent.skyName;
 TfrxMemoView(dm.report.FindObject(‘mmBillNo’)).Memo.Text :=
 OneTimePrint.billContent.saleNo;
 TfrxMemoView(dm.report.FindObject(‘mmSaleTime’)).Memo.Text :=
 FormatDateTime(‘yyyy-mm-dd hh:nn’,
 OneTimePrint.billContent.saleTime);
 TfrxMemoView(dm.report.FindObject(‘mmAmount’)).Memo.Text :=
 FormatCurr(‘0.00’, OneTimePrint.billContent.amount);
 TfrxMemoView(dm.report.FindObject(‘mmPay’)).Memo.Text :=
 FormatCurr(‘0.00’, OneTimePrint.billContent.pay);
 TfrxMemoView(dm.report.FindObject(‘mmGiveChange’)).Memo.Text :=
 FormatCurr(‘0.00’, OneTimePrint.billContent.change);
 // dm.report.ShowReport();
 dm.report.PrepareReport();
 dm.report.Print;
 except
 Self.FPrintQueue.Enqueue(OneTimePrint);
 end;
 finally
 FreeAndNil(dm);
 end;
 end;
 Sleep(1000);
 end;
end;
end.
// 为每一台打印机创建队列和线程
 {$IFDEF pool}
 SetLength(PrintTaskArray, cdsPrinter.RecordCount);
 for i := 0 to High(PrintTaskArray) do
 begin
 PrintTaskArray[i] := TPrintTask.Create;
 PrintTaskArray[i].FreeOnTerminate := False;
 end;
{$ENDIF}
// 释放所有的线程
 {$IFDEF pool}
 for i := 0 to High(PrintTaskArray) do
 begin
 PrintTaskArray[i].Terminate;
 PrintTaskArray[i].WaitFor;
 FreeAndNil(PrintTaskArray[i]);
 end;
// 打印小票
procedure TfrmSettleAccount.PrintBill;
var
 OneTimePrint: TOneTimePrint;
begin
 frmPos.cdsPrinter.First;
 while not frmPos.cdsPrinter.Eof do
 begin
 // 打印机信息
 OneTimePrint.printerInfo.prnNo := frmPos.cdsPrinter.FieldByName(‘prnNo’).AsInteger;
 OneTimePrint.printerInfo.prnName := frmPos.cdsPrinter.FieldByName(‘prnName’).Text;
 OneTimePrint.printerInfo.prnType := frmPos.cdsPrinter.FieldByName(‘prnType’).Text;
 OneTimePrint.printerInfo.prnWidth := frmPos.cdsPrinter.FieldByName(‘prnWidth’).AsInteger;
 OneTimePrint.printerInfo.remark := frmPos.cdsPrinter.FieldByName(‘remark’).Text;
 case OneTimePrint.printerInfo.prnWidth of
 58: OneTimePrint.printerInfo.prnModel := ExtractFilePath(Application.ExeName) + ‘reportpos58.fr3’;
 76: OneTimePrint.printerInfo.prnModel := ExtractFilePath(Application.ExeName) + ‘reportpos76.fr3’;
 80: OneTimePrint.printerInfo.prnModel := ExtractFilePath(Application.ExeName) + ‘reportpos80.fr3’;
 end;
 // 小票内容
 OneTimePrint.billContent.machineNo := UserInfo.MachineId;
 OneTimePrint.billContent.skyName := UserInfo.UserName;
 OneTimePrint.billContent.saleNo := UserInfo.SaleNo;
 OneTimePrint.billContent.saleTime := Now;
 OneTimePrint.billContent.amount := self.Total.totalAmount;
 OneTimePrint.billContent.pay := StrToCurrDef(edtCash.Text, 0);
 OneTimePrint.billContent.change := StrToCurrDef(edtChange.Text, 0);
 OneTimePrint.billContent.prnData := frmPos.cdsSaleD.Data;
 // 加入打印队列
 PrintTaskArray[frmPos.cdsPrinter.RecNo – 1].PrintQueue.Enqueue(OneTimePrint);
 frmPos.cdsPrinter.Next;
 end;
end;
{$ENDIF}
相关资源:校园自助点餐APP的开发.rar-互联 文档类资源-CSDN文库
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!