报表模块几乎是各种大小管理系统都是必不可少的一个模块,而往往报表都需要有数据查看、打印、导出、数据汇总等方面,原本我在准备做酒店管理系统的时候,曾经考虑过试用ActiveReport报表控件的,因为我以前的送水管理系统就是采用这个来做报表的,因此曾经写过一篇文章《
ActiveReport报表开发---谈谈ActiveReport的中文化问题
》,提前为做中文报表做准备。

做ActiveReport的报表,大致需要下面几个步骤,设计好报表表现内容的文件,设计一个通用的窗体用来实现Preview功能的报表查看窗体,再设计一个通用的报表函数进行统一调用,如下所示:



代码


///

<summary>


///
提供通用的打印函数

///

</summary>


///

<param name="rpt1"></param>


///

<param name="ds"></param>



public

void
PrintPreview(ActiveReport3 rpt1,
ref
DataSet ds)
{

try

{
FrmPrintPreview frm

=

new
FrmPrintPreview();
frm.StartPosition

=
FormStartPosition.CenterScreen;

//
frm.Dock = DockStyle.Fill;

//
frm.WindowState = FormWindowState.Maximized;


frm.Show();
rpt1.DataSource

=
ds.Tables[
0
];

//
rpt1.DataMember = cmbQuery.Text;


rpt1.Run();
frm.arvMain.Document

=
rpt1.Document;
}

catch
(Exception ex)
{
MessageUtil.ShowError(ex.Message);
}
}

这样通过报表文件和界面的数据源,就可以实现报表的显示了。

不过由于这种方式,必须为每个报表都设计一个报表文件,如下所示。

最后得到的报表界面大致如下所示。

使用这个ActiveReport来实现我的报表功能的话,这样如果我的报表非常多,那么这个工作量就比较吓人了,最后还是放弃了这种方式,采用了改造我的分页控件的方式来实现,既可以方便数据的展示,有可以继承了报表预览打印、导出等功能,而且这样做的好处就是,我省却了不用设计那么多报表格式文件的时间,并且总体效果也非常不错。

在我前面的文章有介绍过Winform分页控件的内容《
WinForm界面开发之“分页控件”
》,该控件集成了分页、导出Excel、打印、右键菜单等操作,我唯一需要改造的主要就是不用分页功能,然后在增加一些细微的修改就可以了。先看看我的酒店管理系统中的一些报表界面吧。




总体上就是我们一般报表所需要的功能。其中报表打印预览可以设置报表标题,打印的列也可以设定,有一些字段的汇总功能,而且这样的报表基本上不需要额外的代码就能实现(相对分页控件来说)。

下面我们来看看我这个控件大致的代码实现。

首先在Form窗体初始化的时候,指定该控件所需要的一些载体,如空的菜单控件、空的Progressbar进度条控件。



代码


private

void
KFTopTradeReport_Load(
object
sender, EventArgs e)
{
InitDictItem();


this
.winGridView1.ProgressBar
=

this
.toolStripProgressBar1.ProgressBar;

this
.winGridView1.AppendedMenu
=

this
.contextMenuStrip1;


this
.dtStart.Value
=
Convert.ToDateTime(DateTime.Now.ToString(
"
yyyy-MM-dd 00:00:00
"
));

this
.dtEnd.Value
=
Convert.ToDateTime(DateTime.Now.ToString(
"
yyyy-MM-dd 23:59:59
"
));

}

然后在所需要的地方,如按钮、更新操作,调用下面的函数就可以了。



代码


private

void
BindItemCateData()
{

#region
添加别名解析


this
.winGridView1.AddColumnAlias(
"
Rank
"
,
"
名次
"
);

this
.winGridView1.AddColumnAlias(
"
ItemName
"
,
"
项目名称
"
);

this
.winGridView1.AddColumnAlias(
"
Price
"
,
"
商品单价
"
);

this
.winGridView1.AddColumnAlias(
"
Quantity
"
,
"
销售数量
"
);

this
.winGridView1.AddColumnAlias(
"
OriginalAmount
"
,
"
销售总额
"
);

this
.winGridView1.AddColumnAlias(
"
OfferMoney
"
,
"
优惠金额
"
);

this
.winGridView1.AddColumnAlias(
"
Amount
"
,
"
折后金额
"
);

#endregion



#region
条件检索


SearchCondition condition

=

new
SearchCondition();
condition.AddCondition(

"
ItemType
"
,
this
.txtStatisticItem.Text, SqlOperator.Like)
.AddCondition(

"
BeginTime
"
,
this
.dtStart.Value.ToString(), SqlOperator.MoreThanOrEqual)
.AddCondition(

"
BeginTime
"
,
this
.dtEnd.Value.ToString(), SqlOperator.LessThanOrEqual);

string
filter
=
condition.BuildConditionSql();


int
topCount
=
Convert.ToInt32(
this
.txtTopCount.Text);

#endregion


DataTable dt

=
BLLFactory
<
ConsumerList
>
.Instance.GetTopTradeReport(topCount, filter);

int
i
=

1
;

foreach
(DataRow row
in
dt.Rows)
{
row[

"
Rank
"
]
=
i
++
;
//
修改名次信息


}

#region
增加汇总信息


if
(dt.Rows.Count
>

0
)
{
DataRow dr

=
dt.NewRow();
dr[

"
ItemName
"
]
=

string
.Format(
"
项目数:{0}
"
, dt.Rows.Count);

decimal
Price
=
0M;

decimal
Quantity
=
0M;

decimal
OriginalAmount
=
0M;

decimal
OfferMoney
=
0M;

decimal
Amount
=
0M;

foreach
(DataRow row
in
dt.Rows)
{
Price

+=
Convert.ToDecimal(row[
"
Price
"
]);
Quantity

+=
Convert.ToDecimal(row[
"
Quantity
"
]);
OriginalAmount

+=
Convert.ToDecimal(row[
"
OriginalAmount
"
]);
OfferMoney

+=
Convert.ToDecimal(row[
"
OfferMoney
"
]);
Amount

+=
Convert.ToDecimal(row[
"
Amount
"
]);
}
dr[

"
Price
"
]
=
Price;
dr[

"
Quantity
"
]
=
Quantity;
dr[

"
OriginalAmount
"
]
=
OriginalAmount;
dr[

"
OfferMoney
"
]
=
OfferMoney;
dr[

"
Amount
"
]
=
Amount;

dt.Rows.Add(dt.NewRow());
dt.Rows.Add(dt.NewRow());
dt.Rows.Add(dr);
}

#endregion


this
.winGridView1.DataSource
=
dt.DefaultView;

this
.winGridView1.PrintTitle
=
Portal.gc.gAppUnit
+

"
--
"

+

"
客房按项目类别统计报表
"
;
}


以上代码,和分页控件一样,就是对显示的字段进行中文的转义显示,构造查询条件并检索数据,汇总报表内容,然后绑定到自定义控件上,就可以了。

其中检索的代码大致如下所示就可以了,返回的DataTable,当然,如果你的数据源是实体类集合,如List<MyInfo>()的格式数据源,一样正常显示的。



代码


///

<summary>


///
获取贸易排行报表

///

</summary>


///

<param name="condition"></param>


///

<returns></returns>



public
DataTable GetTopTradeReport(
int
topCount,
string
condition)
{

string
sql
=

string
.Format(
@"
select top {0} '0' as Rank, ItemName, Price,
sum(Quantity) Quantity,sum(Price*Quantity) OriginalAmount,sum((Price-DiscountPrice)*Quantity) OfferMoney,sum(Amount) Amount
from KF_ConsumerList {1} And ItemName <> '部分结账'
group by ItemName,Price order by Sum(Quantity) DESC

"
, topCount, condition);


return

base
.SqlTable(sql);
}

我们说看到的就是,基本上所有的报表展示,都不需要关注报表预览的问题,只是关注如何在GridView控件中显示就可以了,因为打印和导出,都是集中管理的。

最后,呈上我所封装的控件,大家可以直接过来使用就可以了,没有任何限制。

分页控件、报表显示控件:
https://files.cnblogs.com/wuhuacong/WinformControl.rar

如果你有好的建议或想法,欢迎大家进行沟通交流。

标签: none

添加新评论