熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

Delphi中票據憑證的精確打印

2013-11-23 17:46:49  來源: Delphi編程 

  概述

  在銀行稅務郵政等行業的實際工作中經常涉及到在印刷好具有固定格式的匯款單儲蓄憑證稅票等單據上的確定位置打印輸出相關的信息在此類需求中精確地定位單據並打印相關信息是解決問題]的關鍵一般情況下開發者都是通過在打印機上通過重復的測試來達到實際需求那麼有沒有簡單有效而又靈活的方法實現上述功能呢?

  基本思路

  分析上述單據的特征可以發現此類打印輸出的信息一般比較簡短不涉及到文字過長的折行處理另外其打印輸出的位置相對固定因此我們可以通過用尺子以毫米為單位測量好每個輸出信息位置的橫向和縱向坐標作為信息輸出的位置但由於不同打印機在實際輸出效果上總是存在理論和實際位置的偏差因此要求程序具有一定的靈活性供最終用戶根據需要進行必要的位置調整因此可設置一打印配置文件用於存儲橫坐標和縱坐標的偏移量用於用戶進行位置校正從而提供了一定的靈活性

  精確打印輸出的程序實現

  . 在Delphi中新建一個名為mprintpas的單元文件並編寫如下程序單元引用中加入Printers

//取得字符的高度
function CharHeight: Word;
var
 Metrics: TTextMetric;
begin
 GetTextMetrics(PrinterCanvasHandle Metrics);
 Result := MetricstmHeight;
end;

file://取得字符的平均寬度
function AvgCharWidth: Word;
var
 Metrics: TTextMetric;
begin
 GetTextMetrics(PrinterCanvasHandle Metrics);
 Result := MetricstmAveCharWidth;
end;

file://取得紙張的物理尺寸單位
function GetPhicalPaper: TPoint;
var
 PageSize : TPoint;
begin
 file://PageSizeX; 紙張物理寬度單位:點
 file://PageSizeY; 紙張物理高度單位:點
 Escape(PrinterHandle GETPHYSPAGESIZE nil@PageSize);
 Result := PageSize;
end;

file://取得紙張的邏輯寬度可打印區域
file://取得紙張的邏輯尺寸
function PaperLogicSize: TPoint;
var
 APoint: TPoint;
begin
 APointX := PrinterPageWidth;
 APointY := PrinterPageHeight;
 Result := APoint;
end;

file://紙張水平對垂直方向的縱橫比例
function HVLogincRatio: Extended;
var
 AP: TPoint;
begin
 Ap := PaperLogicSize;
 Result := Apy/ApX;
end;

file://取得紙張的橫向偏移量單位
function GetOffSetX: Integer;
begin
 Result := GetDeviceCaps(PrinterHandle PhysicalOffSetX);
end;

file://取得紙張的縱向偏移量單位
function GetOffSetY: Integer;
begin
 Result := GetDeviceCaps(PrinterHandle PhysicalOffSetY);
end;

file://毫米單位轉換為英寸單位
function MmToInch(Length: Extended): Extended;
begin
 Result := Length/;
end;

file://英寸單位轉換為毫米單位
function InchToMm(Length: Extended): Extended;
begin
 Result := Length*;
end;

file://取得水平方向每英寸打印機的點數
function HPointsPerInch: Integer;
begin
 Result := GetDeviceCaps(PrinterHandle LOGPIXELSX);
end;

file://取得縱向方向每英寸打印機的光柵數
function VPointsPerInch: Integer;
begin
 Result := GetDeviceCaps(PrinterHandle LOGPIXELSY)
end;

file://橫向點單位轉換為毫米單位
function XPointToMm(Pos: Integer): Extended;
begin
 Result := Pos*/HPointsPerInch;
end;

file://縱向點單位轉換為毫米單位
function YPointToMm(Pos: Integer): Extended;
begin
 Result := Pos*/VPointsPerInch;
end;

file://設置紙張高度單位mm
procedure SetPaperHeight(Value:integer);
var
 Device : array[] of char;
 Driver : array[] of char;
 Port : array[] of char;
 hDMode : THandle;
 PDMode : PDEVMODE;
begin
file://自定義紙張最小高度mm
if Value < then Value := ;
 file://自定義紙張最大高度mm
 if Value > then Value := ;
  PrinterPrinterIndex := PrinterPrinterIndex;
  PrinterGetPrinter(Device Driver Port hDMode);
  if hDMode <> then
   begin
    pDMode := GlobalLock(hDMode);
    if pDMode <> nil then
    begin
     pDMode^dmFields := pDMode^dmFields or DM_PAPERSIZE or
               DM_PAPERLENGTH;
     pDMode^dmPaperSize := DMPAPER_USER;
     pDMode^dmPaperLength := Value * ;
     pDMode^dmFields := pDMode^dmFields or DMBIN_MANUAL;
     pDMode^dmDefaultSource := DMBIN_MANUAL;
     GlobalUnlock(hDMode);
    end;
   end;
   PrinterPrinterIndex := PrinterPrinterIndex;
end;

file://設置紙張寬度單位mm
Procedure SetPaperWidth(Value:integer);
var
 Device : array[] of char;
 Driver : array[] of char;
 Port : array[] of char;
 hDMode : THandle;
 PDMode : PDEVMODE;
begin
file://自定義紙張最小寬度mm
if Value < then Value := ;
 file://自定義紙張最大寬度mm
 if Value > then Value := ;
  PrinterPrinterIndex := PrinterPrinterIndex;
  PrinterGetPrinter(Device Driver Port hDMode);
  if hDMode <> then
  begin
   pDMode := GlobalLock(hDMode);
   if pDMode <> nil then
   begin
    pDMode^dmFields := pDMode^dmFields or DM_PAPERSIZE or
              DM_PAPERWIDTH;
    pDMode^dmPaperSize := DMPAPER_USER;
    file://將毫米單位轉換為mm單位
    pDMode^dmPaperWidth := Value * ;
    pDMode^dmFields := pDMode^dmFields or DMBIN_MANUAL;
    pDMode^dmDefaultSource := DMBIN_MANUAL;
    GlobalUnlock(hDMode);
   end;
  end;
  PrinterPrinterIndex := PrinterPrinterIndex;
end;

file://在 (Xmm Ymm)處按指定配置文件信息和字體輸出字符串
procedure PrintText(X Y: Extended; Txt: string; ConfigFileName: string; FontSize: Integer=);
var
 OrX OrY: Extended;
 Px Py: Integer;
 AP: TPoint;
 Fn: TStrings;
 FileName: string;
 OffSetX OffSetY: Integer;
begin
file://打開配置文件讀出橫向和縱向偏移量
try
 Fn := TStringListCreate;
 FileName := ExtractFilePath(ApplicationExeName) + ConfigFileName;
 if FileExists(FileName) then
 begin
  FnLoadFromFile(FileName);
  file://橫向偏移量
  OffSetX := StrToInt(FnValues[X]);
  file://縱向偏移量
  OffSetY := StrToInt(FnValues[Y]);
 end
else
begin
 file://如果沒有配置文件則生成
 FnValues[X] := ;
 FnValues[Y] := ;
 FnSaveToFile(FileName);
end;
finally
 FnFree;
end;
X := X + OffSetX;
Y := Y + OffSetY;
Px := Round(Round(X * HPointsPerInch * /) / );
Py := Round(Round(Y * VPointsPerInch * /) / );
Py := Py GetOffSetY; file://因為是絕對坐標 因此 不用換算成相對於Y軸坐標
Px := Px + * AvgCharWidth;
PrinterCanvasFontName := 宋體;
PrinterCanvasFontSize := FontSize;
file://PrinterCanvasFontColor := clGreen;
PrinterCanvasTextOut(Px Py Txt);
end;

  . 使用舉例

  在主窗體中加入對mprint單元的引用在一命令鈕的OnClick事件中書寫如下代碼(用於在郵政匯款單上的相應方框內打印郵政編碼

PrinterBeginDoc;
PrintText( configtxt);
PrintText( configtxt);
PrintText( configtxt);
PrintText( configtxt);
PrintText( configtxt);
PrintText( configtxt);
PrinterEndDoc;

  觀察結果用尺子測量偏移量在configtxt文件中修改XY的值即可

  其它設置打印機和紙張類型從略

  結束語

  筆者通過該方法實現了郵政匯款單儲蓄憑證客戶信封等單據的精確打印取得了較為滿意的效果該程序在WindowsDelphi下調試通過


From:http://tw.wingwit.com/Article/program/Delphi/201311/25061.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.