使用FastReport.net在用户的应用程序中创建报表

FastReport .Net是一款强大且应用十分广泛的报表工具,我最喜欢的特点之一是它直接从用户应用程序中创建报表的能力。在这篇文章中,我们来看看这个功能的例子,当你不需要一堆的.exe文件的时候它就能派上用场了。此外,你可以根据应用逻辑来完全掌控self-report的创建、改变报表对象的外观。

首先,我将展示从用户应用程序的代码中构建报表和在特殊设计器中报表模板经典开发的区别。
通常情况下,报表生成器提供了一个特殊的设计器来设计报表模板。这可能是IDE的组件或仅仅是外部程序。开发人员将组件放在报表的页上,并指定它们的属性,这类似于在窗体应用程序中设计表单。
除了这些经典的方法来创建一个报表模板外,FastReport允许你在应用程序代码的帮助下使用相同的组件来创建模板,你同样能够创建报表对象并添加组件以及配置数据源。实践表明,从代码中创建报表比在可视化设计器中时间会稍稍长一点,但有趣的是,这样得到的报表模板可以在同一个可视化编辑器(设计器)中查看并保存到文件中。


让我们来看看例子。
用C#语言创建Windows窗体应用程序(当然你应该先安装FastReport .Net),在表单上放置一个按钮来启动报表。接下来,我要说的是,我们不仅仅要在预览模式下展示报表,还要让它导出到PDF文件。因此添加复选框:


创建一个按钮单击事件处理程序,这里是整个应用程序的代码。
首先,添加应用到FastReport.dll(在FastReport .Net包中)。
同样,添加FastReport库、 FastReport.Utils以及FastReport.Data。


创建报表示例:

private void RunBtn_Click(object sender, EventArgs e)
 {
 //Create instance of class Report
 Report report = new Report();
 }


我们的报表将从数据库中展示数据,因此需要创建数据源:

//load data
DataSet ds = new DataSet();
ds.ReadXml(AppFolder + "\\nwind.xml");

现在需要在报表中注册数据源:

//Register data source
report.RegisterData(ds);

要使用已注册的数据源表,你需要给它授权:

//Enable data table
report.GetDataSource("Products").Enabled = true;

筹备工作做好了,现在转移到报表模板的创建上来,创建报表页面:

//Add report page
ReportPage page = new ReportPage();

并将其添加到报表中:

report.Pages.Add(page);

报表的所有对象都需要有一个特定的名称,你可以用他们自带的并指定属性名称,或者你可以使用一个函数生成一个唯一的名称:

page.CreateUniqueName();

准备填充报表页面。创建一个“Group Header”带(band):

//Create GroupHeader band
GroupHeaderBand group = new GroupHeaderBand();

并将带添加到页面:

page.Bands.Add(group);
group.CreateUniqueName();

设置带的高度:

group.Height = Units.Centimeters * 1;

分组条件和排序顺序:

group.Condition = "[Products.ProductName].Substring(0,1)";
group.SortOrder = FastReport.SortOrder.Ascending;

现在用数据填充带。要做到这一点,从数据源创建一个文本对象以引用该字段:

// create group text
TextObject groupTxt = new TextObject();

重要的父参数指示该带,放置文本对象:

groupTxt.Parent = group;
groupTxt.CreateUniqueName();

设置文本对象的大小和范围:

groupTxt.Bounds = new RectangleF(0, 0, Units.Centimeters * 10, Units.Centimeters * 1);

设置文本大小和范围:

groupTxt.Font = new Font("Arial", 14, FontStyle.Bold);

其他设置视文本的外观而定:

groupTxt.Text = "[[Products.ProductName].Substring(0,1)]";
groupTxt.VertAlign = VertAlign.Center;
groupTxt.Fill = new LinearGradientFill(Color.LightGoldenrodYellow, Color.Gold, 90, 0.5f, 1);

现在最有趣的部分是创建带“数据”:

// create data band
DataBand data = new DataBand();

为该组分配数据带:

group.Data = data;
data.CreateUniqueName();

为带“数据”指定数据源:

data.DataSource = report.GetDataSource("Products");
data.Height = Units.Centimeters * 0.5f;

在这里你可以通过属性过滤器设置过滤器带。现在用文本对象填充带:

// create product name text
TextObject productText = new TextObject();
productText.Parent = data;
productText.CreateUniqueName();
productText.Bounds = new RectangleF(0, 0, Units.Centimeters * 10, Units.Centimeters * 0.5f);
productText.Text = "[Products.ProductName]";

组页脚最适宜特定的分组实例,即使有多个组头也不会混淆。创建组页脚:

// create group footer
 group.GroupFooter = new GroupFooterBand();
 group.GroupFooter.CreateUniqueName();
 group.GroupFooter.Height = Units.Centimeters * 1;

向组页脚中添加总数,它将显示该组的产品计数:

// create total
Total groupTotal = new Total();
groupTotal.Name = "TotalRows";

设置类型计算,计算所用的带,以及显示结果的带,因为我们定义了项目的数量就不需要指定特定字段来计算(使用groupTotal.Expression)。

groupTotal.TotalType = TotalType.Count;
 groupTotal.Evaluator = data;
 groupTotal.PrintOn = group.GroupFooter;

我们需要在报表汇总字典中添加总计的总数。注册:

report.Dictionary.Totals.Add(groupTotal);

像任何表达式展示那样,结果会通过文本对象展示:

// show total in the group footer
 TextObject totalText = new TextObject();
 totalText.Parent = group.GroupFooter;
 totalText.CreateUniqueName();
 totalText.Bounds = new RectangleF(0, 0, Units.Centimeters * 10, Units.Centimeters * 0.5f);
 totalText.Text = "Rows: [TotalRows]";
 totalText.HorzAlign = HorzAlign.Right;
 totalText.Border.Lines = BorderLines.Top;

报表准备好了,现在我们可以显示它或者在设计器里面运行,并且你可以立即将其导出以自己想要的数据格式。让我们用一个复选框,添加到窗体:

if (PDFCheckBox.Checked)
 {
 report.Prepare();
 FastReport.Export.Pdf.PDFExport export = new FastReport.Export.Pdf.PDFExport();
 export.Export(report);
 }
 else
 report.Show();

如果复选框被选中,你会获得对话框保存的PDF文件,反之,该报表将在预览模式下运行。这里值得注意的是,即使不显示对话框,也可以进行导出,像某种“安静模式”。导出会像这样:

export.Export(report, @"C:\Temp\ReportFromCode.pdf");

第一选项-报表示例以及第二选项-结果文件。

我们得到的结果:

//Create instance of class Report
Report report = new Report();
 
//load data
DataSet ds = new DataSet();
ds.ReadXml(AppFolder + "\\nwind.xml");
 
//Register data source
report.RegisterData(ds);
 
//Enable data table
report.GetDataSource("Products").Enabled = true;
 
//Add report page
ReportPage page = new ReportPage();
report.Pages.Add(page);
page.CreateUniqueName();
 
//Create GroupHeader band
GroupHeaderBand group = new GroupHeaderBand();
page.Bands.Add(group);
group.CreateUniqueName();
group.Height = Units.Centimeters * 1;
group.Condition = "[Products.ProductName].Substring(0,1)";
group.SortOrder = FastReport.SortOrder.Ascending;
 
// create group text
TextObject groupTxt = new TextObject();
groupTxt.Parent = group;
groupTxt.CreateUniqueName();
groupTxt.Bounds = new RectangleF(0, 0, Units.Centimeters * 10, Units.Centimeters * 1);
 
groupTxt.Text = "[[Products.ProductName].Substring(0,1)]";
groupTxt.Font = new Font("Arial", 14, FontStyle.Bold);
groupTxt.VertAlign = VertAlign.Center;
groupTxt.Fill = new LinearGradientFill(Color.LightGoldenrodYellow, Color.Gold, 90, 0.5f, 1);
 
// create data band
DataBand data = new DataBand();
group.Data = data;
data.CreateUniqueName();
data.DataSource = report.GetDataSource("Products");
data.Height = Units.Centimeters * 0.5f;
 
// create product name text
TextObject productText = new TextObject();
productText.Parent = data;
productText.CreateUniqueName();
productText.Bounds = new RectangleF(0, 0, Units.Centimeters * 10, Units.Centimeters * 0.5f);
productText.Text = "[Products.ProductName]";
 
// create group footer
group.GroupFooter = new GroupFooterBand();
group.GroupFooter.CreateUniqueName();
group.GroupFooter.Height = Units.Centimeters * 1;
 
// create total
Total groupTotal = new Total();
groupTotal.Name = "TotalRows";
groupTotal.TotalType = TotalType.Count;
groupTotal.Evaluator = data;
groupTotal.PrintOn = group.GroupFooter;
report.Dictionary.Totals.Add(groupTotal);
 
// show total in the group footer
TextObject totalText = new TextObject();
totalText.Parent = group.GroupFooter;
totalText.CreateUniqueName();
totalText.Bounds = new RectangleF(0, 0, Units.Centimeters * 10, Units.Centimeters * 0.5f);
totalText.Text = "Rows: [TotalRows]";
totalText.HorzAlign = HorzAlign.Right;
totalText.Border.Lines = BorderLines.Top;
 
if (PDFCheckBox.Checked)
{
report.Prepare();
FastReport.Export.Pdf.PDFExport export = new FastReport.Export.Pdf.PDFExport();
export.Export(report);
//export.Export(report, @"C:\Temp\ReportFromCode.pdf");
}
else
report.Show();

报表本身:


总结一下,从代码中创建报表是FastReport .Net的又一令人惊讶的功能。什么时候有用呢?如果你不想产生一堆个人文件的报告模板或要在应用程序内隐藏一个报告模板,以避免损坏或修改模板。同样的它在应用程序的执行过程中更改报表模板也非常方便,这赋予了报表很大的灵活性以及使用单个模板的能力、根据程序逻辑修改它的能力。

希望此功能也可以为大家带来便利,提升工作效率。

这个指南让你熟悉报表设计器和了解报表设计的基本概念(各种区域,数据源,二次表,等等)。指南将帮助你开始用FastReport创建报表,但它不能告诉你怎样使用其它基本的报表设计器。 如果你不熟悉报表设计器,我们建议你参考QuickReport的帮助系统。QuickReport的指南已经包含在你的Delphi拷贝。QuickReport的大部分基本概念也适用于FastReport,然而,FastReport能提供更多的弹性和最终用户的自定义。 关于FastReport的说明 FastReport是高弹性的报表设计器,用于报表的数据可以从任何类型的数据源获取,包含字符列表,BDE数据库,ADO数据源(不使用BDE),Interbase(使用IBO),Pascal数组和记录,以及一些不常用的数据源。 整个FastReport系统是用Delphi的Pascal编写的。FastReport不需要动态链接库,但需在你的项目占用大约400kb(Delphi 5)。如果你想最终用户拥有设计能力,这将在你的.EXE增加大约500kb。虽然这看上去比较大,但这只是其它设计的几分之一。你同样应该考虑到FastReport不仅仅只是包含最终用户更改报表设计的能力,还能够适应查询和数据库的变化。FastReport还包含自己的脚本语言,让应用程序和最终用户能够更容易地改变报表。如果你的大部分应用使用FastReport,你可以简单地配置FastReport BPL(大约1400kb)而所有你的应用程序只需要保留很少的一部分。 你可以发现FastReport有一个非常吸引人的用户界面,使用最新的用户界面组件,例如可停靠的工具栏。你的最终用户将会非常愿意使用这个设计器,只需使用鼠标就可以创建大多数报表FastReport是名副其实的快速报表:较其它一些Delphi报表设计器而言,你可以发现没有什么可以接近于它的开发速度。报表预览窗口一直是大多数报表设计器的弱点,高品质的外观,赋于你的应用程序非常专业的用户界面。 FastReport是一个已经拥有三年历史的非常成熟的报表设计器,成长使它拥有其它Delphi报表设计器所不能相比的诸多先进特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值