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
/// <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
/// <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
private void button1_Click(object sender, EventArgs e)
{
MyDynamicReportDemo.ShowDemo(this);
}
//来源:C/S框架网(www.csframework.com) QQ:23404761
客户程序效果:
版权声明:本文为开发框架文库发布内容,转载请附上原文出处连接
NewDoc C/S框架网