WinForm界面开发之酒店管理系统--报表篇
报表模块几乎是各种大小管理系统都是必不可少的一个模块,而往往报表都需要有数据查看、打印、导出、数据汇总等方面,原本我在准备做酒店管理系统的时候,曾经考虑过试用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
如果你有好的建议或想法,欢迎大家进行沟通交流。