遇到一个奇葩的需求。一般情况下我们打印单据,用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. 爬取掌阅app免费电子书数据

    主要介绍如何抓取app数据及抓包工具的使用,能看到这相信你已经有爬虫基础了 编不下去了,主要是我懒,直接开干吧! 一.使用环境和工具 windows + python3 + Jsonpath + Ch ...

  2. Java的OOP三大特征之一——封装

    面向对象三大特征之一 封装  继承  多态   封装性就是把类(对象)的属性和行为结合成一个独立的相同单位,并尽可能隐蔽类(对象)的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系. ...

  3. 如何让网站在百度有LOGO展示

    什么叫没有了网站logo?准确来说应该是网站索引logo,这个logo确实网站很好的一个展示窗口,我以长沙seo关键词为例,我给大家举例! 我输入长沙SEO,出来的百度索引图,原本所有我标红的框子里都 ...

  4. 看看用PS来转基因的动物,居然很欢乐!!

    出于礼貌,我先笑一下,哈哈哈哈哈哈!好了,开始.Gyyporama是挪威的一名程序员,他无聊的时候会从网上找来一些动物的图片,把他们的头和身体进行混合,生成另一种奇怪的动物.然后邀请其他网友过来给他们 ...

  5. linux内socket服务器无法连接windows

    今天在试socket的时候出现了一个问题:问题概述是这样的: 1.linux采用centOS7(mini)版本,虚拟机版本VMware12,网卡设置NAT 2.服务器和客户端都在windows上,通讯 ...

  6. sqli-labs:24,二次注入

    二次排序注入 二次排序注入也称为存储型注入,就是将可能导致 sql 注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以出发 sql 注入. 二次排序注入思路: 1. 黑客通过构造数据的 ...

  7. Best Sightseeing Pair LT1014

    Given an array A of positive integers, A[i] represents the value of the i-th sightseeing spot, and t ...

  8. Continuous Subarray Sum LT523

    Given a list of non-negative numbers and a target integer k, write a function to check if the array ...

  9. echart 3 数据密集时,断点不显示问题

    如上图最开始标识的两点是不显示的,配置处理代码如下(series中配置symbolSize: 1,showAllSymbol: true): myChart.showLoading(); $.get( ...

  10. kbmmw 的HTTPSmartService入门

    前面介绍过kbmmw 中的smartservice. 这个既可以用于kbmmw 的客户端,也可以使用http 访问. 在新版的kbmmw里面,作者加强了http 的支持,我们可以只使用HTTPSmar ...