概述

  NPOI,顧名思義,就是POI的.NET版本。NPOI就是用.NET語言編寫的一套資料匯出Excel的開源專案,支援XML、xls、xlsx、ppt等格式。.NET不僅實現Excel匯出還可以實現Excel匯入,讀取Excel的資料。

實現

  1、通過nuget,新增NPOI元件1.2以上對應的DLL檔案;

  2、編寫如下Nopi封裝類,該類實現如下功能點

    1> 該類實現資料的超過65535自動分寫下一個sheet;

    2> 該類實現Web資料匯出和檔案儲存到本地;

    3> 該類實現Excel檔案的讀取匯出;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Text;
using NPOI;
using NPOI.HPSF;
using NPOI.HSSF;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.POIFS;
using NPOI.Util;
using System.Data;
using NPOI.SS.UserModel;
using NPOI.SS.Util; namespace DBI.Web.Common
{
public class NpoiHelper
{
/// <summary>
/// DataTable匯出到Excel檔案
/// </summary>
/// <param name="dtSource">源DataTable</param>
/// <param name="strHeaderText">表頭文字</param>
/// <param name="strFileName">儲存位置</param>
public static void Export(DataTable dtSource, string strHeaderText, string strFileName)
{
using (MemoryStream ms = Export(dtSource, strHeaderText))
{
using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
{
byte[] data = ms.ToArray();
fs.Write(data, , data.Length);
fs.Flush();
}
}
} /// <summary>
/// DataTable匯出到Excel的MemoryStream,帶標題和表頭
/// </summary>
/// <param name="dtSource">源DataTable</param>
/// <param name="strHeaderText">表頭文字</param>
public static MemoryStream Export(DataTable dtSource, string strHeaderText)
{
HSSFWorkbook workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(dtSource.TableName) ? "Sheet1" : dtSource.TableName); #region 右擊檔案 屬性資訊 DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company = "NPOI";
workbook.DocumentSummaryInformation = dsi; SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
si.Author = "TCL"; //填加xls檔案作者資訊
si.ApplicationName = "建立程式資訊"; //填加xls檔案建立程式資訊
si.LastAuthor = "最後儲存者資訊"; //填加xls檔案最後儲存者資訊
si.Comments = "作者資訊"; //填加xls檔案作者資訊
si.Title = "標題資訊"; //填加xls檔案標題資訊 si.Subject = "主題資訊";//填加檔案主題資訊
si.CreateDateTime = DateTime.Now;
workbook.SummaryInformation = si; #endregion #region 取得列寬,調整寬度 有待優化,如果資料很多,這個地方就會很耗時 int[] arrColWidth = new int[dtSource.Columns.Count];
foreach (DataColumn item in dtSource.Columns)
{
arrColWidth[item.Ordinal] = Encoding.GetEncoding().GetBytes(item.ColumnName.ToString()).Length;
} for (int i = ; i < dtSource.Rows.Count; i++)
{
for (int j = ; j < dtSource.Columns.Count; j++)
{
int intTemp = Encoding.GetEncoding().GetBytes(dtSource.Rows[i][j].ToString()).Length;
if (intTemp > arrColWidth[j])
{
arrColWidth[j] = intTemp;
}
}
} #endregion var dateStyle = workbook.CreateCellStyle();
var format = workbook.CreateDataFormat();
dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd"); var DataCellStyle = CreateBasicCellStyle(workbook); //計算行數,由於Excel 2003最大條數是65535,超過65535自動建立下一個sheet
int rowIndex = ;
foreach (DataRow row in dtSource.Rows)
{
#region 新建表,填充表頭,填充列頭,樣式
if (rowIndex == || rowIndex == )
{
if (rowIndex != )
{
sheet = workbook.CreateSheet();
} #region 表頭及樣式
{
var headerRow = sheet.CreateRow();
headerRow.HeightInPoints = ;
headerRow.CreateCell().SetCellValue(strHeaderText); ICellStyle headStyle = workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中
headStyle.FillForegroundColor = (short); // 設定單元格的背景顏色(單元格的樣式會覆蓋列或行的樣式)
IFont font = workbook.CreateFont();
font.FontHeightInPoints = ;
font.Boldweight = ;
headStyle.SetFont(font);
headerRow.GetCell().CellStyle = headStyle;
//合併單元格
sheet.AddMergedRegion(new CellRangeAddress(, , , dtSource.Columns.Count - ));
}
#endregion #region 列頭及樣式
{
IRow headerRow = sheet.CreateRow();
ICellStyle headStyle = workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
headStyle.VerticalAlignment = VerticalAlignment.Center;
//定義字型
IFont font = workbook.CreateFont();
font.FontHeightInPoints = ;
font.Boldweight = ;
headStyle.SetFont(font);
foreach (DataColumn column in dtSource.Columns)
{
headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
headerRow.GetCell(column.Ordinal).CellStyle = headStyle; //設定列寬
sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + ) * );
}
}
#endregion rowIndex = ;
}
#endregion #region 填充內容
IRow dataRow = sheet.CreateRow(rowIndex);
foreach (DataColumn column in dtSource.Columns)
{
ICell newCell = dataRow.CreateCell(column.Ordinal);
newCell.CellStyle = DataCellStyle; 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 = ;
int.TryParse(drValue, out intV);
newCell.SetCellValue(intV);
break;
case "System.Decimal"://浮點型
case "System.Double":
double doubV = ;
double.TryParse(drValue, out doubV);
newCell.SetCellValue(doubV);
break;
case "System.DBNull"://空值處理
newCell.SetCellValue("");
break;
default:
newCell.SetCellValue("");
break;
} }
#endregion rowIndex++;
}
using (MemoryStream ms = new MemoryStream())
{
workbook.Write(ms);
ms.Flush();
ms.Position = ;
return ms;
}
} /// <summary>
/// 用於Web匯出
/// </summary>
/// <param name="dtSource">源DataTable</param>
/// <param name="strHeaderText">表頭文字</param>
/// <param name="strFileName">檔名</param>
public static void ExportByWeb(DataTable dtSource, string strHeaderText, string strFileName)
{
HttpContext curContext = HttpContext.Current; // 設定編碼和附件格式
curContext.Response.ContentType = "application/vnd.ms-excel";
curContext.Response.ContentEncoding = Encoding.UTF8;
curContext.Response.Charset = "";
curContext.Response.AppendHeader("Content-Disposition",
"attachment;filename=" + HttpUtility.UrlEncode(strFileName, Encoding.UTF8)); curContext.Response.BinaryWrite(Export(dtSource, strHeaderText).GetBuffer());
curContext.Response.End();
} /// <summary>讀取excel
/// 預設第一行為標頭,Exel匯出Table資料
/// </summary>
/// <param name="strFileName">excel文件路徑</param>
/// <returns></returns>
public static DataTable Import(string strFileName)
{
DataTable dt = new DataTable(); HSSFWorkbook hssfworkbook;
using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
{
hssfworkbook = new HSSFWorkbook(file);
}
ISheet sheet = hssfworkbook.GetSheetAt();
System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); IRow headerRow = sheet.GetRow();
int cellCount = headerRow.LastCellNum; for (int j = ; j < cellCount; j++)
{
ICell cell = headerRow.GetCell(j);
dt.Columns.Add(cell.ToString());
} for (int i = (sheet.FirstRowNum + ); i <= sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);
DataRow dataRow = dt.NewRow(); for (int j = row.FirstCellNum; j < cellCount; j++)
{
if (row.GetCell(j) != null)
dataRow[j] = row.GetCell(j).ToString();
} dt.Rows.Add(dataRow);
}
return dt;
} private static HSSFCellStyle CreateBasicCellStyle(HSSFWorkbook workbook)
{
var cellStyle = workbook.CreateCellStyle() as HSSFCellStyle;
cellStyle.BorderLeft = BorderStyle.Thin;
cellStyle.BorderRight = BorderStyle.Thin;
cellStyle.BorderTop = BorderStyle.Thin;
cellStyle.BorderBottom = BorderStyle.Thin;
cellStyle.Alignment = HorizontalAlignment.Center;
cellStyle.VerticalAlignment = VerticalAlignment.Center;
return cellStyle;
}
}
}

參考文件

  NPOI匯出Excel表功能實現(多個工作簿)http://www.cnblogs.com/zhengjuzhuan/archive/2010/02/01/1661103.html

  NET使用NPOI元件將資料匯出Excel-通用方法  http://www.tuicool.com/articles/eq6FRb

   NET NPOI匯出Excel詳解    http://www.cnblogs.com/yinrq/p/5590970.html

  基於NPOI的自定義樣式報表引擎——ExcelReport  http://www.cnblogs.com/hanzhaoxin/p/4232572.html