本人在項目中用到導出,以前幾乎沒做過導出導入這類的功能,最近自己獨立開發了幾個項目,都用到了導出,於是便來一篇文章,記錄一下,方便以后查找,也方便各位新手!
例子比較簡單,不喜勿噴,如果有其它補充,請留言!謝謝!以下導出采用的是導出DataTable,沒有做過多復雜的!
1. NPOI 幫助類,我使用的是 V2.3.0,改造的代碼:

using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.SS.Util; using NPOI.XSSF.UserModel; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Text; namespace bmy.Common { public static class NPOIExcelHelper { /// <summary> /// 組裝workbook. /// </summary> /// <param name="dictionary">列頭</param> /// <param name="dt">dataTable數據</param> /// <param name="columnHeader">表頭</param> /// <returns></returns> public static HSSFWorkbook BuildWorkbook1(Dictionary<string, string> dictionary, DataTable dt, string columnHeader = "") { var workbook = new HSSFWorkbook(); ISheet sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName); var dateStyle = workbook.CreateCellStyle(); var format = workbook.CreateDataFormat(); dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); //取得列寬 // var arrColWidth = new int[dt.Columns.Count]; var arrColWidth = new int[dictionary.Count + 1]; int itemCoutn = 0;//需要導出的列的數量. foreach (DataColumn item in dt.Columns) { //判斷需要導出的 “列” if (dictionary.ContainsKey(item.ColumnName)) { arrColWidth[itemCoutn] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length; itemCoutn++; } } itemCoutn = 0; for (var i = 0; i < dt.Rows.Count; i++) { for (var j = 0; j < dt.Columns.Count; j++) { //判斷需要導出的 “列” if (dictionary.ContainsKey(dt.Rows[i][j].ToString())) { int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length; if (intTemp > arrColWidth[j]) { arrColWidth[j] = intTemp; } } } } int rowIndex = 0;//行索引,第一行為:表頭(列頭) foreach (DataRow row in dt.Rows) { #region 表頭 列頭 if (rowIndex == 65535 || rowIndex == 0) { if (rowIndex != 0) { sheet = workbook.CreateSheet(); } #region 表頭及樣式 { IRow headerRow = sheet.CreateRow(0); headerRow.HeightInPoints = 19.5F; headerRow.Height = 40 * 20; headerRow.CreateCell(0).SetCellValue(columnHeader); //CellStyle ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中 headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 // 設置單元格的背景顏色(單元格的樣式會覆蓋列或行的樣式) headStyle.FillForegroundColor = (short)11; //定義font IFont font = workbook.CreateFont(); font.FontHeightInPoints = 20; font.Boldweight = 700; headStyle.SetFont(font); headerRow.GetCell(0).CellStyle = headStyle; //根據表的列數計算 //sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dt.Columns.Count - 1)); sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dictionary.Count)); #endregion } { #region 列頭及樣式 var headerRow = sheet.CreateRow(1); //CellStyle ICellStyle headStyle = workbook.CreateCellStyle(); headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中 headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 //定義font IFont font = workbook.CreateFont(); font.FontHeightInPoints = 10; font.Boldweight = 700; headStyle.SetFont(font); int columnCount = 0; foreach (var dic in dictionary) { foreach (DataColumn column in dt.Columns) { //判斷需要導出的 “列” if (dic.Key.ToLower()==column.ColumnName.ToLower()) { //headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName); //headerRow.GetCell(column.Ordinal).CellStyle = headStyle; //sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256); headerRow.CreateCell(columnCount).SetCellValue(dic.Value);//column.ColumnName headerRow.GetCell(columnCount).CellStyle = headStyle; sheet.SetColumnWidth(columnCount, (arrColWidth[columnCount]) * 256); columnCount++; continue; } } } #endregion } rowIndex = 2; } #endregion #region 內容 var dataRow = sheet.CreateRow(rowIndex); int columnContentCount = 0; //column.Ordinal foreach (var dicKey in dictionary) { foreach (DataColumn column in dt.Columns) { //判斷需要導出的 “列” if (dicKey.Key.ToLower()==column.ColumnName.ToLower()) { var newCell = dataRow.CreateCell(columnContentCount); string drValue = row[column].ToString(); switch (column.DataType.ToString()) { case "System.String"://字符串類型 newCell.SetCellValue(drValue); break; case "System.DateTime"://日期類型 DateTime dateV; DateTime.TryParse(drValue, out dateV); newCell.SetCellValue(dateV); newCell.CellStyle = dateStyle;//格式化顯示 break; case "System.Boolean"://布爾型 bool boolV = false; bool.TryParse(drValue, out boolV); newCell.SetCellValue(boolV); break; case "System.Int16"://整型 case "System.Int32": case "System.Int64": case "System.Byte": int intV = 0; int.TryParse(drValue, out intV); newCell.SetCellValue(intV); break; case "System.Decimal"://浮點型 case "System.Double": double doubV = 0; double.TryParse(drValue, out doubV); newCell.SetCellValue(doubV); break; case "System.DBNull"://空值處理 newCell.SetCellValue(""); break; default: newCell.SetCellValue(""); break; } columnContentCount++;//列索引 continue; } } } #endregion rowIndex++; } //自動列寬 for (int i = 0; i <= dictionary.Count; i++) sheet.AutoSizeColumn(i, true); return workbook; } } }
2.調用,先保存數據到文件夾,再將文件返回給調用頁面提供下載,下載完成就刪除文件,節省資源。

public static string WriteSheet(Dictionary<string, string> dictionary, DataTable dt, string path, string sheetName) { HSSFWorkbook newBook = BuildWorkbook1(dictionary, dt, sheetName); string date = DateTime.Now.ToString("yyyyMMddHHmmss"); string fileName = sheetName + "_" + date; #region 保存C:\ExcelList //string urlPath = "\\ExcelList\\" + fileName; //string filePath = urlPath; //string directoryName = Path.GetDirectoryName(urlPath); //if (!Directory.Exists(directoryName)) //{ // Directory.CreateDirectory(directoryName); //} //using (var fs = File.OpenWrite(urlPath + ".xls")) //{ // newBook.Write(fs); // Console.WriteLine("生成成功"); //} #endregion string urlPath2 = "/ExcelList/" + fileName; string directoryName2 = Path.GetDirectoryName(urlPath2); string newUrl = path + directoryName2; if (!Directory.Exists(newUrl)) { Directory.CreateDirectory(newUrl); } using (var fs = File.OpenWrite(path + urlPath2 + ".xls")) { newBook.Write(fs); Console.WriteLine("生成成功"); } return fileName + ".xls"; }
3.頁面調用方法, Dictionary<string, string>的作用就是將要導出的DataTable數據的字段,換成中文名稱,方便閱讀。

Dictionary<string, string> dictionary = new Dictionary<string, string>(); DataTable dt = ExcelExport(1, 10000); if (dt.Rows.Count > 0) { sheetName = "待審核訂單列表"; dictionary.Add("OrderNo", "待審核訂單號"); dictionary.Add("Mobile", "手機號碼"); //返回路徑下載 string path = System.AppDomain.CurrentDomain.BaseDirectory; string fileName = MxWeiXinPF.Common.NPOIExcelHelper.WriteSheet(dictionary, dt, path, sheetName); //文件夾 string folder = "/ExcelList/"; //下載 this.ResponDown(Response, path, folder, fileName);
4.下載方法

/// <summary> /// 下載 /// </summary> /// <param name="response">封裝來自ASP.NET 的http相應消息</param> /// <param name="path">文件路徑</param> /// <param name="folder">文件夾</param> /// <param name="fileName">文件名</param> public void ResponDown(HttpResponse response, string path, string folder, string fileName) { response.Clear(); response.ClearHeaders(); response.Buffer = false; response.ContentType = "application/ms-excel"; response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)); //Response.Write(writer); FileStream file = new FileStream(path + folder + fileName, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader br = new BinaryReader(file); response.AppendHeader("Content-Length", file.Length.ToString()); // StringReader sr = new StringReader(writer.GetStringBuilder().ToString()); long flen = file.Length; int size = 102400;//每100k同時下載數據 byte[] readdata = new byte[size];//指定緩沖區的大小 if (size > flen) size = Convert.ToInt32(flen); long fpos = 0; bool isend = false; while (!isend) { if (response.IsClientConnected) { if ((fpos + size) > flen) { size = Convert.ToInt32(flen - fpos); readdata = new byte[size]; isend = true; } if (size > 1) { br.Read(readdata, 0, size);//讀入一個壓縮塊 // byte[] re = Encoding.UTF8.GetBytes(readdata, 0, readdata.Length); response.BinaryWrite(readdata); //Response.OutputStream.Write(re, 0, size); } fpos += size; } else { response.End(); } } file.Close(); br.Close(); response.Flush(); Response.Close(); File.Delete(path + folder + fileName); //刪除文件 response.End(); }
最后,完成!只是簡單記錄,對於代碼沒有更好的優化,盡量以后整理好點貢獻給大家!