在多年的程序开发中一直使用dbgridEh这个轻量级的表格组件,但对它本身所提供的打印功能却不太满意,这之前程序中的报表打印一直在用Fastreport。
近来一个新的程序中,客户要求对表格的内容进行直接打印(即所见所得)。本来想直接修改dbgrideh中的打印代码,以满足要求,但看过一遍代码之后就放弃这想法了:dbgrideh的打印代码实在不敢恭维,如果实在要修改,后期的维护工作不敢保证。虽然Fastreport也能动态打印dbgrideh,但毕竟也是用程序生成模板,灵活性有所欠缺。后来想到了Devexpress中的Expressprinting组件,这是一个很专业的打印组件,只是它本身没有提供dbgrideh的link,之前也不知如何写新的link,也就没有使用过。
Expressprinting本身提供了stringGrid的link,stringgrid继承自Tcustomgrid,而Dbgrideh也是继承自TcustomGrid,如果要为dbgrideh写一个link,与stringgrid的link应该有异曲同工之处。打开TStddxGridReportLink的代码,果不然,它的父类TCustomdxGridReportLink就是专门针对TcustomGrid的打印而写的。阅读TCustomdxGridReportLink的代码,发现它是针对像StringGrid这样的静态表格而写的,而DbgridEh是基于dataset的动态表格,在处理上还是稍有不同。TCustomdxGridReportLink的上级是TAbstractdxGridReportLink,从名称可以就可以知道这是专门为表格而写的一个link(devexpress 的spreadsheet的打印link也是基于TAbstractdxGridReportLink)。于是决定DbgridEh也继承自TAbstractdxGridReportLink,要继承的方法:
function GetColCount: Integer; override;
function GetFixedColCount: Integer; override;
function GetFixedRowCount: Integer; override;
function GetRowCount: Integer; override;
function GetCellFont(ACol, ARow: Integer): TFont;override;
function GetCellText(ACol, ARow: Integer): string; override;
function GetSourceColWidth(ACol: Integer): Integer; override;
function GetSourceRowHeight(ARow: Integer): Integer; override;
function IsDrawBorder: Boolean; override;
function IsDrawFixedHorzLines: Boolean; override;
function IsDrawFixedVertLines: Boolean; override;
function IsDrawHorzLines: Boolean; override;
function IsDrawVertLines: Boolean; override;
procedure ConstructReport(AReportCells: TdxReportCells); override;
public
property DBGrid: TDBGridEH read GetDBGrid;//需要打印的DBGrideh组件
GetCellText是取单元格内容的过程,TCustomdxGridReportLink是通过col,row坐标值来取某一单元格内容,在Dbgrideh是没办法这样取某一行、某一字段的值,经过查阅delphi的帮助,Dataset的RecNO是可以用row来定位的,GetCellText的实现如下:
function TDbGridEhReportLink.GetCellText(ACol, ARow: Integer): string;
begin
if IsFixedCell(ACol, ARow) then
begin
result:=DBGrid.Columns[ACol].Title.Caption;
end else
begin
DBGrid.DataSource.DataSet.RecNo:=ARow;
Result:=DBGrid.DataSource.DataSet.fieldbyname(DBGrid.Columns[ACol].FieldName).AsString;
end;
end;
GetRowCount是取表格所有的行,相对于DbGrideh而言,应该是记录集的Recordcount,再加上标题行,实现如下:
function TDbGridEhReportLink.GetRowCount: Integer;
begin
Result:=DBGrid.DataSource.DataSet.RecordCount+1;
end;
GetFixedRowCount是取表格的固定行数,Dbgrideh的固定行,就是标题行了:
function TDbGridEhReportLink.GetFixedRowCount: Integer;
begin
Result:=1;
end;
ConstructReport是Expressprintint组件一个很重要的过程,从字面就应该知道它的作用了。具体怎么构造一个表格的打印,TAbstractdxGridReportLink已经帮我们实现了,我们只需在ConstructReport过程中写下面这几行代码,Dbgrideh的打印程序就算完成了。
if DBGrid=nil then Exit;
try
Font:=DBGrid.Font;
FixedFont:=DBGrid.TitleFont;
DBGrid.DataSource.DataSet.DisableControls;
inherited;
finally
DBGrid.DataSource.DataSet.EnableControls;
end
用Expressprinting来打印DBGridEh,相对于修改Dbgrideh本身的打印代码,从工作量上来看,是够省事了吧?而且,从扩展性上来看,Expressprinting更强得多。