unit MyLib;
interface
uses
classes, Printers, DBGrids, Graphics, Sysutils, Windows, Forms, DB, Grids,
Dialogs, ComObj, Controls,StdCtrls,ShellAPI;
type//打印Tdbgrid
TPrnOut = class(TObject)
procedure PrintHeader(s:string);
procedure PrintFoot(s:string);
procedure PrintLine(x1,y1,x2,y2:integer);
procedure PrintRow(Items:TStringList;rowDBGrid:TDBGrid);
procedure PrintColumns(colDBGrid:TDBGrid);
procedure PrintRecords(recDBGrid:TDBGrid);
procedure PrintPart(MDBG,PDBG:TDBGrid);
procedure SingleDBGPrint(DBgrid:TDBGrid;Header,Footer:string);
procedure DoubleDBGPrint(MainDBG,PartDBG:TDBGrid;Header,Footer:string);
private
{ Private declarations }
strHead,strFoot:string;
iPage:integer;
iWordWidth,iWordHeight:integer; //单位字宽与字高
iAmount:integer;
iPageHeight,iPageWidth:integer; //有效打印区域高度与宽度
PixelsInInchX:integer;
{Number of pixels in 1/10 of an inch.This is used for lin spacing}
TenthsOfInchPixelsY: Integer;
end;
type//打印TstringGrid
TStrGridPrn = class(TObject)
procedure PrintHeader(s:string);
procedure PrintFoot(s:string);
procedure PrintLine(x1,y1,x2,y2:integer);
procedure PrintRow(Items:TStringList;StrGrid:TStringGrid);
procedure PrintColumns(StrGrid:TStringGrid);
procedure PrintRecords(StrGrid:TStringGrid);
procedure StrGridPrint(StrGrid:TStringGrid;Header,Footer:string);
private
{ Private declarations }
strHead,strFoot:string;
iPage:integer;
iWordWidth,iWordHeight:integer; //单位字宽与字高
iAmount:integer;
iPageHeight,iPageWidth:integer; //有效打印区域高度与宽度
PixelsInInchX:integer;
{Number of pixels in 1/10 of an inch.This is used for lin spacing}
TenthsOfInchPixelsY: Integer;
end;
implementation
{TPrnOut}
procedure TPrnOut.PrintHeader(s:string);
begin
{页头打印}
if s='' then s :='<无标题>';
With Printer do
begin
with Canvas.Font do
begin
Size :=12;
Name:='宋体';
end;
if (not Aborted) then
Canvas.TextOut((PageWidth div 2)-(Canvas.TextWidth(s) div 2),0,s);
iAmount :=iAmount+Canvas.TextHeight(s)*2;
end;
end;
procedure TPrnOut.PrintFoot(s:string);
var
str:string;
begin
{页脚打印}
if s='' then str:=s+'第'+IntToStr(iPage)+'页'
else str:= s +' '+'第'+IntToStr(iPage)+'页';
With Printer do
if (not Aborted) then
Canvas.TextOut((PageWidth div 2)-(Canvas.TextWidth(str) div 2),
(iPageHeight-iWordHeight),str);
iAmount :=0;
iPage :=iPage+1;
end;
procedure TPrnOut.PrintLine(x1,y1,x2,y2:integer);
begin
with Printer.Canvas do
begin
MoveTo(x1,y1);
LineTo(x2,y2);
end;
end;
procedure TPrnOut.PrintRow(Items:TStringList;rowDBGrid:TDBGrid);
var
OutRect:TRect;
i:integer;
Inches:Double;
begin
OutRect.Left :=50;
OutRect.Top :=iAmount;
With Printer.Canvas do
begin
for i := 0 to Items.Count -1 do
begin
Inches :=LongInt(Items.Objects[i])*0.1;
OutRect.Right :=OutRect.Left + Round(PixelsInInchx * Inches);
if OutRect.Right>iPageWidth then
begin
{换行打印}
OutRect.Left :=70;
OutRect.Right :=70+OutRect.Left + Round(PixelsInInchx * Inches);
iAmount := iAmount + iWordHeight;
OutRect.Top := iAmount;
end;
{换页}
if (iAmount+iWordHeight)>(iPageHeight-iWordHeight) then
begin
PrintFoot(''); //打印页脚
iAmount :=0;
if not Printer.Aborted then
Printer.NewPage;
PrintHeader('');
PrintColumns(rowDBGrid); //打印列头
OutRect.Left :=70;
OutRect.Right :=70+OutRect.Left + Round(PixelsInInchx * Inches);
iAmount := iAmount + iWordHeight;
OutRect.Top := iAmount;
end;
if not printer.Aborted then
TextRect(OutRect,OutRect.Left,OutRect.Top,Items[i]);
OutRect.Left :=OutRect.Right;
end;
end;
iAmount :=iAmount + iWordHeight+2;
end;
procedure TPrnOut.PrintColumns(colDBGrid:TDBGrid);
var
lst:TStringList;
i:integer;
begin
{打印列标题}
lst :=TStringList.Create;
try
{获取打印机字的大小}
with printer.Canvas do
begin
Font.Style :=[fsBold,fsUnderline];
iWordWidth :=TextWidth('x');
iWordHeight :=TextHeight('x');
end;
for i:=0 to colDBGrid.Columns.Count-1 do
lst.AddObject(colDBGrid.Columns[i].Title.Caption,
Pointer((colDBGrid.Columns[i].Width div 10)+2));
PrintRow(lst,colDBGrid);
Printer.Canvas.Font.Style :=[];
Except
lst.Free;
printer.EndDoc;
end;
end;
procedure TPrnOut.PrintRecords(recDBGrid:TDBGrid);
var
lst:TStringList;
i:integer;
begin
{打印记录}
lst :=TStringList.Create;
try
with recDBGrid.DataSource.DataSet do
begin
First;
While (not Eof) or Printer.Aborted do
begin
Application.ProcessMessages;
for i:=0 to recDBGrid.Columns.Count-1 do
lst.AddObject(recDBGrid.Columns[i].Field.DisplayText,
Pointer((recDBGrid.Columns[i].Width div 10)+2));
PrintRow(lst,recDBGrid); //行打印
lst.Clear;
Next;
end;
end;
finally
lst.Free;
end;
end;
procedure TPrnOut.PrintPart(MDBG,PDBG:TDBGrid);
var
lst:TStringList;
i:integer;
begin
lst :=TStringList.Create;
try
with MDBG.DataSource.DataSet do
begin
First;
While (not Eof) do
begin
Application.ProcessMessages;
for i:=0 to FieldDefs.Count-1 do
lst.AddObject(MDBG.Columns[i].Field.DisplayText,
Pointer((MDBG.Columns[i].Width div 10)+2));
PrintRow(lst,MDBG); //行打印
lst.Clear;
PrintColumns(PDBG);
PrintRecords(PDBG);
Next;
end;
end;
finally
lst.Free;
end;
end;
procedure TPrnOut.SingleDBGPrint(DBGrid:TDBGrid;
Header,Footer:string);
begin
screen.Cursor :=crHourglass;
strHead :=Header;
strFoot :=Footer;
iPage :=1;
{单表打印}
try
with Printer do
begin
PixelsInInchX :=GetDeviceCaps(Handle,LOGPIXELSX);
TenthsOfInchPixelsY :=GetDeviceCaps(Printer.Handle,LOGPIXELSY) div 10;
iPageHeight :=PageHeight;
iPageWidth :=PageWidth; //减去左右边距
Canvas.Font.Size :=11;
BeginDoc;
end;
{打印页头}
PrintHeader(Header);
{打印标题栏:粗体,下划线}
PrintColumns(DBGrid);
{循环打印记录}
PrintRecords(DBGrid);
{打印页脚:页码}
PrintFoot(Footer);
finally
printer.EndDoc;
screen.Cursor :=crDefault;
end;
end;
procedure TPrnOut.DoubleDBGPrint(MainDBG,PartDBG:TDBGrid;
Header,Footer:string);
begin
screen.Cursor :=crHourglass;
iPage :=1;
{明细表打印}
try
with Printer do
begin
PixelsInInchX :=GetDeviceCaps(Handle,LOGPIXELSX);
TenthsOfInchPixelsY :=GetDeviceCaps(Printer.Handle,LOGPIXELSY) div 10;
iPageHeight :=PageHeight;
iPageWidth :=PageWidth; //减去左右边距
Canvas.Font.Size :=11;
BeginDoc;
end;
{打印页头}
PrintHeader(Header);
{打印标题栏:粗体,下划线}
PrintColumns(MainDBG);
{循环打印记录}
PrintPart(MainDBG,PartDBG);
{打印页脚:页码}
PrintFoot(Footer);
{新页起始:重复上面工作}
finally
printer.EndDoc;
screen.Cursor :=crDefault;
end;
end;
{TStrGridPrn}
procedure TStrGridPrn.PrintHeader(s:string);
begin
{页头打印}
if s='' then s :='<无标题>';
With Printer do
begin
with Canvas.Font do
begin
Size :=12;
Name:='宋体';
end;
if (not Aborted) then
Canvas.TextOut((PageWidth div 2)-(Canvas.TextWidth(s) div 2),0,s);
iAmount :=iAmount+Canvas.TextHeight(s)*2;
end;
end;
procedure TStrGridPrn.PrintFoot(s:string);
var
str:string;
begin
{页脚打印}
if s='' then str:=s+'第'+IntToStr(iPage)+'页'
else str:= s +' '+'第'+IntToStr(iPage)+'页';
With Printer do
if (not Aborted) then
Canvas.TextOut((PageWidth div 2)-(Canvas.TextWidth(str) div 2),
(iPageHeight-iWordHeight),str);
iAmount :=0;
iPage :=iPage+1;
end;
procedure TStrGridPrn.PrintLine(x1,y1,x2,y2:integer);
begin
with Printer.Canvas do
begin
MoveTo(x1,y1);
LineTo(x2,y2);
end;
end;
procedure TStrGridPrn.PrintRow(Items:TStringList;StrGrid:TStringGrid);
var
OutRect:TRect;
i:integer;
Inches:Double;
begin
OutRect.Left :=50;
OutRect.Top :=iAmount;
With Printer.Canvas do
begin
for i := 0 to Items.Count -1 do
begin
Inches :=LongInt(Items.Objects[i])*0.1;
OutRect.Right :=OutRect.Left + Round(PixelsInInchx * Inches);
if OutRect.Right>iPageWidth then
begin
{换行打印}
OutRect.Left :=70;
OutRect.Right :=70+OutRect.Left + Round(PixelsInInchx * Inches);
iAmount := iAmount + iWordHeight;
OutRect.Top := iAmount;
end;
{换页}
if (iAmount+iWordHeight)>(iPageHeight-iWordHeight) then
begin
PrintFoot(''); //打印页脚
iAmount :=0;
if not Printer.Aborted then
Printer.NewPage;
PrintHeader('');
PrintColumns(StrGrid); //打印列头
OutRect.Left :=70;
OutRect.Right :=70+OutRect.Left + Round(PixelsInInchx * Inches);
iAmount := iAmount + iWordHeight;
OutRect.Top := iAmount;
end;
if not printer.Aborted then
TextRect(OutRect,OutRect.Left,OutRect.Top,Items[i]);
OutRect.Left :=OutRect.Right;
end;
end;
iAmount :=iAmount + iWordHeight+2;
end;
procedure TStrGridPrn.PrintColumns(StrGrid:TStringGrid);
var
lst:TStringList;
i:integer;
begin
{打印列标题}
lst :=TStringList.Create;
try
{获取打印机字的大小}
with printer.Canvas do
begin
Font.Style :=[fsBold,fsUnderline];
iWordWidth :=TextWidth('x');
iWordHeight :=TextHeight('x');
end;
for i:=0 to StrGrid.ColCount-1 do
lst.AddObject(StrGrid.Cells[i,0],
Pointer((StrGrid.ColWidths[i] div 10)+2));
PrintRow(lst,StrGrid);
Printer.Canvas.Font.Style :=[];
Except
lst.Free;
printer.EndDoc;
end;
end;
procedure TStrGridPrn.PrintRecords(StrGrid:TStringGrid);
var
lst:TStringList;
i,iRow:integer;
begin
{打印记录}
lst :=TStringList.Create;
try
for iRow :=1 to StrGrid.RowCount-1 do
begin
Application.ProcessMessages;
for i:=0 to StrGrid.ColCount-1 do
lst.AddObject(StrGrid.Cells[i,iRow],
Pointer((StrGrid.ColWidths[i] div 10)+2));
PrintRow(lst,StrGrid); //行打印
lst.Clear;
end;
finally
lst.Free;
end;
end;
procedure TStrGridPrn.StrGridPrint(StrGrid:TStringGrid;
Header,Footer:string);
begin
screen.Cursor :=crHourglass;
strHead :=Header;
strFoot :=Footer;
iPage :=1;
{单表打印}
try
with Printer do
begin
PixelsInInchX :=GetDeviceCaps(Handle,LOGPIXELSX);
TenthsOfInchPixelsY :=GetDeviceCaps(Printer.Handle,LOGPIXELSY) div 10;
iPageHeight :=PageHeight;
iPageWidth :=PageWidth; //减去左右边距
Canvas.Font.Size :=11;
BeginDoc;
end;
{打印页头}
PrintHeader(Header);
{打印标题栏:粗体,下划线}
PrintColumns(StrGrid);
{循环打印记录}
PrintRecords(StrGrid);
{打印页脚:页码}
PrintFoot(Footer);
finally
printer.EndDoc;
screen.Cursor :=crDefault;
end;
end;
end.