FastReport.NET制作动态栏位列报表C#实例
作者:C/S框架网|www.cscode.ne  发布日期:2019/10/24 12:05:05
  FastReport.NET制作动态栏位列报表C#实例


开发大型数据管理系统经常会遇到动态列报表,以前写过几个动态报表,但是个性化太强,代码不能复用。
这次特别整理了FastReport动态列(动态创建组件)报表类库,仅供参考。


贴图图片-微信截图_20191024114959




贴图图片-微信截图_20191024115200


程序说明:

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



客户程序效果:


贴图图片-微信截图_20191024121237
点击下载附件 (VIP会员下载) 点击下载附件 (如下载失败,请邮件通知我们寄回给您,或QQ:23404761留言.)
上一篇 下一篇