2019-1-17为水晶报表(含子报表)绑定数据
我们以PUSH模式为例,既是PUSH,就必须先构造出水晶报表“骨架”---数据集,在项目添加一数据集,我这里在数据集里面添加两个DataTable,一个MainTable(主报表用),一个SubTable(子报表用),在MainTable添加两列:ID和Desc,其中ID设为自增列,如图示
在SubTable添加三列:ID、MainID和Desc,其中ID也设为自增列,MainID用来与MainTable的ID关联
数据骨架构造完毕,我们再为项目添加倆RPT文件,显然是一个主表,一个子表,接着我们为报表设定数据源,打开主表RPT模板,在字段资源管理器右击数据库字段,打开数据库专家,为主报表设定数据表,这里仅将MainTable设定为主表数据源,如图示
子表类似,将SubTable设为子表数据源即可。
好,报表骨架已经有了,再来设计模板,我们先设计子报表模板,将SubTable中的MainID/ID/Desc三字段拖放到子表详细资料节,一般情况下,子报表的页脚节用处不大,显示出来反而占空间,所以我们将其抑制显示,子报表最终设计模板如下图所示,很简单吧:)
子报表设计完后,再来设计主报表,也很简单:)
首先我们将MainTable中的ID/Desc拖放到详细资料节,然后在模板添加一个详细资料节(右击详细资料节选择在下方插入节即可)用来放置子报表对象,在报表空白处点右键->插入->子报表,位置就放在我们刚刚新添加的详细资料b节,此时弹出的插入子报表窗体会自动在项目中选择RPT对象,而且目前我们项目只有主/子报表两个RPT,所以会默认将子报表RPT设为其子报表。回到主报表模板,右击子报表对象->更改子报表链接,将主表ID与子表MainID进行关联,如图示
至此主报表设计完毕,最终设计模板如下图所示
我顺带修改了下ID与Desc字段对象的字体样式,当然设计模板可根据你的实际需要设计,我这边仅仅只是一个Demo
好了,模板设计完毕,进入代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using CrystalDecisions.CrystalReports.Engine; namespace ReportDemo { public partial class FrmMain : Form { /// <summary> /// 全局水晶报表对象 /// </summary> ReportDocument myReport; /// <summary> /// 数据集作为水晶报表“骨架” /// </summary> DataSet1 crDataSet = new DataSet1(); public FrmMain() { InitializeComponent(); } /// <summary> /// 往“骨架”塞数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FrmMain_Load( object sender, EventArgs e) { /* *说明:自增列无需另外设置值 * * * * * */ //主表数据 crDataSet.MainTable.AddMainTableRow( "大类一" ); crDataSet.MainTable.AddMainTableRow( "大类二" ); crDataSet.MainTable.AddMainTableRow( "大类三" ); //子表数据 crDataSet.SubTable.AddSubTableRow(1, "小类一" ); crDataSet.SubTable.AddSubTableRow(1, "小类二" ); crDataSet.SubTable.AddSubTableRow(2, "小类三" ); crDataSet.SubTable.AddSubTableRow(2, "小类四" ); crDataSet.SubTable.AddSubTableRow(2, "小类五" ); crDataSet.SubTable.AddSubTableRow(2, "小类六" ); crDataSet.SubTable.AddSubTableRow(3, "小类七" ); crDataSet.SubTable.AddSubTableRow(3, "小类八" ); crDataSet.SubTable.AddSubTableRow(3, "小类九" ); } /// <summary> /// “Report”按钮事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnReport_Click( object sender, EventArgs e) { myReport = new CrystalReport1(); //只需给主报表设定数据源,无需再为子报表设定数据 myReport.SetDataSource(crDataSet); crystalReportViewer1.ReportSource = myReport; } /// <summary> /// 窗体关闭前删除水晶报表产生的临时文件,避免过多临时文件导致“报表加载失败” /// </summary> protected override void OnFormClosing(FormClosingEventArgs e) { base .OnFormClosing(e); myReport.Dispose(); } } } |
最终运行效果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)