遇到一个奇葩的需求。一般情况下我们打印单据,用FastReport设置打印格式,也就是就设一个模版页而己,就是一种单据格式。如果打印的单据数据多了就自动打印多页了,他们的格式是一样的。也就是读同一个模版页。

现的需求是,如果打印N页内容。每一页的格式除了表体外是一样的(也可能部份不同)。而表体取自不同的数据集(也就是读取不同的FDQuery),需要设置不同的表体格式(表体列的数量,列的名称)。

在各大论坛中找不到现成解决方案。经网友提示,FastReport的打印模版设置好了其实就是一个XML文件。所以我们只需要读取这个XML,然后取出Page部份,复制成N份,根据需求修改不同部份的内容,然后再写入这个打印模版就可以了。开发中发现Delphi里读取XML文件的控件是不少,但是都有或多或少的问题,导制不适用于这个方案,最终我选择了FastReport里自带的FrxXML。功能虽少,但是够用了。

以下分享的是Page页的复制的实现代码,修改内容部份根据实际需求自行编写。至于如何修改,可以参照以下代码。

与网友的交流中,有网友不明白我的需求,最终说我语文小学没毕业,表达不清楚。其实我虽然语文小学有毕业,但也是离毕业的不远

unit frxHelp;

interface

 uses frxClass,frxXML,System.SysUtils,Vcl.Dialogs;
type
TChangeProp=reference to procedure (aXML:TfrxXMLItem); ///*******************根据FastReport设置好的打印模版(ReportPage)生成多页
///
//procedure TForm1.FormCreate(Sender: TObject);
//
//const
// frxFile='G:\delphi\delphi\企业通ERP\DOERP\BIN\fr3\销售明细打印.fr3';
//var
// cStream:TStream;
// I:integer;
// frXML:TfrxXMLDocument;
// frXItem:TfrxXMLItem;
// fdoprop:TChangeProp;
//begin
// I:=0;
// fdoprop:= procedure (aXML:TfrxXMLItem)
// begin
// if aXML.PropExists('DataSet') then
// ShowMessage(aXML.Prop['DataSet']);
// end;
// IF GetFrxpageTemple(frxFile,frXML,frXItem) then
// IF CopyfrxPage(frXML,frXItem,I,'Page3',fdoProp) then
// begin
// cStream:=TMemoryStream.Create;
// frXML.SaveToStream(cStream);
// cStream.Position:=0;
// frxReport1.LoadFromStream(cStream);
// frxReport1.DesignReport();
// end;
//end;
procedure changeProp(aXML:TfrxXMLItem;iXML:Integer;Prop:TChangeProp=nil);
procedure CopyXML(S,D:TfrxXMLItem);
function CopyfrxPage(fXMLDoc:TfrxXMLDocument;sPageItem:TfrxXMLItem;ID:integer;cPname:String;Prop:TChangeProp=nil):Boolean;
function GetFrxpageTemple(cFile:String;out fXMLDoc:TfrxXMLDocument;out PageItem:TfrxXMLItem):Boolean;
implementation
procedure CopyXML(S,D:TfrxXMLItem);
var
I:Integer;
a,b:TfrxXMLItem;
begin
for I := to S.Count- do
begin
a:=s.Items[i];
b:=d.Add;
b.Name:=a.Name;
b.Text:=a.Text;
if a.Count> then
CopyXML(a,b); end;
end;
procedure changeProp(aXML:TfrxXMLItem;iXML:Integer;Prop:TChangeProp);
var
I:Integer;
fXML:TfrxXMLItem;
begin
for I := to aXML.Count- do
begin
fXML:=aXML.Items[I];
//Name属性是必须改的,为避免没有传入属性修改 方法(Prop:TChange)默认强制修改Name
if fXML.PropExists('Name') then
fXML.Prop['Name']:=fXML.Prop['Name']+'N'+iXML.toString;
if Assigned(Prop) then
Prop(aXML);
if fXML.Count> then
changeProp(fxML,iXML,Prop);
Inc(iXml);
end;
end;
function GetFrxpageTemple(cFile:String;out fXMLDoc:TfrxXMLDocument;out PageItem:TfrxXMLItem):Boolean;
begin
if Not FileExists(cFile) then
begin
ShowMessagefmt('打印模版[%s]不存在!!',[cFile]);
Exit(False);
end;
try
fXMLDoc:=TfrxXMLDocument.Create;
fXMLDoc.LoadFromFile(cFile);
PageItem:=TfrxXMLItem.Create;
PageItem:=fXMLDoc.Root.FindItem('TfrxReportPage');
except
on E:Exception do
begin
ShowMessage(E.Message);
Exit(false);
end;
end;
Result:=True;
end;
function CopyfrxPage(fXMLDoc:TfrxXMLDocument;sPageItem:TfrxXMLItem;ID:integer;cPname:String;Prop:TChangeProp):Boolean;
var
fFrxItem:TfrxXMLItem;
begin
try
fFrXItem:=fXMLDoc.Root.Add;
fFrxItem.Name:='TfrxReportPage';
fFrxItem.Text:=sPageItem.Text;
fFrxItem.Prop['Name']:=cPname;
CopyXML(spageItem,fFrxItem);
ChangeProp(fFrxItem,ID,Prop);
except
on E:Exception do
begin
ShowMessage(E.Message);
Exit(false);
end;
end;
result:=True;
end; end.

FastReport 打印模版页(TFrxReportpage)复制的更多相关文章

  1. LODOP批量打印多页模版进行维护

    批量打印的时候,可以循环多任务,也可以循环多页,很多的时候也可以分页分任务,分组打印.如果是一个任务里的多页相同的模版,一个任务中会有很多打印项,这些打印项在每页中的位置是相同的,如果要调整,调整结果 ...

  2. SharePoint 创建模版页

    [1]需要安装SharePoint Designer  最新版编辑工具 [2]我用的是SharePoint Server 2013 如果是Office 请匹配寻找 1.创建母版页面 打开右上角-网站设 ...

  3. 关于JavaScript打印去掉页眉页脚

    因为这个问题,Google和百度都查了个遍,网上主要解决方案都是这一个代码: <script language="JavaScript"> var hkey_root, ...

  4. C# 打印多页tif

    注意点: 1.计算image对象总页数 image.GetFrameCount(FrameDimension.Page); 2.初始化当前页,并获取指定页内容 image.SelectActiveFr ...

  5. IE浏览器打印的页眉页脚设置解决方法

    首先说明问题: 默认情况下,通过IE的打印对话框,打印出来的内容都有页眉和页脚的. 查看ie的页面设置发现如右图中,页眉页脚 下面先说明&w&bPage&p of &P ...

  6. Excel设置excel打印每页都有表头标题

    Excel设置excel打印每页都有表头标题

  7. 【转】C#使用PrintDocument打印 多页 打印预览

    PrintDocument实例所有的订阅事件如下: 创建一个PrintDocument的实例.如下: System.Drawing.Printing.PrintDocument docToPrint ...

  8. C#使用PrintDocument打印 多页 打印预览

    PrintDocument实例所有的订阅事件如下: 创建一个PrintDocument的实例.如下: System.Drawing.Printing.PrintDocument docToPrint ...

  9. [办公应用]如何打印较小边距的PPT讲义(或者每页打印16页)

    关键词:打印 PPT 讲义 4张 边距   今天同事问我如何打印PowerPoint的讲义.她自己使用PowerPoint打印讲义,设置每页4张,但是页边距太大:觉得浪费很大. 经过网上查阅后,现将方 ...

随机推荐

  1. Homestead 修改 Homestead.yaml 文件后 vagrant up 报错的问题

    一般情况是 TAB 和空格的问题. 虽然表面看来,缩进是一致的. 但是 TAB 没能替换为空格,从而导致问题. 解决: $ sudo vim /etc/vim/vimrc.local syntax o ...

  2. XXE总结

    0x00 目录 0x01 XML基础 定义:一种标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. XML文档结构包括XML声明.D ...

  3. apicloud模块开发知识点

    1. 没有加模块的时候dex里面的包 \android\support\annotation \android\support\v4 \com\uzmap\pkg \compile 2. 不能混淆的类 ...

  4. Bing Developer Assistant开发随记

    Thumb很适合用来做拖动效果的,不会让鼠标轻易跑掉. Combo中的选项是当字符串输入并激发事件后自动加入的,可使用IVsUIShell.SetMRUComboText(GuidList.guidO ...

  5. ListView动态改变每一项的高度。

    ListView中每一项的高度默认是相同的,除非超过其预定高度值,否则需要动点手脚. VariableSizedListView 继承 ListView然后重写protected override v ...

  6. Sharing Code Between Silverlight and WPF

    一个很好的列子: http://www.codeproject.com/Articles/254506/XAMLFinance-A-Cross-platform-WPF-Silverlight-WP7 ...

  7. 数组方法splice

    删除功能: 语法:arrayObject.splice(index,count) 功能:删除从index处开始的零个或多个元素. 返回值:含有被删除的元素的数组 说明:count是要删除的项目数量,如 ...

  8. MySQL open_files_limit相关设置

    背景:      数据库链接不上,报错: root@localhost:/var/log/mysql# mysql -uzjy -p -h192.168.1.111 --default-charact ...

  9. CollisionFlags

    CollisionFlags是CharactorController的返回值,表示碰撞的信息 Values: None Sides Above Below function Update () { v ...

  10. kbmmw 中简单返回 extjs 数据JSON

    以前,我们通过自己写json 来返回数据表的内容.在delphi 10.2.2中,官方自带了一个FDBatchMoveJSONWriter1 来直接处理数据库内容.把结果推送到浏览器客户端. 今天我们 ...