zoukankan      html  css  js  c++  java
  • Tprinter打印任何表格控件

    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.

  • 相关阅读:
    删除当前目录下除了system目录的其他文件
    单例设计模式
    系统工程师
    字符串翻转
    教育
    得到b相对于a的路径
    一段处理事务的代码
    搭讪
    win 8 ,vs2011 编程环境下,动软生成器无法连接上 sql server 2008 r2
    从asp网站编程转行到asp.net网站编程的过程
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940793.html
Copyright © 2011-2022 走看看