提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
原创|其它|编辑:郝浩|2011-08-23 15:25:11.000|阅读 1297 次
概述:上 回负责报表这块,说不能再像以前的项目一样的做报表了,以前项目300多张报表,一张一张的画,一张一张的写存储过程,工作量大啊,当然现在的项目报表没 有那么多。这么说我的工作就要是要节省工作量,我经过分析,得出两个结论:第一:报表的数据源得由程序员自己去取来,短时间想做个像报表设计器那样能根据 复杂的业务而“制作”数据源是不可能的;第二:报表的布局复杂多变,即使减少工作量,也无法避免对一个复杂变量的赋值工作。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
上 回负责报表这块,说不能再像以前的项目一样的做报表了,以前项目300多张报表,一张一张的画,一张一张的写存储过程,工作量大啊,当然现在的项目报表没 有那么多。这么说我的工作就要是要节省工作量,我经过分析,得出两个结论:第一:报表的数据源得由程序员自己去取来,短时间想做个像报表设计器那样能根据 复杂的业务而“制作”数据源是不可能的;第二:报表的布局复杂多变,即使减少工作量,也无法避免对一个复杂变量的赋值工作。
开始思考
我们的每张报表分页头数据部分,明细数据部分,页脚数据部分三块。页头数据和页脚数据都只是一条记录,每个字段的值都显示在它的标题后面,如:姓名:×××。明细数据比较多,而且显示格式像下面这样:
标题1 | 标题2 | 标题3 |
1 | a | 张 |
2 | b | 李 |
 它们每行显示的列数多少都是可以自定义的,如果定义的页头数据的列数是3,而页头数据有5个字段,多出来的就要显示在下一行;同时每个字段占用的列数也是可以自定义的,假如页头数据有5个字段,每字段分别占用1、2、1、1、1列,每行显示3列,那么它就会显示成:
姓名:××× | 住址:***************** | |
性别:男 | 籍贯:×× | 出生年月:××× |
/// <summary> /// 页标头列数(默认3) /// </summary> private int mHeaderTableColumnCount = 3; /// <summary> /// 明细表列数(默认10) /// </summary> private int mDetailTableColumnCount = 10; /// <summary> /// 页脚列数(默认5) /// </summary> private int mFooterTableColumnCount = 5;
我想其中最难的就是每个要显示的字段的位置大小问题和用什么数据结构存储这样的布局问题,我用了一个三维数组,它的说明如下:
/// <summary> /// 表示报表布局的数组[i][j][k] /// i=0:页头布局,i=1:明细布局,i=2:页脚布局 /// j:按顺序显示的字段(j=0:报表标题字段) /// k=0:字段名,k=1:标题,k=2:列跨度,k=3:格式化字符串(可选) /// </summary> public string[][][] ReportLayout = null; 所有数据存储在一个DataSet中,DataSet里的第一个Table是页头数据,第二个是明细数据,第三个是页脚数据。 /// <summary> /// 报表数据源,0页头表1明细表2页脚表 /// </summary> public DataSet mDs = null;
开始工作
接下来就是用程序定义各个XRTable(表)、XRTableRow(行)、XRTableCell(列),并根据ReportLayout数组的值设置它们的位置和大小等等属性。这里就放上对明细数据布局的代码(其中一直用ReportLayout[1],这里的1就是指的明细,如果是页头数据就是0了)。 if (mReportLayout.Length > 1)
{ columnWidth = PageWidth / mDetailTableColumnCount; tempHeight = 0; for (tempCount = 0, i = 0; i < ReportLayout[1].Length; i++) tempCount += Convert.ToInt32(ReportLayout[1][i][2]); XRTable detailTable = new XRTable(); detailTable.Location = new System.Drawing.Point(0, tempHeight); detailTable.Size = new System.Drawing.Size(PageWidth, mDetailRowHeight * (tempCount + mDetailTableColumnCount - 1) / mDetailTableColumnCount); detailTable.Borders = (DevExpress.XtraPrinting.BorderSide) ((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Right) | DevExpress.XtraPrinting.BorderSide.Bottom); for (j = 0, i = 0; j < (tempCount + mDetailTableColumnCount - 1) / mDetailTableColumnCount; j++) { XRTableRow r = new XRTableRow(); r.Size = new System.Drawing.Size(PageWidth, mDetailRowHeight); for (int k = 0; i < mReportLayout[1].Length && (k + Convert.ToInt32(ReportLayout[1][i][2])) <= mDetailTableColumnCount; k += Convert.ToInt32(ReportLayout[1][i][2]), i++) { XRTableCell c = new XRTableCell(); c.Size = new System.Drawing.Size (columnWidth * Convert.ToInt32(ReportLayout[1][i][ 2]), mDetailRowHeight); c.Font = new System.Drawing.Font("宋体", 9F); c.TextAlignment = (ReportLayout[1][i][0].Substring(0, 1) == "N" || ReportLayout[1][i][0].Substring(0, 1) == "n") ? DevExpress.XtraPrinting. TextAlignment.MiddleRight : DevExpress.XtraPrinting.TextAlignment.MiddleLeft; c.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] { new DevExpress.XtraReports.UI.XRBinding ("Text", mDs.Tables[1], ReportLayout[1][i][0], ReportLa 4 ? ReportLayout[1][i][3] : string.Empty) }); r.Cells.AddRange(new DevExpress.XtraReports.UI.XRTableCell[] { c }); c.Tag = ReportLayout[1][i][2]; } detailTable.Rows.AddRange (new DevExpress.XtraReports.UI.XRTableRow[] { r }); } mReport.Detail.Controls.AddRange (new DevExpress.XtraReports.UI.XRTable[] { detailTable }); }
这里是数据绑定(c.DataBindings),如果是页头里面的话就应该是:
c.Text = mReportLayout[0][i][1] + ": " + mDs.Tables[0].Rows[0][mReportLayout[0][i][0]];
对于明细还应该在页头里面加个XRTable,来放置标题,这个就不说了,根据上面的代码很容易理解怎么做。
还有分组和合计,也用数组来存储它们的布局:
/// <summary> /// 表示统计字段的布局[i][j] /// i:按顺序显示的字段 /// j=0:字段名,j=1:列跨度,j=2:汇总函数,j=3:格式化字符串(可选) /// </summary> public string[][] TotalLayout = null; /// <summary> /// 表示分组字段的布局[i][j][k] /// i:第i个分组 /// j:每次分组要显示的字段 /// k=0:字段名,k=1:列跨度,k=2:汇总函数,k=3:格式化字符串(可选) /// </summary> public string[][] GroupLayout = null;
根据注释,同上面的那段代码的一个道理,只是要对每个XRTableCell加下面的代码:
if (GroupLayout[i][j].Length >= 3) { XRSummary Summary = new XRSummary(); Summary.Func = (DevExpress.XtraReports.UI.SummaryFunc) Enum.Parse(typeof(DevExpress.XtraReports.UI.SummaryFunc), GroupLayout[i][j][2], true); Summary.FormatString = GroupLayout[i][j].Length >= 4 ? GroupLayout[i][j][3] : string.Empty; Summary.Running = SummaryRunning.Group; //如果是合计则应该是SummaryRunning.Report c.Summary = Summary; }
在做的过程中还发现单元格的线对不齐的事情,总是相差1个象素,后来得到同事 的建议,每次定义一个XRTable就计算它的位置的大小把它设置好,就想现在上面的代码那样,而不是在将该XRTable中的XRTableRow和 XRTableCell都定义完了也设置好它们的属性了再来设置XRTable的属性,这样就对齐了,看来XRTableRow和XRTableCell 的位置大小属性都是根据XRTable来的,刚刚定义的XRTable它的大小应该是100px,绑定到它的XRTableRow和 XRTableCell会根据自身的大小按比例缩放使总大小为100px,之后你再设置XRTable的大小到1000px,它们再按原来的比例缩放到总 大小为1000px,这样一来二去就有点误差了,呵呵,这也是很符合道理的。
实施
以后我们做报表就只要定义个我的类(假如类名是:Report)的一个实例(rpt),定义的同时给构造函数传参(我在这个类中定义了个这样的构造函数,参数中包含了我们要对报表布局以及数据源DataSet的所有变量),然后一个rpt.ShowPreview();就显示报表了(我的类中的有这个方法,这个方法调用了上面说的设置报表的布局等代码,之后用DevExpress.XtraReports报表本身的ShowPreview()来显示报表),一切OK。下面这张图PS了下。
(慧都控件网版权所有,转载请注明出处,否则追究法律责任)
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:网络转载面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢