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); } }