实现Excel 表格功能的ActiveReports动态报表
2009-12-01 10:50
525 查看
注:此文本人是用WindowsLiveWriter离线写的,没想到发布到CSDN后格式完全变了!晕!如有疑问的请联系.另现求源代码的朋友不好意思了,这个组件现在是商业软件的一部分,恕不能提供.
动态报表DLL名:
DynamicReportBuilder
类成员:
[b]
[/b]
主框架:
目的:
完全实现Excel的丰富动态报表功能!不再需要内置报表模板到程序.
开发语言:
C#
引用组件:
ActiveReports3;
为了广泛支持更多的网格视图控件,本项目未引用除ActiveReports以外的任何第三方组件。
功能描述:
支持由任何数据结构对象(如:DataGridView;DevExpress.GridControl,DataTable...)构建报头字段;
支持自定义报表标题(TitleText),子标题(SubTitleText);
支持自定义分组(GroupHeader),并实现分组层级(GroupLevel).支持分组段尾(GroupFooter),页脚统计(PageFooter);
支持自定义字段的位置排序、字段标头宽度、颜色等设置;
动态报表中的各列(ReportField)自动匹配纸张宽度;
支持动态报表条件样式(FormatsCondition),现在可以在报表预览窗口自定义创建条件样式了(v1.1)!
支持自定义打印机页面设置,字体,
支持ParentBanded固定带宽栏;
支持另存为项目模板文件。
已实现主从表的动态报表,并提供了自己实现的表头数据源设计器(v1.1);
待完善:
目前调整字段顺序的方式为:双击字段项向下,按下CTRL键双击字段项则向上。这种功能是常用的,但目前没有提供比较好的显式操作方式,故需再改进报表配置器UI。
动态报表配置器主界面(失真的GIF动画):
源代码:
usingSystem;
usingSystem.Drawing;
usingSystem.Text;
namespaceCIMS.Report.Center.Builder
{
publicclassReportField:IDisposable
{
protectedReportFieldCollectionBasem_collection=null;
protectedFieldAppearancem_appearance=null;
protectedFieldBehaviorm_behavior=null;
protectedstringm_caption=string.Empty;
protectedstringm_dataField=string.Empty;
protectedTypem_dataType;
protectedfloatm_width=0;
protectedstringm_outputFormat=string.Empty;
protectedobjectm_tag=null;
protectedintm_index=0;
protectedboolm_visible=true;
protectedReportFieldm_banded=null;
publiceventEventHandlerFieldVisibleChanged=null;
publiceventEventHandlerFieldCaptionChanged=null;
publiceventEventHandlerFieldWidthChanged=null;
publiceventFieldIndexChangedHandlerFieldIndexChanged=null;
publicReportField(ReportFieldCollectionBasecollection):this(collection,string.Empty,string.Empty,0,true){}
publicReportField(ReportFieldCollectionBasecollection,stringdataField):this(collection,dataField,dataField,0,true){}
publicReportField(ReportFieldCollectionBasecollection,stringcaption,stringdataField):this(collection,caption,dataField,0,true){}
publicReportField(ReportFieldCollectionBasecollection,stringcaption,stringdataField,floatwidth):this(collection,caption,dataField,width,true){}
publicReportField(ReportFieldCollectionBasecollection,stringcaption,stringdataField,floatwidth,boolvisible)
{
m_collection=collection;
m_caption=caption;
m_dataField=dataField;
m_width=width;
m_visible=visible;
m_appearance=newFieldAppearance();
m_behavior=newFieldBehavior();
}
#regionProperties
///<summary>
///获取当前字段的集合
///</summary>
publicReportFieldCollectionBaseCollection{get{returnm_collection;}}
///<summary>
///获取或设置当前字段的所属固定带(没有即为Nothing)
///</summary>
publicReportFieldParentBanded{get{returnm_banded;}set{m_banded=value;}}
///<summary>
///获取列效果设置对象
///</summary>
publicFieldAppearanceAppearance{get{returnm_appearance;}}
///<summary>
///获取列行为设置对象
///</summary>
publicFieldBehaviorBehavior{get{returnm_behavior;}}
///<summary>
///获取或设置行标题文本
///</summary>
publicstringCaption{get{returnm_caption;}set{if(m_caption==value)return;
m_caption=value;
if(FieldCaptionChanged!=null&&this.IsLock==false)FieldCaptionChanged(this,EventArgs.Empty);
}}
protectedboolIsLock{get{
if(m_collectionisReportFieldCollection)return((ReportFieldCollection)this.Collection).IsLock;
returnfalse;
}}
///<summary>
///获取或设置绑定到报表控件的数据字段名
///</summary>
publicstringDataField{get{returnm_dataField;}set{m_dataField=value;}}
///<summary>
///获取或设置绑定字段的数据类型.在生成报表时,根据此类型属性决定创建合适的控件类型
///</summary>
publicTypeDataType{get{returnm_dataType;}set{m_dataType=value;}}
///<summary>
///获取或设置列的初始宽度
///</summary>
publicfloatWidth{get{if(this.Visible==false)return0;returnm_width;}set{
if(m_width==value)return;
m_width=value;
if(FieldWidthChanged!=null&&this.IsLock==false)FieldWidthChanged(this,EventArgs.Empty);
}}
///<summary>
///获取或设置列输出文本的格式化字符格式
///</summary>
publicstringOutputFormat{get{returnm_outputFormat;}set{m_outputFormat=value;}}
///<summary>
///获取或设置列的用户数据对象
///</summary>
publicobjectTag{get{returnm_tag;}set{m_tag=value;}}
///<summary>
///获取或设置位置索引
///</summary>
publicintIndex
{
get{if(this.Visible==false)return-1;returnm_index;}
set
{
if(m_index==value)return;
intoldIndex=m_index;
m_index=value;
if(FieldIndexChanged!=null&&this.IsLock==false)FieldIndexChanged(this,newFieldIndexChangedArgs(m_index,oldIndex));
}
}
///<summary>
///获取或设置是否创建到报表对象(在报表中是否可见)
///</summary>
publicboolVisible
{
get{returnm_visible;}
set
{
if(m_visible==value)return;
m_visible=value;
if(FieldVisibleChanged!=null&&this.IsLock==false)FieldVisibleChanged(this,EventArgs.Empty);
}
}
#endregion
publicoverrideboolEquals(objectobj)
{
if(objisReportField)return((ReportField)obj).DataField==this.DataField;
if(obj!=null)returnobj.ToString()==this.ToString();
returnbase.Equals(obj);
}
publicoverridestringToString()
{
returnthis.DataField;
}
#regionIDisposable成员
publicvoidDispose()
{
this.Appearance.Dispose();
}
#endregion
}
}
using
System;
using
System.Drawing;
using
System.Text;
namespace
CIMS.Report.Center.Builder
{
public
class
StyleFormatCondition:ReportField
{
public
enum
FormatConditionEnum
{
//None=-1,
Equal=0,
NotEqual=1,
Greater=2,
GreaterOrEqual=3,
Less=4,
LessOrEqual=5,
Between=6,
NotBetween=7,
//Expression=8,NoSupport!
}
protected
FormatConditionEnumm_formatCondition=FormatConditionEnum.Equal;
protected
object
m_value1=null
;object
m_value2=null
;
protected
bool
m_applyToRow=false
;
public
StyleFormatCondition(ReportFieldCollectionBasecollection):base
(collection){}
public
StyleFormatCondition(ReportFieldCollectionBasecollection,string
dataField):base
(collection,dataField){}
public
StyleFormatCondition(ReportFieldCollectionBasecollection,string
dataField,FormatConditionEnumcondition):base
(collection,dataField){m_formatCondition=condition;}
///
///获取或设置样式条件(名称兼容于DevExpress.XtraGrid.FormatConditionEnum)
///
public
FormatConditionEnumCondition{get
{return
m_formatCondition;}set
{m_formatCondition=value
;}}
///
///获取或设置值1
///
public
object
Value1{get
{return
m_value1;}set
{m_value1=value
;}}
///
///获取或设置值2(如果条件为:GreaterOrEqual|LessOrEqual|Between|NotBetween)
///
public
object
Value2{get
{return
m_value2;}set
{m_value2=value
;}}
//获取或设置是否应用样式到整行
public
bool
ApplyToRow{get
{return
m_applyToRow;}set
{m_applyToRow=value
;}}
public
override
bool
Equals(object
obj)
{
return
this
==obj;
}
}
}
……由于源代码太多!下面只贴核心代码.
下面是配置器UI的核心代码…
protected
void
OnCreateControls(FontcontrolFont)
{
Common.InfoProvider.OnInfo("正在创建已收集到的动态报表元素,请稍候...
",'r');
if
(controlFont==null
)controlFont=this
.ReportSettings.ReportFont;
int
totalHeight=0;
int
w=2;
int
h=6;
GroupControlgroup=null
;
ctrlHeader=new
ReportHeaderControl();
ctrlHeader.TitleText=ReportSettings.OptionsHeader.TitleText;
ctrlHeader.TitleSubText=ReportSettings.OptionsHeader.TitleSubText;
ctrlHeader.LogoStatus=ReportSettings.OptionsHeader.LogoStatus;
ctrlHeader.Width=panelLayout.Width-w;
totalHeight+=ctrlHeader.Height+h;
group=CreateGroupControl("报表页眉(ReportHeader)
",ctrlHeader);
group.Width=panelLayout.Width-w;
totalHeight+=group.Height+h;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(ctrlHeader);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
if
(this
.Groups!=null
&&this
.Groups.Count>0)
{
this
.Groups.SortByIndex(System.Windows.Forms.SortOrder.Descending);
GroupFieldCollectionControlgfc=new
GroupFieldCollectionControl(this
.ReportSettings,this
.Groups);
gfc.Width=panelLayout.Width-w;
totalHeight+=gfc.Height+h;
group=CreateGroupControl("报表分组层级(ReportGroupLevel)
",gfc);
group.Width=panelLayout.Width-w;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(gfc);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
gfc.OnInit();
totalHeight+=group.Height+h;
}
this
.Fields.SortByIndex(System.Windows.Forms.SortOrder.Descending);
FieldCollectionControlfc=new
FieldCollectionControl(this
.ReportSettings,this
.Fields);
fc.Width=panelLayout.Width-w;
totalHeight+=fc.Height+h;
group=CreateGroupControl("报表数据字段(ReportDetailFields)
",fc);
group.Width=panelLayout.Width-w;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(fc);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
fc.OnInit();
totalHeight+=group.Height+h;
if
(this
.Summaries!=null
&&this
.Summaries.Count>0)
{
this
.Summaries.SortByIndex(System.Windows.Forms.SortOrder.Descending);
SummaryFieldCollectionControlsfc=new
SummaryFieldCollectionControl(this
.ReportSettings,this
.Summaries);
sfc.Width=panelLayout.Width-w;
totalHeight+=sfc.Height+h;
group=CreateGroupControl("报表页脚统计字段(ReportSummaries)
",sfc);
group.Width=panelLayout.Width-w;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(sfc);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
sfc.OnInit();
totalHeight+=group.Height+h;
}
if
(this
.FormatConditions!=null
&&this
.FormatConditions.Count>0)
{
this
.FormatConditions.SortByIndex(SortOrder.Descending);
StyleFormatConditionCollectionControlsfc=new
StyleFormatConditionCollectionControl(this
.ReportSettings,this
.FormatConditions);
sfc.Width=panelLayout.Width-w;
totalHeight+=sfc.Height+h;
group=CreateGroupControl("报表数据字段条件样式(StyleFormatConditions)
",sfc);
group.Width=panelLayout.Width-w;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(sfc);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
sfc.OnInit();
totalHeight+=group.Height+h;
}
ctrlFooter=new
ReportFooterControl();
ctrlFooter.ShowPageOfTotal=ReportSettings.OptionsFooter.ShowPageOfTotal;
ctrlFooter.ShowCreatedBy=ReportSettings.OptionsFooter.ShowCreatedBy;
ctrlFooter.ShowAuditedBy=ReportSettings.OptionsFooter.ShowAuditedBy;
ctrlFooter.ShowApprovedBy=ReportSettings.OptionsFooter.ShowApprovedBy;
ctrlFooter.ShowCreatedDate=ReportSettings.OptionsFooter.ShowCreatedDate;
ctrlFooter.Width=panelLayout.Width-w;
totalHeight+=ctrlFooter.Height+h;
group=CreateGroupControl("报表页脚(ReportFooter)
",ctrlFooter);
group.Width=panelLayout.Width-w;
totalHeight+=group.Height+h;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(ctrlFooter);
//ctrlFooter.OnInit();
group.OnInit();
this
.panelLayout.Height=totalHeight;
this
.panelLayout.Width=this
.panelScroll.Width-SystemInformation.VerticalScrollBarWidth-1;
Common.InfoProvider.OnInfo("元素已创建到编辑容器!您可以选择不生成某字段/统计或调整字段的列宽。
",'m');
}
下面是动态报表的核心实现部分(ReportBuilderBase,ReportBuilder,DetailReportBuilder待实现
)…
我们先来了解一下纸张布局.
用于装订的装订线边距(固定区域);
上边距区域(相当于页眉);
打印区域(可通过调整页边距来打印更多内容!);
左右对开页的对称页边距;
下边距区域(相当于页脚)。
动态报表需要使各列按纸张打印区域自动调整宽度缩放比例,以不能产生空白区域或超出打印区域。下面是关键属性/函数:
由于ActiveReports默认使用的是英制单位,所以我们需要知道:1英寸=1/100像素。
///
///可放置控件的总宽度
///
protected
float
PrintWidth{get
{return
m_printWidth;}}
///
///控件的宽度缩放比例
///
protected
float
PrintWidthScale{get
{return
m_printWidthScale;}}
m_printWidth和m_printWidthScale变量在BeginBuild(ActiveReport3rpt)方法中初始化:
代码太多!只贴核心方法,需要完整代码的请联系
带分组段落和条件格式的动态报表:
带固定带宽和条件格式及页脚统计的动态报表:
v1.1新增功能:
1,现在能创建主从动态报表了!
2,新增表头数据项目设计器以更好的支持主从报表的动态创建:
3,新增一个报表生成向导,从UI来看,WPF技术带来的UI视觉效果果然非同一般!
4,新增水印设计器:
v1.1增强功能和修改:
1,现在Form支持调整大小了!
2,现在报表支持动态图章和水印了!
动态报表DLL名:
DynamicReportBuilder
类成员:
[b]
[/b]
主框架:
目的:
完全实现Excel的丰富动态报表功能!不再需要内置报表模板到程序.
开发语言:
C#
引用组件:
ActiveReports3;
为了广泛支持更多的网格视图控件,本项目未引用除ActiveReports以外的任何第三方组件。
功能描述:
支持由任何数据结构对象(如:DataGridView;DevExpress.GridControl,DataTable...)构建报头字段;
支持自定义报表标题(TitleText),子标题(SubTitleText);
支持自定义分组(GroupHeader),并实现分组层级(GroupLevel).支持分组段尾(GroupFooter),页脚统计(PageFooter);
支持自定义字段的位置排序、字段标头宽度、颜色等设置;
动态报表中的各列(ReportField)自动匹配纸张宽度;
支持动态报表条件样式(FormatsCondition),现在可以在报表预览窗口自定义创建条件样式了(v1.1)!
支持自定义打印机页面设置,字体,
支持ParentBanded固定带宽栏;
支持另存为项目模板文件。
已实现主从表的动态报表,并提供了自己实现的表头数据源设计器(v1.1);
待完善:
目前调整字段顺序的方式为:双击字段项向下,按下CTRL键双击字段项则向上。这种功能是常用的,但目前没有提供比较好的显式操作方式,故需再改进报表配置器UI。
动态报表配置器主界面(失真的GIF动画):
源代码:
usingSystem;
usingSystem.Drawing;
usingSystem.Text;
namespaceCIMS.Report.Center.Builder
{
publicclassReportField:IDisposable
{
protectedReportFieldCollectionBasem_collection=null;
protectedFieldAppearancem_appearance=null;
protectedFieldBehaviorm_behavior=null;
protectedstringm_caption=string.Empty;
protectedstringm_dataField=string.Empty;
protectedTypem_dataType;
protectedfloatm_width=0;
protectedstringm_outputFormat=string.Empty;
protectedobjectm_tag=null;
protectedintm_index=0;
protectedboolm_visible=true;
protectedReportFieldm_banded=null;
publiceventEventHandlerFieldVisibleChanged=null;
publiceventEventHandlerFieldCaptionChanged=null;
publiceventEventHandlerFieldWidthChanged=null;
publiceventFieldIndexChangedHandlerFieldIndexChanged=null;
publicReportField(ReportFieldCollectionBasecollection):this(collection,string.Empty,string.Empty,0,true){}
publicReportField(ReportFieldCollectionBasecollection,stringdataField):this(collection,dataField,dataField,0,true){}
publicReportField(ReportFieldCollectionBasecollection,stringcaption,stringdataField):this(collection,caption,dataField,0,true){}
publicReportField(ReportFieldCollectionBasecollection,stringcaption,stringdataField,floatwidth):this(collection,caption,dataField,width,true){}
publicReportField(ReportFieldCollectionBasecollection,stringcaption,stringdataField,floatwidth,boolvisible)
{
m_collection=collection;
m_caption=caption;
m_dataField=dataField;
m_width=width;
m_visible=visible;
m_appearance=newFieldAppearance();
m_behavior=newFieldBehavior();
}
#regionProperties
///<summary>
///获取当前字段的集合
///</summary>
publicReportFieldCollectionBaseCollection{get{returnm_collection;}}
///<summary>
///获取或设置当前字段的所属固定带(没有即为Nothing)
///</summary>
publicReportFieldParentBanded{get{returnm_banded;}set{m_banded=value;}}
///<summary>
///获取列效果设置对象
///</summary>
publicFieldAppearanceAppearance{get{returnm_appearance;}}
///<summary>
///获取列行为设置对象
///</summary>
publicFieldBehaviorBehavior{get{returnm_behavior;}}
///<summary>
///获取或设置行标题文本
///</summary>
publicstringCaption{get{returnm_caption;}set{if(m_caption==value)return;
m_caption=value;
if(FieldCaptionChanged!=null&&this.IsLock==false)FieldCaptionChanged(this,EventArgs.Empty);
}}
protectedboolIsLock{get{
if(m_collectionisReportFieldCollection)return((ReportFieldCollection)this.Collection).IsLock;
returnfalse;
}}
///<summary>
///获取或设置绑定到报表控件的数据字段名
///</summary>
publicstringDataField{get{returnm_dataField;}set{m_dataField=value;}}
///<summary>
///获取或设置绑定字段的数据类型.在生成报表时,根据此类型属性决定创建合适的控件类型
///</summary>
publicTypeDataType{get{returnm_dataType;}set{m_dataType=value;}}
///<summary>
///获取或设置列的初始宽度
///</summary>
publicfloatWidth{get{if(this.Visible==false)return0;returnm_width;}set{
if(m_width==value)return;
m_width=value;
if(FieldWidthChanged!=null&&this.IsLock==false)FieldWidthChanged(this,EventArgs.Empty);
}}
///<summary>
///获取或设置列输出文本的格式化字符格式
///</summary>
publicstringOutputFormat{get{returnm_outputFormat;}set{m_outputFormat=value;}}
///<summary>
///获取或设置列的用户数据对象
///</summary>
publicobjectTag{get{returnm_tag;}set{m_tag=value;}}
///<summary>
///获取或设置位置索引
///</summary>
publicintIndex
{
get{if(this.Visible==false)return-1;returnm_index;}
set
{
if(m_index==value)return;
intoldIndex=m_index;
m_index=value;
if(FieldIndexChanged!=null&&this.IsLock==false)FieldIndexChanged(this,newFieldIndexChangedArgs(m_index,oldIndex));
}
}
///<summary>
///获取或设置是否创建到报表对象(在报表中是否可见)
///</summary>
publicboolVisible
{
get{returnm_visible;}
set
{
if(m_visible==value)return;
m_visible=value;
if(FieldVisibleChanged!=null&&this.IsLock==false)FieldVisibleChanged(this,EventArgs.Empty);
}
}
#endregion
publicoverrideboolEquals(objectobj)
{
if(objisReportField)return((ReportField)obj).DataField==this.DataField;
if(obj!=null)returnobj.ToString()==this.ToString();
returnbase.Equals(obj);
}
publicoverridestringToString()
{
returnthis.DataField;
}
#regionIDisposable成员
publicvoidDispose()
{
this.Appearance.Dispose();
}
#endregion
}
}
using
System;
using
System.Drawing;
using
System.Text;
namespace
CIMS.Report.Center.Builder
{
public
class
StyleFormatCondition:ReportField
{
public
enum
FormatConditionEnum
{
//None=-1,
Equal=0,
NotEqual=1,
Greater=2,
GreaterOrEqual=3,
Less=4,
LessOrEqual=5,
Between=6,
NotBetween=7,
//Expression=8,NoSupport!
}
protected
FormatConditionEnumm_formatCondition=FormatConditionEnum.Equal;
protected
object
m_value1=null
;object
m_value2=null
;
protected
bool
m_applyToRow=false
;
public
StyleFormatCondition(ReportFieldCollectionBasecollection):base
(collection){}
public
StyleFormatCondition(ReportFieldCollectionBasecollection,string
dataField):base
(collection,dataField){}
public
StyleFormatCondition(ReportFieldCollectionBasecollection,string
dataField,FormatConditionEnumcondition):base
(collection,dataField){m_formatCondition=condition;}
///
///获取或设置样式条件(名称兼容于DevExpress.XtraGrid.FormatConditionEnum)
///
public
FormatConditionEnumCondition{get
{return
m_formatCondition;}set
{m_formatCondition=value
;}}
///
///获取或设置值1
///
public
object
Value1{get
{return
m_value1;}set
{m_value1=value
;}}
///
///获取或设置值2(如果条件为:GreaterOrEqual|LessOrEqual|Between|NotBetween)
///
public
object
Value2{get
{return
m_value2;}set
{m_value2=value
;}}
//获取或设置是否应用样式到整行
public
bool
ApplyToRow{get
{return
m_applyToRow;}set
{m_applyToRow=value
;}}
public
override
bool
Equals(object
obj)
{
return
this
==obj;
}
}
}
……由于源代码太多!下面只贴核心代码.
下面是配置器UI的核心代码…
protected
void
OnCreateControls(FontcontrolFont)
{
Common.InfoProvider.OnInfo("正在创建已收集到的动态报表元素,请稍候...
",'r');
if
(controlFont==null
)controlFont=this
.ReportSettings.ReportFont;
int
totalHeight=0;
int
w=2;
int
h=6;
GroupControlgroup=null
;
ctrlHeader=new
ReportHeaderControl();
ctrlHeader.TitleText=ReportSettings.OptionsHeader.TitleText;
ctrlHeader.TitleSubText=ReportSettings.OptionsHeader.TitleSubText;
ctrlHeader.LogoStatus=ReportSettings.OptionsHeader.LogoStatus;
ctrlHeader.Width=panelLayout.Width-w;
totalHeight+=ctrlHeader.Height+h;
group=CreateGroupControl("报表页眉(ReportHeader)
",ctrlHeader);
group.Width=panelLayout.Width-w;
totalHeight+=group.Height+h;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(ctrlHeader);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
if
(this
.Groups!=null
&&this
.Groups.Count>0)
{
this
.Groups.SortByIndex(System.Windows.Forms.SortOrder.Descending);
GroupFieldCollectionControlgfc=new
GroupFieldCollectionControl(this
.ReportSettings,this
.Groups);
gfc.Width=panelLayout.Width-w;
totalHeight+=gfc.Height+h;
group=CreateGroupControl("报表分组层级(ReportGroupLevel)
",gfc);
group.Width=panelLayout.Width-w;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(gfc);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
gfc.OnInit();
totalHeight+=group.Height+h;
}
this
.Fields.SortByIndex(System.Windows.Forms.SortOrder.Descending);
FieldCollectionControlfc=new
FieldCollectionControl(this
.ReportSettings,this
.Fields);
fc.Width=panelLayout.Width-w;
totalHeight+=fc.Height+h;
group=CreateGroupControl("报表数据字段(ReportDetailFields)
",fc);
group.Width=panelLayout.Width-w;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(fc);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
fc.OnInit();
totalHeight+=group.Height+h;
if
(this
.Summaries!=null
&&this
.Summaries.Count>0)
{
this
.Summaries.SortByIndex(System.Windows.Forms.SortOrder.Descending);
SummaryFieldCollectionControlsfc=new
SummaryFieldCollectionControl(this
.ReportSettings,this
.Summaries);
sfc.Width=panelLayout.Width-w;
totalHeight+=sfc.Height+h;
group=CreateGroupControl("报表页脚统计字段(ReportSummaries)
",sfc);
group.Width=panelLayout.Width-w;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(sfc);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
sfc.OnInit();
totalHeight+=group.Height+h;
}
if
(this
.FormatConditions!=null
&&this
.FormatConditions.Count>0)
{
this
.FormatConditions.SortByIndex(SortOrder.Descending);
StyleFormatConditionCollectionControlsfc=new
StyleFormatConditionCollectionControl(this
.ReportSettings,this
.FormatConditions);
sfc.Width=panelLayout.Width-w;
totalHeight+=sfc.Height+h;
group=CreateGroupControl("报表数据字段条件样式(StyleFormatConditions)
",sfc);
group.Width=panelLayout.Width-w;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(sfc);
ctrlHeader.OnInit(controlFont.Name);
group.OnInit();
sfc.OnInit();
totalHeight+=group.Height+h;
}
ctrlFooter=new
ReportFooterControl();
ctrlFooter.ShowPageOfTotal=ReportSettings.OptionsFooter.ShowPageOfTotal;
ctrlFooter.ShowCreatedBy=ReportSettings.OptionsFooter.ShowCreatedBy;
ctrlFooter.ShowAuditedBy=ReportSettings.OptionsFooter.ShowAuditedBy;
ctrlFooter.ShowApprovedBy=ReportSettings.OptionsFooter.ShowApprovedBy;
ctrlFooter.ShowCreatedDate=ReportSettings.OptionsFooter.ShowCreatedDate;
ctrlFooter.Width=panelLayout.Width-w;
totalHeight+=ctrlFooter.Height+h;
group=CreateGroupControl("报表页脚(ReportFooter)
",ctrlFooter);
group.Width=panelLayout.Width-w;
totalHeight+=group.Height+h;
panelLayout.Controls.Add(group);
panelLayout.Controls.Add(ctrlFooter);
//ctrlFooter.OnInit();
group.OnInit();
this
.panelLayout.Height=totalHeight;
this
.panelLayout.Width=this
.panelScroll.Width-SystemInformation.VerticalScrollBarWidth-1;
Common.InfoProvider.OnInfo("元素已创建到编辑容器!您可以选择不生成某字段/统计或调整字段的列宽。
",'m');
}
下面是动态报表的核心实现部分(ReportBuilderBase,ReportBuilder,DetailReportBuilder待实现
)…
我们先来了解一下纸张布局.
用于装订的装订线边距(固定区域);
上边距区域(相当于页眉);
打印区域(可通过调整页边距来打印更多内容!);
左右对开页的对称页边距;
下边距区域(相当于页脚)。
动态报表需要使各列按纸张打印区域自动调整宽度缩放比例,以不能产生空白区域或超出打印区域。下面是关键属性/函数:
由于ActiveReports默认使用的是英制单位,所以我们需要知道:1英寸=1/100像素。
///
///可放置控件的总宽度
///
protected
float
PrintWidth{get
{return
m_printWidth;}}
///
///控件的宽度缩放比例
///
protected
float
PrintWidthScale{get
{return
m_printWidthScale;}}
m_printWidth和m_printWidthScale变量在BeginBuild(ActiveReport3rpt)方法中初始化:
protected virtual void BeginBuild(ActiveReport3rpt) { //......更多初始化代码 m_defaultHeight=DesignOptions.DefaultPageDetailByNewReport; m_hasBandeds=this .Fields.HasBandedColumns; m_printWidth=RoundTowDecimals(Settings.CalcPaperValidWidth(rpt.PageSettings));//打印空间宽度 if (m_printWidth==-1)m_printWidth=DesignOptions.DefaultPrintWidthByNewReport;//默认宽度 m_printWidthScale=this .Settings.AutoScaleFieldsSizeByPaperSpace?CalcSacleWidth(m_printWidth):1; }
protected SizeFGetFieldSize(ReportFieldfield,bool fixFieldHeight) { return GetFieldSize(field,fixFieldHeight,this .DefaultHeight); } protected SizeFGetFieldSize(ReportFieldfield,float customHeight) { return GetFieldSize(field,false ,customHeight); } protected SizeFGetFieldSize(ReportFieldfield,bool fixFieldHeight,float fixHeight) { return new SizeF(RoundTowDecimals(CalcInchByFontSize(field.Width)*PrintWidthScale),fixFieldHeight?fixHeight:(this .HasBandeds&&field.ParentBanded==null ?fixHeight*2:fixHeight)); } /// ///按文本和字体获取控件的大小,不适合于字段 /// /// 文本 /// 字体 /// 是否返回字体高度,否则返回默认高度 /// protected SizeFGetSize(string text,Fontfont,bool customHeight) { Graphicsg=Owner.CreateGraphics(); using (g) { SizeFresult=g.MeasureString(text,font); return new SizeF(RoundTowDecimals(CalcInchByFontSize(result.Width)*PrintWidthScale),(customHeight?ConvertToInch(result.Height):this .DefaultHeight)); } } /// ///计算固定带宽的总宽度 /// /// 字段的固定带宽 /// public SizeFGetBandedSize(ReportFieldbanded) { float totalWidth=0; foreach (ReportFieldfieldin this .Fields) { if (field.ParentBanded.Equals(banded))totalWidth+=GetFieldSize(field,true ).Width; } return new SizeF(totalWidth,this .DefaultHeight); } public float CalcSacleWidth(float printWidth) { float totalWidth=0; foreach (ReportFieldfieldin this .Fields) { if (field.Visible==false )continue ; totalWidth+=field.Width; } if (Groups!=null ) { int count=Groups.VisibleCount; if (count>1)totalWidth+=(count-1)*(DEFAULT_GROUP_LEFT*100); } float result=printWidth/ConvertToInch(totalWidth); if (result<0)result=1; return result; } public static float RoundTowDecimals(float value ) { return (float )(decimal .Round((decimal )value ,DEFAULT_ROUND_DECIMALS,MidpointRounding.AwayFromZero)); } /// ///将像素转到到英寸 /// /// 像素 /// public float ConvertToInch(float fieldDPI) { return fieldDPI/100; } /// ///计算字段的实际宽度(英寸,不应用缩放比例) /// /// 像素 /// protected float CalcInchByFontSize(float fieldDPI) { float inchWidth=ConvertToInch(fieldDPI); float multiple=0; if (this .Settings.ReportFont.Size>=11)multiple=0.5f; else if (this .Settings.ReportFont.Size>=10)multiple=0.2f; else if (this .Settings.ReportFont.Size>=9)multiple=0.1f; return inchWidth+(inchWidth*multiple); }
代码太多!只贴核心方法,需要完整代码的请联系
CreateDynamicReportCoreSourceCode
///
///获取动态报表
///
public
ActiveReport3CreateDynamicReport()
{
bool
buildingEvent=ReportFieldsBuilding!=null
;
bool
cancelBuild=false
;
if
(this
.Fields.Count==0)throw
new
NullReferenceException("报表可选字段为空!
");
int
visibleFieldsCount=this
.Fields.VisibleCount;
if
(visibleFieldsCount==0)throw
new
NullReferenceException("报表已选字段为空!
");
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.CreateReport,out
cancelBuild))return
null
;
DataDynamics.ActiveReports.ActiveReport3rpt=new
DataDynamics.ActiveReports.ActiveReport3();
rpt.Name="rptDynamicReport
";
rpt.MasterReport=this
.Settings.OptionsHeader.LogoStatus!=LogoTypeEnum.None;
try
{
int
visibleGroupsCount=Groups==null
?0:this
.Groups.VisibleCount;
int
visibleSummariesCount=Summaries==null
?0:this
.Summaries.VisibleCount;
this
.BeginBuild(rpt);
/***************************初始化段落******************************/
if
(visibleGroupsCount>0)
{
//-------------------------------------------------------创建分组
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.CreateGF,out
cancelBuild))return
null
;
groupHeaders=new
System.Collections.ArrayList();
groupFooters=new
System.Collections.ArrayList();
int
groupIndex=1;
bool
visibleGroupFooter=Settings.SummarySectionAt==ReportSummarySection.GroupAndLastPageFooter&&visibleSummariesCount>0;
foreach
(ReportFieldgroupFieldin
this
.Groups)
{
if
(groupField.Visible==false
)continue
;
string
ghName=SectionType.GroupHeader.ToString()+groupIndex.ToString();
string
gfName=SectionType.GroupFooter.ToString()+groupIndex.ToString();
GroupHeadergh=new
GroupHeader();
gh.Name=ghName;
gh.Height=this
.DefaultHeight+DEFAULT_GROUP_TOP;
gh.DataField=groupField.DataField;
gh.GroupKeepTogether=GroupKeepTogether.All;
gh.KeepTogether=true
;
gh.RepeatStyle=RepeatStyle.OnColumn;
groupHeaders.Add(gh);
GroupFootergf=new
GroupFooter();
gf.Name=gfName;
gf.Height=gh.Height;
gf.Visible=visibleGroupFooter;
groupFooters.Add(gf);
groupIndex++;
}
}
/***************************初始化页宽******************************/
rpt.PrintWidth=this
.PrintWidth;
/***************************初始化页眉******************************/
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.InitPH,out
cancelBuild))return
null
;
if
(Settings.OptionsHeader.LogoStatus!=LogoTypeEnum.None)
{
//-------------------------------------------------------创建LOGO
SubReportsubReport=new
SubReport();
subReport.Name="subReport_TitleLogo
";
subReport.CanGrow=true
;
subReport.CanShrink=true
;
subReport.CloseBorder=false
;
CIMS.Report.Utility.Utils.SetHeaderSubReport(subReport);
if
(Settings.OptionsHeader.LogoStatus==LogoTypeEnum.LargeCard)
subReport.Report=Utility.Utils.CreateHeaderSubReport(Settings.PublicSet.ReportHeaderLogo);
else
subReport.Report=new
Headers.HeaderSZ_Small();
subReport.Report.Run();
subReport.ReportName=subReport.Report.Name;
subReport.Location=new
System.Drawing.PointF(0,0);
this
.PageHeader.Controls.Add(subReport);
}
//-------------------------------------------------------创建标题
if
(string
.IsNullOrEmpty(Settings.OptionsHeader.TitleText)==false
)
{
LabellabTitle=new
Label();//创建正标题栏
labTitle.Name="labTitle
";
labTitle.Border.BottomStyle=BorderLineStyle.ExtraThickSolid;//加粗实线
labTitle.Font=Settings.ReportFontTitle;
labTitle.Text=Settings.OptionsHeader.TitleText;
labTitle.Alignment=TextAlignment.Center;
labTitle.VerticalAlignment=VerticalTextAlignment.Middle;
SizeFs=GetSize(labTitle.Text,labTitle.Font,true
);
s.Width+=0.45f;
labTitle.Size=s;
labTitle.Location=new
PointF((rpt.PrintWidth/2)-(s.Width/2),0);
this
.PageHeader.Controls.Add(labTitle);
if
(string
.IsNullOrEmpty(Settings.OptionsHeader.TitleSubText)==false
)
{
LabellabSubTitle=new
Label();////创建子标题栏
labSubTitle.Name="labSubTitle
";
labSubTitle.Font=Settings.ReportFontSubTitle;
labSubTitle.Text=Settings.OptionsHeader.TitleSubText;
labSubTitle.Alignment=TextAlignment.Left;
labSubTitle.VerticalAlignment=VerticalTextAlignment.Middle;
labSubTitle.ForeColor=SystemColors.ControlDarkDark;
s=GetSize(labSubTitle.Text,labSubTitle.Font,true
);
s.Width+=0.45f;
labSubTitle.Size=s;
labSubTitle.Location=new
PointF(labTitle.Left+labTitle.Width+0.1f,labTitle.Height-s.Height);
this
.PageHeader.Controls.Add(labSubTitle);
}
}
float
initFieldLeft=0;
/***************************初始化分组******************************/
if
(visibleGroupsCount>0)
{
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.InitFieldsHeaderInGH,out
cancelBuild))return
null
;
int
groupIndex=1;
foreach
(ReportFieldgroupFieldin
this
.Groups)
{
if
(groupField.Visible==false
)continue
;
string
ghName=SectionType.GroupHeader.ToString()+groupIndex.ToString();
GroupHeadergh=GetGroupHeader(ghName);
CreateGroupField(gh,groupField,groupIndex);//创建分组控件
groupIndex++;
}
GroupHeaderlastGH=(GroupHeader)GroupHeaders[GroupHeaders.Count-1];//最后分组,用于创建明细字段的标题
lastGH.Controls[0].Border.BottomStyle=BorderLineStyle.None;
lastGH.Controls[1].Border.BottomStyle=BorderLineStyle.None;
initFieldLeft=lastGH.Controls[0].Left;//于分组中的第一个控件对齐
CreateFieldsHeader(lastGH,initFieldLeft);
}
else
{
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.InitFieldsHeaderInPH,out
cancelBuild))return
null
;
CreateFieldsHeader(this
.PageHeader,initFieldLeft);
}
/***************************创建明细字段******************************/
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.InitFieldsInDetail,out
cancelBuild))return
null
;
this
.CreateDetailFields(initFieldLeft);
/*************************创建页脚统计字段****************************/
if
(visibleSummariesCount>0)
{
if
(visibleGroupsCount>0&&this
.Settings.SummarySectionAt==ReportSummarySection.GroupAndLastPageFooter)
{
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.InitSummariesInGF,out
cancelBuild))return
null
;
GroupFootergf=(GroupFooter)this
.GroupFooters[this
.GroupFooters.Count-1];//统计放最后一个分组段尾
gf.Height=this
.DefaultHeight;
this
.CreateFieldsSummaries(gf,initFieldLeft,true
);
}
if
(this
.PageFooter.Height<this
.DefaultHeight)this
.PageFooter.Height=this
.DefaultHeight;
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.InitSummariesInPF,out
cancelBuild))return
null
;
this
.CreateFieldsSummaries(this
.PageFooter,initFieldLeft,false
);
}
/*********************创建页脚签名栏和报表信息************************/
if
(this
.Settings.OptionsFooter.CanCreatePageFooter)
{
if
(buildingEvent&&OnRaiseReportBuildingEvent(ReportBuildActive.InitPF,out
cancelBuild))return
null
;
if
(visibleSummariesCount>0&&this
.PageFooter.Height<(this
.DefaultHeight*2+0.1f))this
.PageFooter.Height=this
.DefaultHeight*2+0.1f;
this
.CreatePageFooterInfos();
}
return
rpt;
}
catch
(Exceptionerr)
{
Common.ExceptionMessenger.OnThrowError(err.StackTrace,err);
if
(rpt!=null
)rpt.Dispose();
return
null
;
}
finally
{
if
(cancelBuild)
{
if
(rpt!=null
)rpt.Dispose();
}
else
{
if
(rpt!=null
)
{
try
{
this
.EndBuild(rpt);
}
catch
{}
}
}
}
}
带分组段落和条件格式的动态报表:
带固定带宽和条件格式及页脚统计的动态报表:
v1.1新增功能:
1,现在能创建主从动态报表了!
2,新增表头数据项目设计器以更好的支持主从报表的动态创建:
3,新增一个报表生成向导,从UI来看,WPF技术带来的UI视觉效果果然非同一般!
4,新增水印设计器:
v1.1增强功能和修改:
1,现在Form支持调整大小了!
2,现在报表支持动态图章和水印了!
相关文章推荐
- JS小功能(操作Table--动态添加删除表格及数据)实现代码
- JS小功能(操作Table--动态添加删除表格及数据)实现代码
- jQuery实现仿Excel表格编辑功能 - Handsontable
- JS实现动态表格的添加,修改,删除功能(推荐)
- 利用SQL*PLUS导出成EXCEL和html的功能实现报表统计:
- jQuery实现表格元素动态创建功能
- Jquery实现表格元素的动态创建功能
- jQuery实现的简单动态添加、删除表格功能示例
- JavaScript动态实现表格添加、删除、插入、上移、下移一行功能
- Excel:利用Excel内置功能实现对某列表格按照条件进行升降序排列——Jason niu
- jQuery+ajax实现动态添加表格tr td功能示例
- 实现类Excel表格编辑功能的jQuery插件:Handsontable
- 使用Aspose.Cell控件实现Excel高难度报表的生成(一)导出表格控件
- jQuery仿Excel表格编辑功能的实现代码
- 水晶报表导出为pdf, word , excel 格式(已经测试过,实现了该功能)
- thinkPHP+phpexcel实现excel报表输出功能示例
- 利用jquery实现动态表格的相关操作以及列表全选功能
- 使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
- 报表导出到word或者excel的功能实现
- Java实现POI导出Excel报表功能