FlexCell表格控件有很多亮点的功能,使用也算比较方便,很多时候,可以模拟传统的Excel内容在Winform界面上展现,而且也支持内容格式的预设置等,本文主要介绍利用这个控件来实现一些特殊的统计及关联信息显示的功能。在实际项目中,有一个这样的需求,首先需要显示一些数据的总的汇总数据,每条又可以进一步查看其对应的明细数据,类似于数据仓库的钻取功能,那么我们要如何实现以上的功能呢?
1、报表统计功能介绍
功能介绍如下图所示。
单击链接可以进一步展现相关的人员列表,如下图所示。
2、功能实现思路分析
实现以上功能,如果利用.NET自带的DataGridView,通过在在Cell里面添加链接控件的方式,估计也能实现,不过可能操作起来会比较麻烦一些。
本文主要介绍利用FlexCell 表格控件实现以上操作的思路,共大家参考,并非为该控件做广告。
首先我们需要在为每个条件显示一行记录,对应还要记住它的条件,其中有一个超链接的单元格,供我们单击可以查看明细。为了记住该行的条件,我其实在一个隐藏列里面放置了条件表达式,真实情况下如下所示,只是为了显示美观,不需要显示隐藏的条件内容。
FlexCell提供超链接的单元格类型,设置为超链接类型的单元格,内容会加下划线,而且可以对超链接的事件进行捕捉处理。
得到了响应的处理事件,以及存放了对应的条件描述,那么在事件里,打开一个新窗体,根据条件内容获取对应的列表显示出来即可。
3、功能实现代码
1)绑定相关的汇总数据
Dictionary<string, CListItem> dict = GetAgeCondition(); if (dict.Keys.Count > 0) { grid1.Cell(startRow++, 1).Text = "年龄段情况:"; foreach (string key in dict.Keys) { CListItem item = dict[key]; grid1.Cell(startRow, 2).Text = key; grid1.Cell(startRow, 3).Text = string.Format("有{0}人,占比例{1} ", item.Text, item.Value); grid1.Cell(startRow, 4).Text = string.Format("Age:{0}", key); startRow++; } }
2)超链接处理事件代码
在控件上单击Grid的Hyperlink处理事件,然后实现其内部处理代码,如下所示。
private void grid1_HyperLinkClick(object Sender, FlexCell.Grid.HyperLinkClickEventArgs e) { FlexCell.Cell cell = grid1.Cell(e.Row, 4); if (cell != null && !string.IsNullOrEmpty(cell.Text)) { FrmStatisticDetail dlg = new FrmStatisticDetail(); dlg.KeyCondition = cell.Text; dlg.ShowDialog(); } e.URL = ""; e.Changed = true; }
3)明细窗体处理代码
private void DealAge(string condition, ref int startRow) { grid1.Cell(1, 1).Text += string.Format("(条件:年龄{0})", condition); startRow++; // 设置单元格文字 grid1.Cell(startRow, 1).Text = "年龄"; grid1.Cell(startRow, 2).Text = "编号"; grid1.Cell(startRow, 3).Text = "姓名"; grid1.Cell(startRow, 4).Text = "性别"; grid1.Cell(startRow, 5).Text = "生日"; grid1.Cell(startRow, 6).Text = "职别"; grid1.Cell(startRow, 7).Text = "部别"; grid1.Range(startRow, 1, startRow, 7).BackColor = Color.Yellow; int start = startRow++; string where = "Age " + condition; if(condition.Contains("~")) { string[] conArray = condition.Split('~'); where = string.Format("Age >={0} and Age<={1}", conArray[0], conArray[1]); } DataTable dt = BLLFactory<Pilot>.Instance.FindByView("PilotAgeView", where, "Age", true); foreach (DataRow row in dt.Rows) { grid1.Cell(startRow, 1).Text = row["Age"].ToString(); grid1.Cell(startRow, 2).Text = row["PilotNo"].ToString(); grid1.Cell(startRow, 3).Text = row["Name"].ToString(); grid1.Cell(startRow, 4).Text = row["Sex"].ToString(); DateTime birthday; if (DateTime.TryParse(row["Birthday"].ToString(), out birthday)) { grid1.Cell(startRow, 5).Text = birthday.ToString("yyyy-MM-dd"); } grid1.Cell(startRow, 6).Text = row["OfficialRank"].ToString(); grid1.Cell(startRow, 7).Text = row["DeptCode"].ToString(); startRow++; } FlexCell.Range range = grid1.Range(start, 1, startRow, 7); range.set_Borders(FlexCell.EdgeEnum.Outside | FlexCell.EdgeEnum.Inside, FlexCell.LineStyleEnum.Thin); startRow++; startRow++; }
上面的代码,主要就是动态绘制表头,设置格式,然后绘制表格明细的单元格内容即可。
4)实现打印、导出Excel/PDF等功能
控件内置了很多导出功能,实现基本的导出、打印功能,非常方便,代码如下。
private void menu_Preview_Click(object sender, EventArgs e) { try { grid1.PrintPreview(); } catch (Exception err) { MessageDxUtil.ShowError(err.Message); } } private void menu_PageSetting_Click(object sender, EventArgs e) { try { grid1.ShowPageSetupDialog(); } catch (Exception err) { MessageDxUtil.ShowError(err.Message); } } private void menu_ExportExcel_Click(object sender, EventArgs e) { try { #region 保存Excel文件 SpecialDirectories sp = new SpecialDirectories(); SaveFileDialog dialog = new SaveFileDialog(); dialog.Filter = "Excel(*.xls)|*.xls|All File(*.*)|*.*"; dialog.Title = "保存Excel"; try { dialog.InitialDirectory = sp.Desktop; } catch { dialog.InitialDirectory = "C:\\"; } dialog.RestoreDirectory = true; if (dialog.ShowDialog() == DialogResult.OK) { string fileToSave = dialog.FileName; if (string.IsNullOrEmpty(fileToSave)) { return; } bool success = grid1.ExportToExcel(fileToSave, true, true); if (success) { Process.Start(fileToSave); } } #endregion } catch (Exception err) { MessageDxUtil.ShowError(err.Message); } } /// <summary> /// 导出Excel文件 /// </summary> /// <param name="fileToSave">文件路径</param> /// <returns></returns> public bool ExportExcel(string fileToSave) { bool success = grid1.ExportToExcel(fileToSave, true, true); return success; } private void menu_ExportPDF_Click(object sender, EventArgs e) { try { grid1.PageSetup.DocumentName = "统计报表"; bool success = grid1.ExportToPDF(""); } catch (Exception err) { MessageDxUtil.ShowError(err.Message); } }