Excel導出
Excel導出的意義
因為在項目中有些報表數據客戶需要導出功能,那么導出為Excel就十分有必要了,可是有些客戶的機器上並沒有安裝Excel或者安裝的版本參差不一。
那么我們在這樣的情況下應該應該怎么做呢?最簡單的方法就是引用Excel相關的Com組件就行了,可是這種情況只能在安裝了Excel的用戶適用,
對於沒有安裝Excel的用戶不能強制用戶安裝吧。那么我們只能將眼光瞄向第三方的類庫了,能用的Excel操作導出類庫大致有這么三個
- NPOI
- ExcelRepor
-
aspose.cells
好的,廢話不多說,接下來就將這幾種導出方法一一道來:首先我們模擬一個數據源

1 private DataTable dt = new DataTable(); 2 3 /// <summary> 4 /// 裝載數據 5 /// </summary> 6 private void Inidata() 7 { 8 dt.TableName = "student"; 9 dt.Columns.Add("Name", typeof(string)); 10 dt.Columns.Add("Team", typeof(string)); 11 DataRow dr = dt.NewRow(); 12 DataRow dr1 = dt.NewRow(); 13 dr["Name"] = "科比"; 14 dr["Team"] = "湖人"; 15 dt.Rows.Add(dr); 16 dr1["Name"] = "詹姆斯"; 17 dr1["Team"] = "騎士"; 18 dt.Rows.Add(dr1); 19 list.Add(new Student { Name = "科比", Team = "湖人" }); 20 list.Add(new Student { Name = "詹姆斯", Team = "騎士" }); 21 }
使用NPOI導出
NPOI 是 POI 項目的 .NET 版本。具體的信息請自行百度。下邊是我們公司用的一個NPOI到處的Helper中的片段

1 public class NPOIExportExclHelper 2 { 3 /// <summary> 4 /// 創建一個Excel 5 /// Yakecan 6 /// </summary> 7 /// <returns>返回一個空表格</returns> 8 public HSSFWorkbook InitializeWorkBook() 9 { 10 HSSFWorkbook workBook = new HSSFWorkbook(); 11 DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation(); 12 SummaryInformation si = PropertySetFactory.CreateSummaryInformation(); 13 14 dsi.Company = "河南xx軟件科技有限公司"; 15 dsi.Manager = "Office Word 2003/2007"; 16 17 si.Author = "www.henanluheng.com"; 18 si.Subject = "信息導出"; 19 si.Title = "系統報表"; 20 21 workBook.DocumentSummaryInformation = dsi; 22 workBook.SummaryInformation = si; 23 24 return workBook; 25 } 26 27 28 /// <summary> 29 /// 把指定的DataTable導出Excel 30 /// Yakecan 31 /// </summary> 32 /// <param name="dt">數據源</param> 33 /// <param name="path">導出的路徑(包含文件的名稱及后綴名)</param> 34 /// <param name="tittle">Sheet的名稱</param> 35 public void Export(DataTable dt, string path, string tittle) 36 { 37 HSSFWorkbook workbook = InitializeWorkBook(); 38 ISheet sheet1 = workbook.CreateSheet(tittle); 39 40 IRow titleRow = sheet1.CreateRow(0); 41 titleRow.Height = (short)20 * 25; 42 43 ICellStyle titleStyle = workbook.CreateCellStyle(); 44 titleStyle.Alignment = HorizontalAlignment.Center; 45 titleStyle.VerticalAlignment = VerticalAlignment.Center; 46 IFont font = workbook.CreateFont(); 47 font.FontName = "宋體"; 48 font.FontHeightInPoints = (short)16; 49 titleStyle.SetFont(font); 50 51 NPOI.SS.Util.CellRangeAddress region = new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dt.Columns.Count); 52 sheet1.AddMergedRegion(region); // 添加合並區域 53 54 ICell titleCell = titleRow.CreateCell(0); 55 titleCell.CellStyle = titleStyle; 56 titleCell.SetCellValue(tittle); 57 58 59 IRow headerRow = sheet1.CreateRow(1); 60 ICellStyle headerStyle = workbook.CreateCellStyle(); 61 headerStyle.Alignment = HorizontalAlignment.Center; 62 headerStyle.VerticalAlignment = VerticalAlignment.Center; 63 headerStyle.BorderBottom = BorderStyle.Thin; 64 headerStyle.BorderLeft = BorderStyle.Thin; 65 headerStyle.BorderRight = BorderStyle.Thin; 66 headerStyle.BorderTop = BorderStyle.Thin; 67 IFont titleFont = workbook.CreateFont(); 68 titleFont.FontHeightInPoints = (short)11; 69 titleFont.FontName = "宋體"; 70 headerStyle.SetFont(titleFont); 71 72 headerRow.CreateCell(0).SetCellValue("序號"); 73 headerRow.GetCell(0).CellStyle = headerStyle; 74 75 for (int i = 0; i < dt.Columns.Count; i++) 76 { 77 headerRow.CreateCell(i + 1).SetCellValue(dt.Columns[i].ColumnName); 78 headerRow.GetCell(i + 1).CellStyle = headerStyle; 79 sheet1.SetColumnWidth(i, 256 * 18); 80 } 81 82 ICellStyle bodyStyle = workbook.CreateCellStyle(); 83 bodyStyle.BorderBottom = BorderStyle.Thin; 84 bodyStyle.BorderLeft = BorderStyle.Thin; 85 bodyStyle.BorderRight = BorderStyle.Thin; 86 bodyStyle.BorderTop = BorderStyle.Thin; 87 for (int r = 0; r < dt.Rows.Count; r++) 88 { 89 IRow bodyRow = sheet1.CreateRow(r + 2); 90 bodyRow.CreateCell(0).SetCellValue(r + 1); 91 bodyRow.GetCell(0).CellStyle = bodyStyle; 92 bodyRow.GetCell(0).CellStyle.Alignment = HorizontalAlignment.Center; 93 94 for (int c = 0; c < dt.Columns.Count; c++) 95 { 96 bodyRow.CreateCell(c + 1).SetCellValue(dt.Rows[r][c].ToString()); 97 bodyRow.GetCell(c + 1).CellStyle = bodyStyle; 98 } 99 } 100 101 sheet1.CreateFreezePane(1, 2); 102 103 FileStream fs = new FileStream(path, FileMode.Create); 104 workbook.Write(fs); 105 fs.Flush(); 106 fs.Position = 0; 107 sheet1 = null; 108 headerRow = null; 109 workbook = null; 110 //OutPutExcelStreamOnClient(ms, xlsName); 111 fs.Dispose(); 112 } 113 114 115 }
好了,接下來讓我們來使用一下這個導出的功能,導出代碼如下,這些沒什么技術含量,F5啟動程序查看導出的效果
1 SaveFileDialog savedialog = ShowExportExcelDoalog(); 2 savedialog.FileName = "這是我的測試數據"; 3 if (savedialog.ShowDialog() == DialogResult.OK) 4 { 5 NPOIExportExclHelper excelHelper = new NPOIExportExclHelper(); 6 excelHelper.Export(dt, savedialog.FileName, "這是我的測試數據"); 7 }
OK,這是我們導出的效果圖,自動為我們加上了序號這一列,不過整體來說導出的功能還是沒有任何問題。不過還是有一點瑕疵,數據的列名還是英文,解決方法也很簡單只要我們設置數據源的dt的列頭名設置為中國文就行了,dt.Columns["Name"].ColumnName = "姓名"; 設置完成再導出就沒問題了。對於我們直男程序員來說這樣大致差不多也就完成了任務,可是這樣的效果對於真正的生產環境來說還是不行的,因為有些客戶還要求導出的Excel要有格式,比如標題高亮啊、數據行每行顏色的高亮。這些怎么辦呢,這就用到接下來的方法了。
使用ExcelReport和模板導出
使用模板導出Excel可以實現Excel的數據和樣式的分離,雖然NPOI也可以導出的時候設置樣式但是代碼比較繁瑣。
ExcelReport是博客園的一個大神韓兆新搗鼓出來的一個小工具。在QQ群中作者對於使用者遇到的問題和意見還是反饋的很積極的,這點要給作者點個贊的。關於這個控件的具體詳細方法還請大家參考作者的一系列博客,下面只是給你導出的最基本的代碼。
首先是我們的模板格式
導出代碼如下
1 SaveFileDialog saveFileDlg = new SaveFileDialog(); 2 saveFileDlg.Filter = "Excel 2003文件|*.xls|Excel 2007文件|*.xlsx"; 3 4 if (DialogResult.OK.Equals(saveFileDlg.ShowDialog())) 5 { 6 //實例化一個參數容器,並加載模板填充規則文件 7 8 ParameterCollection collection = new ParameterCollection(); 9 10 collection.Load(@"Templete\excelreport.xml"); 11 //實例化一個元素格式化器列表 12 13 List<ElementFormatter> formatters = new List<ElementFormatter>(); 14 15 formatters.Add(new CellFormatter(collection["Sheet1", "time"], "第一次")); //添加一個單元格格式化器 16 //添加一個Table格式化器 17 formatters.Add(new TableFormatter<Student>(collection["Sheet1", "Name"].X, list, 18 new TableColumnInfo<Student>(collection["Sheet1", "Name"].Y, t => t.Name), 19 new TableColumnInfo<Student>(collection["Sheet1", "Team"].Y, t => t.Team)) 20 ); 21 22 //導出文件到本地 23 ExportHelper.ExportToLocal(@"Templete\excelreport.xls", saveFileDlg.FileName, 24 new SheetFormatterContainer("Sheet1", formatters));
使用aspose.cells和模板導出
Aspose是一個非常強大的“收費控件”,我們要用到的是aspose.cells,這個控件的使用不需要引用其他別的控件,其次代碼也非常簡單。具體的使用方法參考Aspose.Cells 根據Excel模板導出數據統計
模板如下
1 WorkbookDesigner designer = new WorkbookDesigner(); 2 //Server.MapPath("./") 3 string path = System.AppDomain.CurrentDomain.BaseDirectory + "/Templete/aspose.xls"; 4 designer.Open(path); 5 designer.SetDataSource(dt); 6 designer.Process(); 7 //Save the excel file 8 string fileToSave = System.AppDomain.CurrentDomain.BaseDirectory + "Templete/JH_ManageExcel.xls"; 9 if (File.Exists(fileToSave)) 10 { 11 File.Delete(fileToSave); 12 } 13 14 designer.Save(fileToSave, FileFormatType.Excel2003); 15 //打開Excel文件 16 Process.Start(fileToSave);
總結
本文只是簡單的介紹幾種Excel的導出方法,並沒有具體的深入研究。這三種方式各有各的特點,第一種方法比較通用,適合那些需要多種導出且對導出的樣式沒有要求的項目,后邊兩種適合那些對導出數據有樣式需求的項目。第二種方式所用的類庫開源、免費但是代碼比較繁瑣,且還需要生成Xml的配置文件使起來還是比較麻煩,第三種使用起來最好、最簡便,不過需要收費。如果用在商業項目中還是需要斟酌的。