FastReport.NET制作动态栏位列报表C#实例
FastReport.NET制作动态栏位列报表C#实例
开发大型数据管理系统经常会遇到动态列报表,以前写过几个动态报表,但是个性化太强,代码不能复用。 这次特别整理了FastReport动态列(动态创建组件)报表类库,仅供参考。 程序说明: 1. 可以不使用左侧、右侧固定列。 2. 自动创建动态列时需要第1个组件位置参考。 3. 动态列宽度取平均值。 4. 右侧固定列往左靠齐(AlignRightColumns) 动态列动态创建报表组件类库: C# Code: /// <summary> /// C#.NET FastReport动态列(动态创建组件)报表类库 /// </summary> public class MyDynamicReport { private FastReport.Report _Report; //左侧固定组件 private IList<TextObjectBase> _LeftFixedColumns = new List<TextObjectBase>();//列头 private IList<TextObjectBase> _LeftFixedColumnsDataBind = new List<TextObjectBase>();//数据绑定 public IList<TextObjectBase> LeftFixedColumns { get { return _LeftFixedColumns; } } public IList<TextObjectBase> LeftFixedColumnsDataBind { get { return _LeftFixedColumnsDataBind; } } //右侧固定组件 private IList<TextObjectBase> _RightFixedColumns = new List<TextObjectBase>();//列头 private IList<TextObjectBase> _RightFixedColumnsDataBind = new List<TextObjectBase>();//数据绑定 public IList<TextObjectBase> RightFixedColumns { get { return _RightFixedColumns; } } public IList<TextObjectBase> RightFixedColumnsDataBind { get { return _RightFixedColumnsDataBind; } } private IList<ColumnItem> _DynamicColumns = new List<ColumnItem>(); //private const int MAX_COLUMNS_NORMAL = 5;//纵向A4纸最多支持的动态列数量 //private const int MAX_COLUMNS_LANDSCAPE = 9;//横向A4纸最多支持的动态列数量 private const int MIN_WIDTH = 80;//组件最小宽度 private const string NUM_FORMAT = "0.0000"; public MyDynamicReport(FastReport.Report report) { _Report = report; } /// <summary> /// 创建动态组件 /// </summary> /// <param name="column">列实体类</param> /// <param name="isDataBinding">True:数据区的动态对象</param> /// <returns></returns> private TextObject CreateTextObject(ColumnItem column, bool isDataBinding = false) { TextObject o = new TextObject(); if (isDataBinding) { o.Text = column.FieldName; o.Name = "D_Field_" + column.ColumnID; } else { o.Text = column.ColumnName; o.Name = "D_Column_" + column.ColumnID; } o.Font = new Font("宋体", 9); o.Visible = true; o.Printable = true; o.CanGrow = true; o.GrowToBottom = true; o.HideZeros = true; o.Border.Lines = BorderLines.All; o.VertAlign = VertAlign.Center; o.HorzAlign = HorzAlign.Center; o.Format = new FastReport.Format.CustomFormat() { Format = NUM_FORMAT }; return o; } /// <summary> /// 批量创建动态组件列 /// </summary> /// <param name="startPoint">创建第一个动态组件列的起始位置</param> /// <param name="container">所在容器</param> /// <param name="height">动态列高度</param> /// <param name="isDataBinding">容器是否数据绑定区(DataBand)</param> public List<TextObject> BuildDynamicColumns(MyPoint startPoint, BandBase container, float height, bool isDataBinding = false) { List<TextObject> list = new List<TextObject>(); float MaxWidth = CalcDynamicAreaMaxWidth(); float tmp = MaxWidth / _DynamicColumns.Count; float width = (float)Math.Round(tmp, 2); TextObject text; float dynamicWidth = 0; float left = startPoint.X; foreach (ColumnItem c in _DynamicColumns) { text = CreateTextObject(c, isDataBinding); text.Width = width; text.Height = height; text.Left = left; text.Top = startPoint.Y; container.Objects.Add(text); list.Add(text); left += text.Width; dynamicWidth += text.Width; } return list; } internal void AlignRightColumns(IList<TextObjectBase> rightControls, List<TextObject> refDynamic) { //最后一个动态生成的组件 TextObjectBase last = refDynamic[refDynamic.Count - 1]; foreach (TextObjectBase o in rightControls) { o.Left = last.Left + last.Width; o.Top = last.Top; last = o; } } public void CalcWidth(List<TextObject> list) { float w; foreach (TextObject o in list) { w = o.CalcWidth(); o.Width = w; } } /// <summary> /// 计算动态列组件区域的宽度。页面宽度-固定列的宽度 /// </summary> /// <returns></returns> private float CalcDynamicAreaMaxWidth() { float left = 0; float right = 0; foreach (TextObjectBase o in _LeftFixedColumns) left += o.Width; foreach (TextObjectBase o in _RightFixedColumns) right += o.Width; DataBand databander = _Report.FindObject("Data1") as DataBand; float px1 = databander.Width;//获取一个组件的完整宽度 return (px1 - left - right) - 5f; } /// <summary> /// 是否横向打印 /// </summary> /// <returns></returns> public bool IsLandscape() { float left = 0; float right = 0; foreach (TextObjectBase o in _LeftFixedColumns) left += o.Width; foreach (TextObjectBase o in _RightFixedColumns) right += o.Width; int dynamicColumns = _DynamicColumns.Count; FastReport.ReportPage page = (ReportPage)_Report.Pages[0]; //必须以A4纸宽度作为判断基准 double px = MillimetersToPixelsWidth(210);//获取默认A4纸张宽度,毫米转换为对应像素宽度 //计算边距 float margin = (float)MillimetersToPixelsWidth(page.LeftMargin + page.RightMargin); //判断标准:【页边距+固定列宽度+动态列最小宽度】是否大于A4纸宽度 bool result = margin + left + right + dynamicColumns * MIN_WIDTH > px; return result; } /// <summary> /// 调整页面纵向或横向打印 /// </summary> /// <param name="p"></param> public void AdjustPageLandscape(ReportPage p) { if (this.IsLandscape()) { p.Landscape = true; p.Width = 297; p.Height = 210; } else { p.Landscape = false; p.Width = 210; p.Height = 297; } } public void SetDynamicColumns(IEnumerable<ColumnItem> list) { foreach (ColumnItem o in list) _DynamicColumns.Add(o); } /// <summary> /// 毫米宽度转像素宽度 /// </summary> /// <param name="mmUnit"></param> /// <returns></returns> private static double MillimetersToPixelsWidth(double mmUnit) //length是毫米,1厘米=10毫米 { System.Windows.Forms.Panel p = new System.Windows.Forms.Panel(); System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(p.Handle); IntPtr hdc = g.GetHdc(); int width = GetDeviceCaps(hdc, 4); // HORZRES int pixels = GetDeviceCaps(hdc, 8); // BITSPIXEL g.ReleaseHdc(hdc); return (((double)pixels / (double)width) * (double)mmUnit); } [DllImport("gdi32.dll")] private static extern int GetDeviceCaps(IntPtr hdc, int Index); } //来源:C/S框架网(www.csframework.com) QQ:23404761 Demo程序: C# Code: /// <summary> /// C#.NET FastReport动态报表实例演示 /// </summary> public class MyDynamicReportDemo { public static void ShowDemo(Form owner) { FastReport.Report report = new FastReport.Report(); report.Load(@"E:\Jonny's Project\NNOMS\NNOMS.2018\Debug\Reports\DynamicReportDemo.frx"); MyDynamicReport demo = new MyDynamicReport(report); demo.SetDynamicColumns(GetColumnItems()); //添加左侧固定列 demo.LeftFixedColumns.Add((TextObjectBase)report.FindObject("Text2")); demo.LeftFixedColumns.Add((TextObjectBase)report.FindObject("Text4")); demo.LeftFixedColumnsDataBind.Add((TextObjectBase)report.FindObject("Text5")); demo.LeftFixedColumnsDataBind.Add((TextObjectBase)report.FindObject("Text7")); //添加右侧固定列 demo.RightFixedColumns.Add((TextObjectBase)report.FindObject("Text3")); demo.RightFixedColumnsDataBind.Add((TextObjectBase)report.FindObject("Text6")); //调整横向、纵向打印 demo.AdjustPageLandscape((ReportPage)report.Pages[0]); BandBase container_Column = (BandBase)report.FindObject("ColumnHeader1");//列头容器组件 BandBase container_Data = (BandBase)report.FindObject("Data1");//数据区容器组件 //列的参考组件 TextObjectBase T1 = (TextObjectBase)report.FindObject("Text4"); MyPoint P1 = new MyPoint(); P1.X = T1.Right; P1.Y = T1.Top; List<TextObject> l1 = demo.BuildDynamicColumns(P1, container_Column, container_Column.Height, false); List<TextObject> l2 = demo.BuildDynamicColumns(P1, container_Data, container_Data.Height, true); DataTable data = GetDemoTable(); data.TableName = "D"; report.RegisterData(data, "D"); //给DataBand数据列表绑定数据源 DataBand dataBand = report.FindObject("Data1") as DataBand; DataSourceBase dataSource = report.GetDataSource("D"); dataBand.DataSource = dataSource; //右侧的组件往左侧对齐 demo.AlignRightColumns(demo.RightFixedColumns, l1); demo.AlignRightColumns(demo.RightFixedColumnsDataBind, l2); //demo.CalcWidth(l1); //demo.CalcWidth(l2); report.Prepare(); report.ShowPrepared(true, owner); } private static List<ColumnItem> GetColumnItems() { ColumnItem c1 = new ColumnItem { ColumnID = "F01", ColumnName = "产品编码", FieldName = "[D.F01]" }; ColumnItem c2 = new ColumnItem { ColumnID = "F02", ColumnName = "产品名称\r\n断行测试", FieldName = "[D.F02]" }; ColumnItem c3 = new ColumnItem { ColumnID = "F03", ColumnName = "产品规格 3234234234234234234234234aaaaa", FieldName = "[D.F03]" }; ColumnItem c4 = new ColumnItem { ColumnID = "F04", ColumnName = "产品型号", FieldName = "[D.F04]" }; //ColumnItem c5 = new ColumnItem { ColumnID = "F05", ColumnName = "产品单价", FieldName = "[D.F05]" }; //ColumnItem c6 = new ColumnItem { ColumnID = "F06", ColumnName = "产品材质", FieldName = "[D.F06]" }; List<ColumnItem> list = new List<ColumnItem>(); list.Add(c1); list.Add(c2); list.Add(c3); list.Add(c4); //list.Add(c5); //list.Add(c6); return list; } private static DataTable GetDemoTable() { DataTable dt = new DataTable(); dt.Columns.Add("F01", typeof(String)); dt.Columns.Add("F02", typeof(String)); dt.Columns.Add("F03", typeof(String)); dt.Columns.Add("F04", typeof(String)); //dt.Columns.Add("F05", typeof(String)); //dt.Columns.Add("F06", typeof(String)); //dt.Rows.Add(new object[] { "1", "产品1", "规格1", "型号1", "100.21", "纯铜" }); //dt.Rows.Add(new object[] { "2", "产品2", "规格2", "型号2", "100.21", "纯银" }); //dt.Rows.Add(new object[] { "3", "产品3", "规格3", "型号3", "100.21", "不锈钢" }); //dt.Rows.Add(new object[] { "4", "产品4", "规格4", "型号4", "100.21", "玫瑰金" }); dt.Rows.Add(new object[] { "1", "产品1", "规格1", "型号1"}); dt.Rows.Add(new object[] { "2", "产品2", "规格2", "型号2" }); dt.Rows.Add(new object[] { "3", "产品3", "规格3", "型号3"}); dt.Rows.Add(new object[] { "4", "产品4", "规格4", "型号4" }); return dt; } } //来源:C/S框架网(www.csframework.com) QQ:23404761 运行Demo程序: C# Code: private void button1_Click(object sender, EventArgs e) { MyDynamicReportDemo.ShowDemo(this); } //来源:C/S框架网(www.csframework.com) QQ:23404761 客户程序效果:
参考文档:
FastReport for .Net 报表开发实例(C#源码下载) DevExpress XtraReport报表实例源码下载(C#) C#数组,多维数组,动态数组 DevExpress XtraReport - 动态加载报表布局模板 运行时动态设计FastReport.Net报表另一种处理方式 C#启动程序时检测运行多个实例 C# 窗体上显示透明图片,制作已审核/未审核图标 报表图片使用工具FastReport.NET 2013.2.5 C#.NET 定义动态对象dynamic以及属性和方法 C#.NET 定义动态对象dynamic以及转换JSON字符串 C# Winform 打开文件颜色字体目录对话框实例 C#.NET 后端WebApi接口搭建教程,WebApi接口开发实例 C# Winform 使用SUM CASE WHEN实现动态列交叉数据报表 C# FastReport.NET批量打印条形码报表详解教程 C# FastReport实时设计报表,程序运行时动态设计报表
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 | |