在之前幾篇文章中,介紹了關於Apsose.cell這個強大的Excel操作控件的使用,相關文章如下:
使用Aspose.Cell控件實現Excel高難度報表的生成(一)
使用Aspose.Cell控件實現Excel高難度報表的生成(二)
使用Aspose.Cell控件實現多個Excel文件的合並
這幾篇文章,都對Apose.Cell這個控件生成各種Excel的方式進行了闡述,對直接把DataTable或者IList生成Excel的操作,對通過模板方式實現自定義報表的各種方式,以及多個文件的合並的方式進行了介紹。
本文繼續介紹該控件進一步的使用,也主要介紹如何動態生成(不使用模板文件)各種單元格,以及圖表的增加等功能,介紹生成的表格完全自定義,這個報表時一個典型的圖文並茂的統計報表,它的最終樣式如下所示。
這個報表,表格數據是動態生成,圖形則是直接從窗體的圖表控件(如ZedGraph圖表控件)或者PictureBox控件中獲取,寫入Excel文檔中的。
測試程序主界面如下所示。
和很多其他的Excel操作控件(NPOI、Myxls)一樣嗎,Apose.Cell也提供了WorkBook、WorkSheet、Range、Cell這些對象的包裝,操作這些對象,基本上能夠滿足我們各種復雜的需求,給我們更加彈性化的操作。
1、 添加基本對象進行操作
Workbook workbook = new Workbook(); Worksheet worksheet = workbook.Worksheets[0];
這幾個對象是操作Excel必須的,如果需要設定生成的Excel打印預覽的參數,進行一些屬性設置,如下所示。
Workbook workbook = new Workbook(); Worksheet worksheet = workbook.Worksheets[0]; worksheet.PageSetup.Orientation = PageOrientationType.Landscape;//橫向打印 worksheet.PageSetup.Zoom = 100;//以100%的縮放模式打開 worksheet.PageSetup.PaperSize = PaperSizeType.PaperA4;
我們知道,由於該報表完全是手工生成,報表的標題,以及下面幾行說明文字,也是需要生成的,操作其實就是把一些單元格合並為一個區域(Range),然后賦值,改變樣式就可以了,如下所示的效果和代碼
Range range; Cell cell; int colSpan = 4 + DeptNameList.Count * 2; range = worksheet.Cells.CreateRange(0, 0, 1, colSpan); range.Merge(); range.RowHeight = 20; range.Style = CreateTitleStyle(workbook); cell = range[0, 0]; cell.PutValue("患病情況統計"); range = worksheet.Cells.CreateRange(1, 0, 1, colSpan); range.Merge(); range.RowHeight = 15; cell = range[0, 0]; cell.PutValue("所選部別范圍內,總計有1000名人員,查詢統計結果如下:"); range = worksheet.Cells.CreateRange(2, 0, 1, colSpan); range.Merge(); range.RowHeight = 15; cell = range[0, 0]; cell.PutValue("自2007-1-1開始到現在,統計共有500人有患病史,累計900人次,患病情況如下表:");
2、生成報表頭部表格
報表中最復雜的是表頭的生成,因為它是不規則的表頭,因此需要很細的操作Cell和Range對象,實現復雜表頭(也是很常見的)的生成。
這個是慢工出細活,需要對Cell和Range熟悉使用,然后給他們分配不同的行列就可以生成一個標准如下的表頭了。
Style headStyle = CreateStyle(workbook, true); Style normalStyle = CreateStyle(workbook, false); int startRow = 4; range = worksheet.Cells.CreateRange(startRow, 0, 2, 1); range.Merge(); range.Style = headStyle; cell = range[0, 0]; cell.PutValue("序號"); cell.Style = headStyle; range = worksheet.Cells.CreateRange(startRow, 1, 2, 1); range.Merge(); range.Style = headStyle; range.ColumnWidth = 40; cell = range[0, 0]; cell.PutValue("疾病名稱"); cell.Style = headStyle; int startCol = 2; foreach (string deptName in DeptNameList) { range = worksheet.Cells.CreateRange(startRow, startCol, 1, 2); range.Merge(); range.Style = headStyle; cell = range[0, 0]; cell.PutValue(deptName); cell = worksheet.Cells[startRow + 1, startCol]; cell.PutValue("人次"); cell.Style = headStyle; cell = worksheet.Cells[startRow + 1, startCol + 1]; cell.PutValue("百分比"); cell.Style = headStyle; startCol += 2; } range = worksheet.Cells.CreateRange(startRow, startCol, 1, 2); range.Merge(); range.Style = headStyle; cell = range[0, 0]; cell.PutValue("合計"); cell = worksheet.Cells[startRow + 1, startCol]; cell.PutValue("人次"); cell.Style = headStyle; cell = worksheet.Cells[startRow + 1, startCol + 1]; cell.PutValue("百分比"); cell.Style = headStyle; #endregion
3、填入表格內容
這個不算復雜,只需要遍歷然后生成內容到單元格即可。
//寫入數據到Excel startRow = startRow + 2; for (int i = 0; i < dt.Rows.Count; i++) { startCol = 0; for (int j = 0; j < dt.Columns.Count; j++) { DataRow dr = dt.Rows[i]; cell = worksheet.Cells[startRow, startCol]; cell.PutValue(dr[j]); cell.Style = normalStyle; startCol++; } startRow++; }
4、插入圖表及導出打開操作
這個Apose.Cell控件的WorkSheet提供了worksheet.Pictures.Add方法,可以添加圖片的操作,不過圖片是通過流方式寫入,我們把圖表的Image對象轉換一下,創建一個內存流就可以了。如下所示。
//寫入圖注 startRow += 1;//跳過1行 range = worksheet.Cells.CreateRange(startRow++, 0, 1, colSpan); range.Merge(); range.RowHeight = 15; cell = range[0, 0]; cell.PutValue("以柱狀圖展示如下:"); //插入圖片到Excel里面 byte[] bytes = ImageHelper.ImageToBytes(this.pictureBox1.Image); using (MemoryStream stream = new MemoryStream(bytes)) { worksheet.Pictures.Add(startRow, 0, stream); } //Save the excel file. string saveFile = FileDialogHelper.SaveExcel("rangecells.xls", "C:\\"); if (!string.IsNullOrEmpty(saveFile)) { workbook.Save(saveFile); if (MessageUtil.ShowYesNoAndTips("保存成功,是否打開文件?") == System.Windows.Forms.DialogResult.Yes) { System.Diagnostics.Process.Start(saveFile); } }
至此,基於Apose.Cell的自定義報表的另外一種操作也全部實現了,為了實現這個簡單的例子,以便在項目中使用,花了不少時間,不過以后對於生成這類復雜的和自定義報表,可以直接利用它們基礎的對象進行操作即可;
如果是一些常規的報表,可以利用自定義模板的方式生成,然后綁定數據源;如果是二維表,或者ILIst集合,導出Excel就更簡單了。以上兩種都可以直接利用封裝好的AsposeExcelTools來進行操作,這個通用的類庫,可以省卻每次去編寫代碼的繁瑣,提高效率。