求Printer打印例程! ( 积分: 200 )

  • 主题发起人 主题发起人 findwo
  • 开始时间 开始时间
F

findwo

Unregistered / Unconfirmed
GUEST, unregistred user!
主要用想于打票,
 
主要用想于打票,
 
This example uses a button and a memo on a form. When the user clicks the button, the content of the memo is printed, with a 200-pixel border around the page. To run this example successfully, you must add the Printers unit to the uses clause of your unit.
procedure TForm1.Button1Click(Sender: TObject);
begin
with Printerdo
begin
begin
Doc;
Canvas.TextRect(Rect(200,200,PageWidth-200,PageHeight-200),
200, 200, Memo1.Lines.Text);
EndDoc;
end;

end;
 
这个会报错的啊能不能详细点?
 
uses printers;
 
delphi 的
TPrinter
帮助
 
你的这个代码有没有试过没反应的啊!
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=584736
Delphi中票据凭证的精确打印

2001-11-09 08:51:25
一、概述
  在银行,税务,邮政等行业的实际工作中,经常涉及到在印刷好具有固定格式的汇款单,储蓄凭证,税票等单据上的确定位置打印输出相关的信息。在此类需求中,精确地定位单据并打印相关信息,是解决问题]的关键。一般情况下,开发者都是通过在打印机上通过重复的测试来达到实际需求。那么,有没有简单有效而又灵活的方法实现上述功能呢?
  二、基本思路
  分析上述单据的特征,可以发现:此类打印输出的信息一般比较简短,不涉及到文字过长的折行处理,另外,其打印输出的位置相对固定。因此,我们可以通过用尺子以毫米为单位,测量好每个输出信息位置的横向和纵向坐标,作为信息输出的位置。但由于不同打印机在实际输出效果上,总是存在理论和实际位置的偏差,因此,要求程序具有一定的灵活性,供最终用户根据需要,进行必要的位置调整。因此,可设置一打印配置文件,用于存储横坐标和纵坐标的偏移量,用于用户进行位置校正,从而提供了一定的灵活性。
  三、精确打印输出的程序实现
  1. 在Delphi中新建一个名为mprint.pas的单元文件并编写如下程序,单元引用中加入Printers略:
 
//取得字符的高度
function CharHeight: Word;
var
 Metrics: TTextMetric;
begin
 GetTextMetrics(Printer.Canvas.Handle, Metrics);
 Result := Metrics.tmHeight;
end;

file://取得字符的平均宽度
function AvgCharWidth: Word;
var
 Metrics: TTextMetric;
begin
 GetTextMetrics(Printer.Canvas.Handle, Metrics);
 Result := Metrics.tmAveCharWidth;
end;

file://取得纸张的物理尺寸---单位:点
function GetPhicalPaper: TPoint;
var
 PageSize : TPoint;
begin
 file://PageSize.X/;
纸张物理宽度-单位:点
 file://PageSize.Y/;
纸张物理高度-单位:点
 Escape(Printer.Handle, GETPHYSPAGESIZE, 0,nil,@PageSize);
 Result := PageSize;
end;

file://2/.取得纸张的逻辑宽度--可打印区域
file://取得纸张的逻辑尺寸
function PaperLogicSize: TPoint;
var
 APoint: TPoint;
begin
 APoint.X := Printer.PageWidth;
 APoint.Y := Printer.PageHeight;
 Result := APoint;
end;

file://纸张水平对垂直方向的纵横比例
function HVLogincRatio: Extended;
var
 AP: TPoint;
begin
 Ap := PaperLogicSize;
 Result := Ap.y/Ap.X;
end;

file://取得纸张的横向偏移量-单位:点
function GetOffSetX: Integer;
begin
 Result := GetDeviceCaps(Printer.Handle, PhysicalOffSetX);
end;

file://取得纸张的纵向偏移量-单位:点
function GetOffSetY: Integer;
begin
 Result := GetDeviceCaps(Printer.Handle, PhysicalOffSetY);
end;

file://毫米单位转换为英寸单位
function MmToInch(Length: Extended): Extended;
begin
 Result := Length/25.4;
end;

file://英寸单位转换为毫米单位
function InchToMm(Length: Extended): Extended;
begin
 Result := Length*25.4;
end;

file://取得水平方向每英寸打印机的点数
function HPointsPerInch: Integer;
begin
 Result := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
end;

file://取得纵向方向每英寸打印机的光栅数
function VPointsPerInch: Integer;
begin
 Result := GetDeviceCaps(Printer.Handle, LOGPIXELSY)
end;

file://横向点单位转换为毫米单位
function XPointToMm(Pos: Integer): Extended;
begin
 Result := Pos*25.4/HPointsPerInch;
end;

file://纵向点单位转换为毫米单位
function YPointToMm(Pos: Integer): Extended;
begin
 Result := Pos*25.4/VPointsPerInch;
end;

file://设置纸张高度-单位:mm
procedure SetPaperHeight(Value:integer);
var
 Device : array[0..255] of char;
 Driver : array[0..255] of char;
 Port : array[0..255] of char;
 hDMode : THandle;
 PDMode : PDEVMODE;
begin
file://自定义纸张最小高度127mm
if Value < 127 then
Value := 127;
 file://自定义纸张最大高度432mm
 if Value > 432 then
Value := 432;
  Printer.PrinterIndex := Printer.PrinterIndex;
  Printer.GetPrinter(Device, Driver, Port, hDMode);
  if hDMode <> 0 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 * 10;
     pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
     pDMode^.dmDefaultSource := DMBIN_MANUAL;
     GlobalUnlock(hDMode);
    end;
   end;
   Printer.PrinterIndex := Printer.PrinterIndex;
end;

file://设置纸张宽度:单位--mm
Procedure SetPaperWidth(Value:integer);
var
 Device : array[0..255] of char;
 Driver : array[0..255] of char;
 Port : array[0..255] of char;
 hDMode : THandle;
 PDMode : PDEVMODE;
begin
file://自定义纸张最小宽度76mm
if Value < 76 then
Value := 76;
 file://自定义纸张最大宽度216mm
 if Value > 216 then
Value := 216;
  Printer.PrinterIndex := Printer.PrinterIndex;
  Printer.GetPrinter(Device, Driver, Port, hDMode);
  if hDMode <> 0 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://将毫米单位转换为0.1mm单位
    pDMode^.dmPaperWidth := Value * 10;
    pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
    pDMode^.dmDefaultSource := DMBIN_MANUAL;
    GlobalUnlock(hDMode);
   end;
  end;
  Printer.PrinterIndex := Printer.PrinterIndex;
end;

file://在 (Xmm, Ymm)处按指定配置文件信息和字体输出字符串
procedure PrintText(X, Y: Extended;
Txt: string;
ConfigFileName: string;FontSize: Integer=12);
var
 OrX, OrY: Extended;
 Px, Py: Integer;
 AP: TPoint;
 Fn: TStrings;
 FileName: string;
 OffSetX, OffSetY: Integer;
begin
file://打开配置文件,读出横向和纵向偏移量
try
 Fn := TStringList.Create;
 FileName := ExtractFilePath(Application.ExeName) + ConfigFileName;
 if FileExists(FileName) then
 begin
  Fn.LoadFromFile(FileName);
  file://横向偏移量
  OffSetX := StrToInt(Fn.Values['X']);
  file://纵向偏移量
  OffSetY := StrToInt(Fn.Values['Y']);
 end
else
begin
 file://如果没有配置文件,则生成
 Fn.Values['X'] := '0';
 Fn.Values['Y'] := '0';
 Fn.SaveToFile(FileName);
end;
finally
 Fn.Free;
end;
X := X + OffSetX;
Y := Y + OffSetY;
Px := Round(Round(X * HPointsPerInch * 10000/25.4) / 10000);
Py := Round(Round(Y * VPointsPerInch * 10000/25.4) / 10000);
Py := Py - GetOffSetY;
file://因为是绝对坐标, 因此, 不用换算成相对于Y轴坐标
Px := Px + 2 * AvgCharWidth;
Printer.Canvas.Font.Name := '宋体';
Printer.Canvas.Font.Size := FontSize;
file://Printer.Canvas.Font.Color/ := clGreen;
Printer.Canvas.TextOut(Px, Py, Txt);
end;


  2. 使用举例
  在主窗体中加入对mprint单元的引用,在一命令钮的OnClick事件中书写如下代码(用于在邮政汇款单上的相应方框内打印邮政编码843300):
 
Printer.begin
Doc;
PrintText(16, 14, '8', 'config.txt');
PrintText(26, 14, '4', 'config.txt');
PrintText(36, 14, '3', 'config.txt');
PrintText(46, 14, '3', 'config.txt');
PrintText(56, 14, '0', 'config.txt');
PrintText(66, 14, '0', 'config.txt');
Printer.EndDoc;

  观察结果,用尺子测量偏移量,在config.txt文件中修改X,Y的值即可。
  其它,设置打印机和纸张类型从略。
  四、结束语
  笔者通过该方法,实现了邮政汇款单,储蓄凭证,客户信封等单据的精确打印,取得了较为满意的效果。该程序在Windows98,Delphi5下调试通过。
 
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=2397777
套打关键要精确测量打印位置,
给你一个自写的关于套打的单元(附如何使用示例)
---------------------------------
unit cu_Printer;
interface
uses
Printers, Types, Windows, Messages, SysUtils, Variants, Graphics,Dialogs,
Inifiles, Forms;
type
TCustomPrinter=class(TObject)
private
FiOffsetX: Integer;
//水平方向偏移量:毫米
FiOffsetY: Integer;
//垂直方向偏移量:毫米
//取得字符的高度
function CharHeight: Word;
//取得字符的平均宽度
function AvgCharWidth: Word;
//取得纸张的物理尺寸---单位:点
function GetPhicalPaper: TPoint;
//得到打印机默认的页边距
function GetPrintStartPos:TPoint;
//取得纸张的逻辑宽度--可打印区域,纸张的逻辑尺寸
function PaperLogicSize: TPoint;
//纸张水平对垂直方向的纵横比例
function HVLogincRatio: Extended;
//取得纸张的横向偏移量-单位:点
function GetOffSetX: Integer;
//取得纸张的纵向偏移量-单位:点
function GetOffSetY: Integer;
//毫米单位转换为英寸单位
function MmToInch(Length: Extended): Extended;
//英寸单位转换为毫米单位
function InchToMm(Length: Extended): Extended;
//取得水平方向每英寸打印机的点数
function HPointsPerInch: Integer;
//取得纵向方向每英寸打印机的光栅数
function VPointsPerInch: Integer;
//横向点单位转换为毫米单位
function XPointToMm(Pos: Integer): Extended;
//纵向点单位转换为毫米单位
function YPointToMm(Pos: Integer): Extended;
//设置纸张尺寸:纸张宽度和纸张高度-单位:mm
procedure SetPagerSize(const ASize: Integer;
AWidth,AHeight:do
uble);
protected
public
constructor Create;
{********************************************************************
函数名称: InitPrinter
函数功能: 初始化打印机,包括打印机名称、纸张大小等等
输入参数: ConfigIni: string --打印配置文件:*.ini
输出参数: None --参数的用途
*********************************************************************
建立日期: 2002-11-27
作 者: 宋修虎
最近更新时间:
********************************************************************}
procedure InitPrinter(PRatio: Integer=1;APWidth:do
uble=171;
APHeight:do
uble=78;APsize: Integer=256;ADeviceName:string='';
Adefault:string='YES';AOffsetX:Integer=0;AOffsetY:Integer=0);
overload;
procedure InitPrinter(ConfigIni: string;PRatio: Integer=1);
overload;
{********************************************************************
函数名称: PrintText
函数功能: 在 (Xmm, Ymm)处按指定配置文件信息和字体输出字符串
输入参数: X, Y: Extended;
-- 打印起始点,单位为毫米
输入参数: LineHeight, TextWidth: Extended;
--行高,待打印矩形宽度
输入参数: Txt: string;
-- 待打印的文本
输入参数: FontSize: Integer=12 --字体为'宋体',缺省大小为12,
输入参数: TextAlignment: Integer=DT_LEFT --文本对齐方式,缺省为'左对齐'
输入参数: AllowNewLine:Boolean=False --是否允许换行
输出参数: 换了几行则返回几,默认为1,未换行 --参数的用途
*********************************************************************
建立日期: 2002-11-27
作 者: 宋修虎
最近更新时间:
********************************************************************}
function PrintText(Xmm, Ymm, LineHeight, TextWidth: Extended;
Txt: string;
FontSize: Integer=10;
TextAlignment: Integer=DT_LEFT;
AllowNewLine:Boolean=False):Integer;
overload;
function PrintText(Xmm, Ymm: Extended;
Txt: string;FontSize: Integer=10;
AllowNewLine:Boolean=False):Integer;
overload;
procedure PrintChar(s: PChar);
procedure PrintEllipse(Xmm1, Ymm1, Xmm2, Ymm2: Integer;APenWidth: Integer=2);
procedure PrintLine(Xmm1, Ymm1, Xmm2, Ymm2: Integer;
ACanvas: TCanvas;
APenWidth: Integer=5);
procedure PrintTableLine(ACanvas: TCanvas;
APenWidth: Integer=5);
end;

implementation

constructor TCustomPrinter.Create;
begin
FiOffsetX:=0;
FiOffsetY:=0;
end;

function TCustomPrinter.CharHeight: Word;
{取得字符的高度}
var
Metrics: TTextMetric;
begin
GetTextMetrics(Printer.Canvas.Handle, Metrics);
Result := Metrics.tmHeight;
end;

//取得字符的平均宽度
function TCustomPrinter.AvgCharWidth: Word;
var
Metrics: TTextMetric;
begin
GetTextMetrics(Printer.Canvas.Handle, Metrics);
Result := Metrics.tmAveCharWidth;
end;

//取得纸张的物理尺寸---单位:点
function TCustomPrinter.GetPhicalPaper: TPoint;
var
PageSize : TPoint;
begin
//PageSize.X;
纸张物理宽度-单位:点
//PageSize.Y;
纸张物理高度-单位:点
Escape(Printer.Handle, GETPHYSPAGESIZE, 0,nil,@PageSize);
Result := PageSize;
end;

//打印机的坐标原点总是在纸张的左上角,不管纸张从那个方向进入打印机。
//得到打印机默认的页边距
function TCustomPrinter.GetPrintStartPos:TPoint;
var
pageMargin:TPoint;
myEscape:integer;
begin
pageMargin.x:=0;
pageMargin.y:=0;
myEscape:=GETPRINTINGOFFSET;
if Escape(Printer.Handle,QUERYESCSUPPORT,sizeof(myEscape),@myEscape,nil)>0 then
begin
if Escape(printer.Handle,GETPRINTINGOFFSET,0,nil,@pageMargin)<=0 then
begin
pageMargin.x:=0;
pageMargin.y:=0;
end;
end;
result:=pageMargin;
end;

//2.取得纸张的逻辑宽度--可打印区域
//取得纸张的逻辑尺寸
function TCustomPrinter.PaperLogicSize: TPoint;
var
APoint: TPoint;
begin
APoint.X := Printer.PageWidth;
APoint.Y := Printer.PageHeight;
Result := APoint;
end;

//纸张水平对垂直方向的纵横比例
function TCustomPrinter.HVLogincRatio: Extended;
var
AP: TPoint;
begin
Ap := PaperLogicSize;
Result := Ap.y/Ap.X;
end;

//取得纸张的横向偏移量-单位:点 --打印机的每英寸为多少像素
function TCustomPrinter.GetOffSetX: Integer;
begin
Result := GetDeviceCaps(Printer.Handle, PhysicalOffSetX);
end;

//取得纸张的纵向偏移量-单位:点 --打印机的每英寸为多少像素
function TCustomPrinter.GetOffSetY: Integer;
begin
Result := GetDeviceCaps(Printer.Handle, PhysicalOffSetY);
end;

//毫米单位转换为英寸单位
function TCustomPrinter.MmToInch(Length: Extended): Extended;
begin
Result := round(Length/25.4);
//每毫米水平方向象素
end;

//英寸单位转换为毫米单位
function TCustomPrinter.InchToMm(Length: Extended): Extended;
begin
Result := round(Length*25.4);//每毫米水平方向象素
end;

//取得水平方向每英寸打印机的点数
function TCustomPrinter.HPointsPerInch: Integer;
begin
Result := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
end;

//取得纵向方向每英寸打印机的光栅数
function TCustomPrinter.VPointsPerInch: Integer;
begin
Result := GetDeviceCaps(Printer.Handle, LOGPIXELSY)
end;

//横向点单位转换为毫米单位
function TCustomPrinter.XPointToMm(Pos: Integer): Extended;
begin
Result := Pos*25.4/HPointsPerInch;
end;

//纵向点单位转换为毫米单位
function TCustomPrinter.YPointToMm(Pos: Integer): Extended;
begin
Result := Pos*25.4/VPointsPerInch;
end;

procedure TCustomPrinter.SetPagerSize(const ASize: Integer;
AWidth,
AHeight:do
uble);
var
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port : array[0..255] of char;
hDMode : THandle;
PDMode : PDEVMODE;
paperOrientation: Integer;
begin
//自定义纸张最小高度70mm
if AHeight < 70 then
AHeight := 70;
//自定义纸张最大高度432mm
if AHeight > 500 then
AHeight := 500;
//自定义纸张最小宽度76mm
if AWidth < 76 then
AWidth := 76;
//自定义纸张最大宽度216mm
if AWidth > 300 then
AWidth := 300;
paperOrientation:=1;
{AWidth := 171;
AHeight := 78;}
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
{设定打印的方向为纵向或横向
if PaperOrientation<>0 then
pDMode^.dmOrientation:=DMORIENT_LANDSCAPE
else
pDMode^.dmOrientation:=DMORIENT_PORTRAIT;
//设置拷贝份数为1份.
pDMode^.dmCopies:=1;}
//自定义纸张
pDMode^.dmPaperSize := DMPAPER_USER;
{pDMode^.dmPaperSize:=256;}
//将毫米单位转换为0.1mm单位
pDMode^.dmPaperWidth := round(AWidth * 10);
pDMode^.dmPaperLength := round(Aheight * 10);
pDMode^.dmFields := pDMode^.dmFields or DM_PAPERSIZE or
DM_PAPERWIDTH;
pDMode^.dmFields := pDMode^.dmFields or DM_PAPERLENGTH;
//pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
{pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERSIZE;
pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERWIDTH;
pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERLENGTH;}
//pDMode^.dmDefaultSource := DMBIN_MANUAL;
GlobalUnlock(hDMode);
end;
end;
Printer.PrinterIndex := Printer.PrinterIndex;
end;

procedure TCustomPrinter.InitPrinter(PRatio: Integer=1;APWidth:do
uble=171;
APHeight:do
uble=78;APsize: Integer=256;ADeviceName:string='';
Adefault:string='YES';AOffsetX:Integer=0;AOffsetY:Integer=0);
{在 (Xmm, Ymm)处按指定配置文件信息和字体输出字符串}
var
dName: string;
bDefault:string;//是否使用缺省打印机
offSetX, offSetY: Integer;
pSize: Integer;
pWidth,pHeight:do
uble;
begin
bDefault:=Adefault;
dName:=ADeviceName;
pSize:=APsize;
pWidth:=APWidth;
pHeight:=APHeight;
offSetX:=AOffsetX;
offSetY:=AOffsetY;
pHeight:=pHeight*PRatio;
FiOffsetX:=offSetX;
FiOffsetY:=offSetY;
if CompareText(UpperCase(bDefault),'YES')=0 then
//是否使用缺省打印机
Printer.PrinterIndex:=-1
else
if dName<>'' then
Printer.PrinterIndex:= Printer.Printers.IndexOf(dName);
SetPagerSize(pSize,pWidth,pHeight);
end;

procedure TCustomPrinter.InitPrinter(ConfigIni: string;PRatio: Integer=1);
{在 (Xmm, Ymm)处按指定配置文件信息和字体输出字符串}
var
fN: string;
inif: TIniFile;
dName: string;
bDefault:string;//是否使用缺省打印机
offSetX, offSetY: Integer;
pSize: Integer;
pWidth,pHeight:do
uble;
begin
pSize:=256;
pWidth:=239;
pHeight:=139.7;
offSetX:=0;
offSetY:=0;
fN := ExtractFilePath(Application.ExeName)+'/'+ ConfigIni;
if FileExists(fN) then
begin
inif:= TIniFile.Create(fN);
try
try
dName:=inif.ReadString('Printer','DeviceName','error');
bDefault:=inif.ReadString('Printer','IsUseDefault','Yes');
pSize:=StrToInt(inif.ReadString('Printer','PaperSize','256'));
pWidth:=StrToFloat(inif.ReadString('Printer','PageWidth','20'));
pHeight:=StrToFloat(inif.ReadString('Printer','PageHeight','20'));
offSetX:=StrToInt(inif.ReadString('Printer','OffsetX','0'));
offSetY:=StrToInt(inif.ReadString('Printer','OffsetY','0'));
except
bDefault:='Yes';
pSize:=256;
pWidth:=239;
pHeight:=139.7;
offSetX:=0;
offSetY:=0;
end;
finally
inif.Free;
end;
end;
pHeight:=pHeight*PRatio;
FiOffsetX:=offSetX;
FiOffsetY:=offSetY;
if CompareText(bDefault,'Yes')=0 then
//是否使用缺省打印机
Printer.PrinterIndex:=-1
else
Printer.PrinterIndex:= Printer.Printers.IndexOf(dName);
SetPagerSize(pSize,pWidth,pHeight);
end;

//在 (Xmm, Ymm)处按指定配置文件信息和字体输出字符串
function TCustomPrinter.PrintText(Xmm, Ymm, LineHeight, TextWidth: Extended;
Txt: string;
FontSize: Integer=10;
TextAlignment: Integer=DT_LEFT;
AllowNewLine:Boolean=False): Integer;
var
PrintRect: TRect;
Px,Py: Integer;
lh,tw: Extended;
tmpTxt,prnTxt: string;
begin
Result:=1;
Xmm := Xmm + FiOffSetX;
Ymm := Ymm + FiOffSetY;
Px := Round(Round(Xmm * HPointsPerInch * 10000/25.4) / 10000);
Py := Round(Round(Ymm * VPointsPerInch * 10000/25.4) / 10000);
Py := Py - GetOffSetY;
//因为是绝对坐标, 因此, 不用换算成相对于Y轴坐标
Px := Px + 2 * AvgCharWidth;
tw:= Round(Round(textwidth * HPointsPerInch * 10000/25.4) / 10000);
lh:= Round(Round(LineHeight * VPointsPerInch * 10000/25.4) / 10000);
Printer.Canvas.Font.Name :='宋体';
// Arial'
Printer.Canvas.Font.Size := FontSize;
//Printer.Canvas.Font.Color := clGreen;
PrintRect.Left := Round(px);
PrintRect.Top := Round(py);
PrintRect.Bottom := Round(PrintRect.Top + Lh);
PrintRect.Right := Round(PrintRect.Left +tw);
if (Length(txt)*AvgCharWidth>tw) and AllowNewLine then
begin
tmpTxt:=Txt;
while Length(tmpTxt)*AvgCharWidth>twdo
begin
prnTxt:=string(Copy(WideString(tmpTxt),1,Length(WideString(Copy(tmpTxt,1,Trunc(tw/AvgCharWidth))))-1));
if not Printer.Aborted then
DrawText(Printer.Canvas.Handle,PChar(prnTxt),Length(prnTxt),PrintRect,TextAlignment);
tmpTxt:=' '+Copy(tmpTxt,Length(prnTxt)+1,Length(tmpTxt)-Length(prnTxt));
Py:=PrintRect.Bottom-PrintRect.Top;
PrintRect.Top:= PrintRect.Bottom;
PrintRect.Bottom:= PrintRect.Bottom+py;
Inc(Result);
end;
if not Printer.Aborted then
DrawText(Printer.Canvas.Handle,PChar(tmpTxt),Length(tmpTxt),PrintRect,TextAlignment);
end
else
if not Printer.Aborted then
DrawText(Printer.Canvas.Handle,PChar(Txt),Length(Txt),PrintRect,TextAlignment);
end;

function TCustomPrinter.PrintText(Xmm, Ymm: Extended;
Txt: string;
FontSize: Integer=10;AllowNewLine:Boolean=False):Integer;
var
Px, Py: Integer;
begin
Result:=1;
Xmm := Xmm + FiOffSetX;
Ymm := Ymm + FiOffSetY;
Px := Round(Round(Xmm * HPointsPerInch * 10000/25.4) / 10000);
Py := Round(Round(Ymm * VPointsPerInch * 10000/25.4) / 10000);
Py := Py - GetOffSetY;
//因为是绝对坐标, 因此, 不用换算成相对于Y轴坐标
Px := Px + 2 * AvgCharWidth;
Printer.Canvas.Font.Name := '宋体';
Printer.Canvas.Font.Size := FontSize;
//Printer.Canvas.Font.Color := clGreen;
if not Printer.Aborted then
Printer.Canvas.TextOut(Px, Py, Txt);
end;

Procedure TCustomPrinter.PrintChar(s: PChar);
var
tf: TextFile;
begin

AssignFile(tF, 'LPT1');
Rewrite(tF);
Write(tF,s);
CloseFile(tF);
end;

procedure TCustomPrinter.PrintEllipse(Xmm1, Ymm1, Xmm2, Ymm2: Integer;APenWidth: Integer=2);
var
oldPen: TPen;
Px1, Py1, Px2, Py2 : Integer;
begin
oldPen:=TPen.Create;
OldPen.Assign(Printer.Canvas.Pen);
Xmm1 := Xmm1 + FiOffSetX;
Ymm1 := Ymm1 + FiOffSetY;
Xmm2 := Xmm2 + FiOffSetX;
Ymm2 := Ymm2 + FiOffSetY;
Px1 := Round(Round(Xmm1 * HPointsPerInch * 10000/25.4) / 10000);
Py1 := Round(Round(Ymm1 * VPointsPerInch * 10000/25.4) / 10000);
Py1 := Py1 - GetOffSetY;
//因为是绝对坐标, 因此, 不用换算成相对于Y轴坐标
Px1 := Px1 + 2 * AvgCharWidth;
Px2 := Round(Round(Xmm2 * HPointsPerInch * 10000/25.4) / 10000);
Py2 := Round(Round(Ymm2 * VPointsPerInch * 10000/25.4) / 10000);
Py2 := Py2 - GetOffSetY;
//因为是绝对坐标, 因此, 不用换算成相对于Y轴坐标
Px2 := Px2 + 2 * AvgCharWidth;
// Printer.Canvas.Font.Name := '宋体';
// Printer.Canvas.Font.Size := 10;
// FontSize
Printer.Canvas.Pen.Style := psSolid;
Printer.Canvas.Pen.Width := APenWidth;
if not Printer.Aborted then
Printer.Canvas.Ellipse(Px1,Py1,Px2,Py2);
Printer.Canvas.Pen.Assign(OldPen);
OldPen.Free;
end;

procedure TCustomPrinter.PrintLine(Xmm1, Ymm1, Xmm2, Ymm2: Integer;
ACanvas: TCanvas;
APenWidth: Integer=5);
var
oldPen: TPen;
Px1, Py1, Px2, Py2 : Integer;
begin
oldPen:=TPen.Create;
OldPen.Assign(ACanvas.Pen);
Xmm1 := Xmm1 + FiOffSetX;
Ymm1 := Ymm1 + FiOffSetY;
Xmm2 := Xmm2 + FiOffSetX;
Ymm2 := Ymm2 + FiOffSetY;
Px1 := Round(Round(Xmm1 * HPointsPerInch * 10000/25.4) / 10000);
Py1 := Round(Round(Ymm1 * VPointsPerInch * 10000/25.4) / 10000);
Py1 := Py1 - GetOffSetY;
//因为是绝对坐标, 因此, 不用换算成相对于Y轴坐标
Px1 := Px1 + 2 * AvgCharWidth;
Px2 := Round(Round(Xmm2 * HPointsPerInch * 10000/25.4) / 10000);
Py2 := Round(Round(Ymm2 * VPointsPerInch * 10000/25.4) / 10000);
Py2 := Py2 - GetOffSetY;
//因为是绝对坐标, 因此, 不用换算成相对于Y轴坐标
Px2 := Px2 + 2 * AvgCharWidth;
with ACanvasdo
begin
//Printer.Canvas.Font.Name := '宋体';
//Printer.Canvas.Font.Size := 10;
// FontSize
Pen.Style:= psSolid;
Pen.Width:= APenWidth;
// APenWidth
if not Printer.Aborted then
begin
MoveTo(px1,py1);
LineTo(px2,py2);
end;
Pen.Assign(OldPen);
end;
OldPen.Free;
end;

procedure TCustomPrinter.PrintTableLine(ACanvas: TCanvas;
APenWidth: Integer=5);
var
cv:TCanvas;
begin
cv:=ACanvas;
PrintLine(0,32,170,32,cv,APenWidth);
//行
PrintLine(0,40,170,40,cv,APenWidth);
PrintLine(0,72,170,72,cv,APenWidth);
PrintLine(0,79,170,79,cv,APenWidth);
PrintLine(0,32,0,79,cv,APenWidth);
//列
PrintLine(68,32,68,72,cv,APenWidth);
PrintLine(80,32,80,72,cv,APenWidth);
PrintLine(102,32,102,72,cv,APenWidth);
//PrintLine(111,32,111,72,cv,APenWidth);
//PrintLine(122,32,122,72,cv,APenWidth);
PrintLine(127,32,127,79,cv,APenWidth);
PrintLine(157,32,158,79,cv,APenWidth);
PrintLine(170,32,170,79,cv,APenWidth);
end;
--------------------------------------
如下为如何调用:
procedure TFTL.tlPrintClick(Sender: TObject);
var
cp: TCustomPrinter;
j,iPage: Integer;
sql,totalPage:string;
rkrq: TDateTime;
fsize: Integer;
bhsje,se,hjje,fe,xjbhsje,xjse,xjhjje,xjfe,hjbhsje,hjse,hjhjje,hjfe:do
uble;
begin
inherited;
if oqyCB.Bof and oqyCB.Eof then
Exit;
if oqyCB.State in [dsEdit, dsInsert] then
oqyCB.Post;
sql:='SELECT COUNT(*) FROM GZWZ.TLDMX WHERE TLDXH='+oqyZB.FieldByName('TLDXH').AsString;
QueryOpen(oqyTemp,sql);
totalPage:=IntToStr((oqyTemp.Fields[0].AsInteger+6) div 7);
oqyCB.First;
cp:=TCustomPrinter.Create;
try
fsize:=9;
iPage:=1;
j:=0;
xjbhsje:=0;
xjse:=0;
xjhjje:=0;
cp.InitPrinter('PrintConfig.Ini');
Printer.Title:='进仓单';
Printer.begin
Doc;
while not oqyCB.Eofdo
begin
if j>=7 then
begin
Printer.NewPage;
//打印新页
iPage:=iPage+1;
j:=0;
end;
if j=0 then
begin

rkrq:=oqyZB.FieldByName('RKRQ').AsDateTime;
cp.PrintText(40,22,13,90,'退仓单',16,DT_CENTER);
cp.PrintText(152,19,15,50,oqyZB.FieldByName('DJBH').AsString,12,DT_LEFT);
if rkrq<>0 then
begin
cp.PrintText(9,35,8,10,FormatDateTime('YYYY',rkrq),fsize,DT_LEFT);//年
cp.PrintText(24,35,8,5,FormatDateTime('MM',rkrq),fsize,DT_LEFT);//月
cp.PrintText(33,35,8,5,FormatDateTime('DD',rkrq),fsize,DT_LEFT);//日
end;
cp.PrintText(70,35,8,30,oqyZB.FieldByName('GCMC').AsString,fsize,DT_LEFT);
//
cp.PrintText(128,35,8,45,oqyZB.FieldByName('GCBH').AsString,fsize,DT_LEFT);//
//页脚
cp.PrintText(20,127,8,30,oqyZB.FieldByName('TLR').AsString,9,DT_LEFT);
//领料人
cp.PrintText(75,127,8,30,oqyZB.FieldByName('SHR').AsString,9,DT_LEFT);
//领料人
cp.PrintText(140,127,8,20,oqyZB.FieldByName('RKRXM').AsString,9,DT_LEFT);
//领料人
cp.PrintText(175,127,8,30,'--第'+IntToStr(iPage)+'页 共'+totalPage+'页--',9,DT_RIGHT);
//页码
end;
//打印材料
cp.PrintText(1, 49+j*8,8,35,oqyCB.FieldByName('CLMC').AsString,fsize,DT_LEFT);
cp.PrintText(37, 49+j*8,8,35,oqyCB.FieldByName('CLGG').AsString,fsize,DT_LEFT);
cp.PrintText(72, 49+j*8,8,10,oqyCB.FieldByName('DW').AsString,fsize,DT_LEFT);
cp.PrintText(80,49+j*8,8,22,FormatFloat('#,##0.00',oqyCB.FieldByName('THSL').AsFloat),fsize,DT_RIGHT);
cp.PrintText(102,49+j*8,8,30,FormatFloat('#,##0.000000',oqyCB.FieldByName('BHSJG').AsFloat),fsize,DT_RIGHT);
bhsje:=StrToFloat(FormatFloat('0.00',oqyCB.FieldByName('THJE').AsFloat));
hjje:=StrToFloat(FormatFloat('0.00',oqyCB.FieldByName('HJJE').AsFloat));
se:=StrToFloat(FormatFloat('0.00',oqyCB.FieldByName('BHSJG').AsFloat*
oqyCB.FieldByName('THSL').AsFloat*oqyCB.FieldByName('SL').AsFloat));//税额为三者之差,目的以调平金额。
fe:=hjje-bhsje-se;
if oqyCB.FieldByName('FL').AsFloat=0 then
begin
se:=se+fe;
fe:=0;
end;
cp.PrintText(132,49+j*8,8,18,FormatFloat('#,##0.00',bhsje),fsize,DT_RIGHT);
cp.PrintText(151,49+j*8,8,18,FormatFloat('#,##0.00',hjje-bhsje),fsize,DT_RIGHT);
cp.PrintText(169,49+j*8,8,31,FormatFloat('#,##0.00',hjje),fsize,DT_RIGHT);
xjbhsje:=xjbhsje+bhsje;
xjse:=xjse+se;
xjhjje:=xjhjje+hjje;
xjfe:=xjfe+fe;
hjbhsje:=hjbhsje+bhsje;
hjse:=hjse+se;
hjhjje:=hjhjje+hjje;
hjfe:=hjfe+fe;

j:=j+1;
oqyCB.Next;
//-----打印小计-----
if j=7 then
begin
cp.PrintText(1, 49+7*8,8,35,'小 计',fsize,DT_LEFT);
cp.PrintText(132,49+7*8,8,18,FormatFloat('#,##0.00',xjbhsje),fsize,DT_RIGHT);
cp.PrintText(151,49+7*8,8,18,FormatFloat('#,##0.00',xjhjje-xjbhsje),fsize,DT_RIGHT);
cp.PrintText(169,49+7*8,8,31,FormatFloat('#,##0.00',xjhjje),fsize,DT_RIGHT);
xjbhsje:=0;
xjse:=0;
xjhjje:=0;
if not oqyCB.eof then
cp.PrintText(146,52+8*8,8,30,'合计见后',fsize,DT_RIGHT);
end;
end;

//-----打印小计-----
if j<7 then
begin
cp.PrintText(1, 49+7*8,8,35,'小 计',fsize,DT_LEFT);
cp.PrintText(132,49+7*8,8,18,FormatFloat('#,##0.00',xjbhsje),fsize,DT_RIGHT);
cp.PrintText(151,49+7*8,8,18,FormatFloat('#,##0.00',xjhjje-xjbhsje),fsize,DT_RIGHT);
cp.PrintText(169,49+7*8,8,31,FormatFloat('#,##0.00',xjhjje),fsize,DT_RIGHT);
xjbhsje:=0;
xjse:=0;
xjhjje:=0;
end;

cp.PrintText(14, 52+8*8,8,120,oqyZB.FieldByName('BZ').AsString,fsize,DT_LEFT);
cp.PrintText(146,52+8*8-2,8,23,FormatFloat('税¥'+'#,##0.00',hjse),fsize,DT_RIGHT);//税额
if hjfe<>0 then

cp.PrintText(146,52+8*8+2,8,23,FormatFloat('费¥'+'#,##0.00',hjfe),fsize,DT_RIGHT);//费额
cp.PrintText(169,52+8*8-2,8,31,FormatFloat('成¥'+'#,##0.00',hjbhsje),fsize,DT_RIGHT);//不含税成本额
cp.PrintText(169,52+8*8+2,8,31,FormatFloat('合¥'+'#,##0.00',hjhjje),fsize,DT_RIGHT);//合计金额
Printer.endDoc;
finally
cp.Free;
end;
end;
----------------
其中用到的PrintConfig.Ini在上面的单元中.
 
如何让打印机不自动走纸
如我使用
printer.begin
doc
printer.enddoc
后打印机就会自动前面留1.2cm,后面留1.2cm如何让它不留这些空白?
 
向打印机发送char(27)+char(10)
--------------------以下内容转自网络
http://www.delphibbs.com/delphibbs/dispq.asp?LID=1539718这个帖子应该对你有帮助
v a r
f : Te x t F i l e ;
b e g i n
A s s i g n P r n ( f ) ;
t r y
R e w r i t e ( f ) ;
Wr i t e l n ( f ,char(27)+char(10)) ;
f i n a l l y
C l o s e F i l e ( f ) ;
e n d ;
e n d ;
 
谢谢大家,结贴[:D]!
 
后退
顶部