遇到一个奇葩的需求。一般情况下我们打印单据,用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. LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

    #6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  2. nginx gzip on 无效

    优化页面的时候,使用nginx开启gzip ,发现并没有什么反映~ 在nginx.conf中的配置如下: gzip on; gzip_min_length 1k; gzip_buffers 16k; ...

  3. js 实现获取当前日期/时间/星期

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. Jvm(jdk8)源码分析1-java命令启动流程详解

    JDK8加载源码分析 1.概述 现在大多数互联网公司都是使用java技术体系搭建自己的系统,所以对java开发工程师以及java系统架构师的需求非常的多,虽然普遍的要求都是需要熟悉各种java开发框架 ...

  5. docker 批量操作容器

    docker stop $(sudo docker ps -q)

  6. ajax from 提交

    $.ajax({                 cache: true,                 type: "POST",                 url:aj ...

  7. yii2 控制器渲染

    render() : 渲染一个 视图名并使用一个 布局返回到渲染结果. renderPartial() : 渲染一个 视图名并且不使用布局. renderAjax() : 渲染一个 视图名并且不使用布 ...

  8. Mysql正常启动之后默认使用的文件

    --basedir=/usr/local/mysql  --datadir=/usr/local/mysql/data  --plugin-dir=/usr/local/mysql/lib/plugi ...

  9. MySql Cast与Convert函数

    两者具体的语法如下: Cast(value as type): Convert(value ,type): type不是都可以滴,可以转换的type如下: 二进制,同带binary前缀的效果 : BI ...

  10. es6 字符串方法

    1.字符串的新方法  includes() 包含属性 startsWith() 头部开始是否包含 endWith() 字符串是否在尾部   ========三个返回值都为布尔值  第二参数为数字  e ...