其他语言

位置:IT落伍者 >> 其他语言 >> 浏览文章

Delphi中票据凭证的精确打印


发布日期:2018年02月10日
 
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下调试通过

               

上一篇:Delphi控制Excel2000心得

下一篇:DELPHI下的多线程程序设计