📄 pjinvoice.pas
字号:
if FTabSize>100 then FTabSize:=100;
if FTabSize<1 then FTabSize:=1;
Update;
end;
end;
function TCustomInvoicePrintJob.GetNormalText(Strings: TStrings): string;
begin
Result:=Strings.Text;
if Result<>'' then
while Result[Length(Result)] in [#10,#13] do
Delete(Result,Length(Result),1);
end;
procedure TCustomInvoicePrintJob.Loaded;
begin
inherited;
Update;
end;
constructor TCustomInvoicePrintJob.Create(AOwner: TComponent);
begin
inherited;
FPages:=TList.Create;
FLogo:=TPicture.Create;
FCompanyNameFont:=TFont.Create;
with FCompanyNameFont do
begin
Name:='Arial';
Size:=20;
end;
FInvoiceHeaderFont:=TFont.Create;
with FInvoiceHeaderFont do
begin
Name:='Arial';
Size:=12;
Style:=[fsBold];
end;
FCompanyAddressFont:=TFont.Create;
with FCompanyAddressFont do
begin
Name:='Arial';
Size:=10;
Style:=[fsBold];
end;
FCustomerAddressFont:=TFont.Create;
with FCustomerAddressFont do
begin
Name:='Arial';
Size:=10;
Style:=[fsBold];
end;
FDetailsHeaderFont:=TFont.Create;
with FDetailsHeaderFont do
begin
Name:='Arial';
Size:=10;
Style:=[fsBold];
end;
FDetailsFont:=TFont.Create;
with FDetailsFont do
begin
Name:='Arial';
Size:=10;
end;
FTotalFont:=TFont.Create;
with FTotalFont do
begin
Name:='Arial';
Size:=10;
Style:=[fsBold];
end;
FInvoiceFooterFont:=TFont.Create;
with FInvoiceFooterFont do
begin
Name:='Arial';
Size:=10;
Style:=[fsBold];
end;
FInvoiceHeader:=TStringList.Create;
FCompanyAddress:=TStringList.Create;
FCustomerAddress:=TStringList.Create;
FDetailsHeader:=TStringList.Create;
FDetails:=TStringList.Create;
FTotal:=TStringList.Create;
FInvoiceFooter:=TStringList.Create;
FTabSize:=25;
end;
destructor TCustomInvoicePrintJob.Destroy;
begin
FPages.Free;
FLogo.Free;
FCompanyNameFont.Free;
FCustomerAddressFont.Free;
FCompanyAddressFont.Free;
FDetailsHeaderFont.Free;
FDetailsFont.Free;
FTotalFont.Free;
FInvoiceFooterFont.Free;
FCompanyAddress.Free;
FCustomerAddress.Free;
FDetailsHeader.Free;
FDetails.Free;
FTotal.Free;
FInvoiceFooter.Free;
inherited;
end;
procedure TCustomInvoicePrintJob.DrawArea(TheCanvas: TCanvas; PageIndex: Integer; TheRect: TRect; Area: TDrawArea; Target: TDrawTarget);
var
R: TRect;
i,TS,StartLine,EndLine: Integer;
S: string;
function LineHeight: Integer;
var
TM: TTextMetric;
begin
GetTextMetrics(TheCanvas.Handle,TM);
Result:=TM.tmHeight+2;
end;
begin
if Area=daPage then
with TheRect,TheCanvas do
begin
R:=TheRect;
with R do
begin
SetBkMode(Handle,TRANSPARENT);
if PageIndex=1 then
begin
// Logo
Font.Assign(FCompanyNameFont);
Bottom:=Top+TextHeight(FCompanyName);
if Assigned(FLogo.Graphic) then
begin
Right:=Left+2*(Bottom-Top);
StretchBitmap(TheCanvas,R,TBitmap(FLogo.Graphic),smFit,ahLeft,avCenter,Target);
Left:=Right+(Bottom-Top);
Right:=TheRect.Right;
end;
TextOut(Left,Top,FCompanyName);
if FCompanyNameSeparator then
begin
MoveTo(TheRect.Left,Bottom+LineHeight div 2);
LineTo(Right,PenPos.Y);
end;
Left:=TheRect.Left;
// InvoiceHeader
Top:=Bottom+LineHeight;
Bottom:=TheRect.Bottom;
Font.Assign(FInvoiceHeaderFont);
Inc(Top,DrawText(Handle,PChar(GetNormalText(FInvoiceHeader)),-1,R,DT_WORDBREAK or DT_NOCLIP)+LineHeight);
if FInvoiceHeaderSeparator then
begin
MoveTo(TheRect.Left,Top);
LineTo(Right,PenPos.Y);
end;
Inc(Top,LineHeight);
Bottom:=TheRect.Bottom;
// CompanyAddress
Font.Assign(FCompanyAddressFont);
Inc(Top,DrawText(Handle,PChar(GetNormalText(FCompanyAddress)),-1,R,DT_WORDBREAK or DT_NOCLIP)+LineHeight);
if FCompanyAddressSeparator then
begin
MoveTo(TheRect.Left,Top);
LineTo(Right,PenPos.Y);
end;
Inc(Top,LineHeight);
// CustomerAddress
Font.Assign(FCustomerAddressFont);
Inc(Top,DrawText(Handle,PChar(GetNormalText(FCustomerAddress)),-1,R,DT_WORDBREAK or DT_NOCLIP)+LineHeight);
if FCustomerAddressSeparator then
begin
MoveTo(TheRect.Left,Top);
LineTo(Right,PenPos.Y);
end;
Inc(Top,LineHeight);
// DetailsHeader
Font.Assign(FDetailsHeaderFont);
TS:=FTabSize*(Right-Left) div 100;
for i:=0 to Pred(FDetailsHeader.Count) do
begin
S:=FDetailsHeader[i];
TabbedTextOut(Handle,Left,Top,PChar(S),Length(S),1,TS,Left);
Inc(Top,LineHeight);
end;
Inc(Top,LineHeight);
if FDetailsHeaderSeparator then
begin
MoveTo(TheRect.Left,Top);
LineTo(Right,PenPos.Y);
end;
Inc(Top,LineHeight);
end;
// Details
Font.Assign(FDetailsFont);
TS:=FTabSize*(Right-Left) div 100;
if PageIndex=1 then StartLine:=0
else
if Integer(FPages[PageIndex-2]) and $F0000 = brkDetails then StartLine:=Integer(FPages[PageIndex-2]) and $FFFF
else StartLine:=0;
if (PageIndex<=FPages.Count) and (Integer(FPages[Pred(PageIndex)]) and $F0000 = brkDetails) then EndLine:=Pred(Integer(FPages[Pred(PageIndex)]) and $FFFF)
else EndLine:=Pred(FDetails.Count);
for i:=StartLine to EndLine do
begin
S:=FDetails[i];
TabbedTextOut(Handle,Left,Top,PChar(S),Length(S),1,TS,Left);
Inc(Top,LineHeight);
end;
Inc(Top,LineHeight);
if EndLine=Pred(FDetails.Count) then
if FDetailsSeparator then
begin
MoveTo(TheRect.Left,Top);
LineTo(Right,PenPos.Y);
end;
Inc(Top,LineHeight);
if PageIndex=PageCount then
begin
// Total
Font.Assign(FTotalFont);
TS:=FTabSize*(Right-Left) div 100;
for i:=0 to Pred(FTotal.Count) do
begin
S:=FTotal[i];
TabbedTextOut(Handle,Left,Top,PChar(S),Length(S),1,TS,Left);
Inc(Top,LineHeight);
end;
Inc(Top,LineHeight);
if FTotalSeparator then
begin
MoveTo(TheRect.Left,Top);
LineTo(Right,PenPos.Y);
end;
// InvoiceFooter
Inc(Top,LineHeight);
DrawText(Handle,PChar(FInvoiceFooter.Text),-1,R,DT_WORDBREAK or DT_EXPANDTABS or DT_TABSTOP or FTabSize shl 8);
end;
end;
end
else inherited;
end;
procedure TCustomInvoicePrintJob.Update;
var
i,Cur: Integer;
R,PR: TRect;
Canvas: TCanvas;
function LineHeight: Integer;
var
TM: TTextMetric;
begin
GetTextMetrics(Canvas.Handle,TM);
Result:=TM.tmHeight+2;
end;
begin
if csLoading in ComponentState then Exit;
Canvas:=TCanvas.Create;
try
Cur:=0;
R:=GetPageRect;
PR:=R;
FPages.Clear;
with Canvas,R do
begin
Handle:=CreateDC('DISPLAY',nil,nil,nil);
Font.PixelsPerInch:=GetDeviceCaps(Printer.Handle,LOGPIXELSY);
// Logo
Font.Assign(FCompanyNameFont);
Inc(Cur,TextHeight(FCompanyName)+LineHeight div 2);
// InvoiceHeader
Font.Assign(FInvoiceHeaderFont);
Inc(Cur,LineHeight div 2);
Inc(Cur,DrawText(Handle,PChar(GetNormalText(FInvoiceHeader)),-1,R,DT_WORDBREAK or DT_NOCLIP or DT_CALCRECT)+LineHeight);
Inc(Cur,LineHeight);
// CompanyAddress
Right:=PR.Right;
Font.Assign(FCompanyAddressFont);
Inc(Cur,DrawText(Handle,PChar(GetNormalText(FCompanyAddress)),-1,R,DT_WORDBREAK or DT_NOCLIP or DT_CALCRECT)+LineHeight);
Inc(Cur,LineHeight);
// CustomerAddress
Right:=PR.Right;
Font.Assign(FCustomerAddressFont);
Inc(Cur,DrawText(Handle,PChar(GetNormalText(FCustomerAddress)),-1,R,DT_WORDBREAK or DT_NOCLIP or DT_CALCRECT)+LineHeight);
Inc(Cur,LineHeight);
// DetailsHeader
Font.Assign(FDetailsHeaderFont);
Inc(Cur,FDetailsHeader.Count*LineHeight);
Inc(Cur,LineHeight);
Inc(Cur,LineHeight);
// Details
Font.Assign(FDetailsFont);
for i:=0 to Pred(FDetails.Count) do
begin
Inc(Cur,LineHeight);
if Cur>=PR.Bottom-PR.Top then
begin
FPages.Add(Pointer(brkDetails+i));
Cur:=0;
end;
end;
Inc(Cur,LineHeight);
if Cur>=PR.Bottom-PR.Top then
begin
FPages.Add(Pointer(brkDetails));
Cur:=0;
end;
Inc(Cur,LineHeight);
// Total
Font.Assign(FTotalFont);
for i:=0 to Pred(FTotal.Count) do
begin
Inc(Cur,LineHeight);
if Cur>=PR.Bottom-PR.Top then
begin
FPages.Add(Pointer(brkFooter));
Exit;
end;
end;
Inc(Cur,LineHeight);
if Cur>=PR.Bottom-PR.Top then
begin
FPages.Add(Pointer(brkFooter));
Exit;
end;
Inc(Cur,LineHeight);
// InvoiceFooter
Right:=PR.Right;
Inc(Cur,LineHeight);
Inc(Cur,DrawText(Handle,PChar(FInvoiceFooter.Text),-1,R,DT_WORDBREAK or DT_EXPANDTABS or DT_TABSTOP or (FTabSize shl 8) or DT_CALCRECT));
if Cur>PR.Bottom-PR.Top then FPages.Add(Pointer(brkFooter));
end;
finally
Canvas.Handle:=0;
Canvas.Free;
end;
PageCount:=Succ(FPages.Count);
inherited;
end;
procedure Register;
begin
RegisterComponents('Print Jobs', [TInvoicePrintJob]);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -