在上一篇文章[關于大數據的查詢與導出]中,提到了使用NPOI組件導出Excel,本想上次一起分享給大家,無奈最近比較忙,今天抽空整理了下,分享出來.
- 預置填充模板,并且需要支持公式計算;
- 可導入圖片;
- 可以追加數據形式填充表格.

/// <summary>/// 導出接口/// </summary>public interface IExport{ /// <summary> /// 導出數據,基于模板文件處理替換后,保存為一個新文件 /// </summary> /// <param name="templateFile">模板文件</param> /// <param name="targetFile">目標文件</param> /// <param name="fromater">模板格式化處理規則</param> void Export(string templateFile, string targetFile, ExportFormater fromater); /// <summary> /// 導出數據,基于模板文件處理替換后,保存為一個新文件 /// </summary> /// <typeparam name="T">數據源類型</typeparam> /// <param name="templateFile">模板文件</param> /// <param name="targetFile">目標文件</param> /// <param name="formater">模板格式化處理規則</param> /// <param name="source">數據源</param> void Export<T>(string templateFile, string targetFile, ExportFormater<T> formater, IList<T> source) where T : class; /// <summary> /// 以追加的形式,將數據添加到已存在的文件中 /// </summary> /// <typeparam name="T">數據源類型</typeparam> /// <param name="targetFile">目標文件</param> /// <param name="formater">模板格式化處理規則</param> /// <param name="source">數據源</param> void ExportByAppend<T>(string targetFile, ExportFormater<T> formater, IList<T> source) where T : class;}/// <summary> /// 散列單元格數據格式器 /// </summary> public class DispersedCellFormater { /// <summary> /// 單元格坐標 /// </summary> public Point CellPoint { get; set; } /// <summary> /// 格式化字符串 /// </summary> public string FormaterString { get; set; } /// <summary> /// 格式化數據 /// </summary> public object CellValue { get; set; } /// <summary> /// 實例化 /// </summary> public DispersedCellFormater() { } /// <summary> /// 實例化 /// </summary> /// <param name="x">cell 橫坐標</param> /// <param name="y">cell 縱坐標</param> /// <param name="formatStr">格式化字符串</param> /// <param name="val">替換值</param> public DispersedCellFormater(int x, int y, string formatStr, object val) { this.CellPoint = new Point(x, y); this.FormaterString = formatStr; this.CellValue = val; } }/// <summary> /// 圖片Cell格式化器 /// </summary> public class ImageCellFormater { /// <summary> /// 單元格位置 /// </summary> public Point CellPoint { get; set; } /// <summary> /// 顯示圖片 /// </summary> public Image Img { get; set; } /// <summary> /// 實例化 /// </summary> public ImageCellFormater() { } /// <summary> /// 實例化 /// </summary> /// <param name="x">cell橫坐標</param> /// <param name="y">cell縱坐標</param> /// <param name="img">圖片</param> public ImageCellFormater(int x, int y, Image img) { this.CellPoint = new Point(x, y); this.Img = img; } }/// <summary>/// 明細單元格取值規則/// <typeparam name="T">數據類型</typeparam>/// </summary>public class DetailCellValueFormater<T> where T : class{ /// <summary> /// 列索引 /// </summary> public int Index { get; set; } /// <summary> /// 取值函數 /// </summary> public Func<T, object> Value { get; set; } /// <summary> /// 實例化 /// </summary> public DetailCellValueFormater() { } /// <summary> /// 實例化 /// </summary> /// <param name="index">列索引</param> /// <param name="val">數據</param> public DetailCellValueFormater(int index, Func<T, object> val) { this.Index = index; this.Value = val; }}/// <summary>/// 用于描述導出格式化數據/// </summary>public class ExportFormater{ /// <summary> /// 散列單元格替換規格 /// </summary> public List<DispersedCellFormater> DispersedCellFormaters { get; PRivate set; } /// <summary> /// 圖片單元格格式化規則 /// </summary> public List<ImageCellFormater> ImageCellFormaters { get; private set; } /// <summary> /// 明細數據起始行索引 /// </summary> public int DetailRowBeginIndex { get; set; } /// <summary> /// 實例化 /// </summary> public ExportFormater() { DispersedCellFormaters = new List<DispersedCellFormater>(); ImageCellFormaters = new List<ImageCellFormater>(); }}/// <summary>/// 用于描述導出格式化數據,帶有明細區數據取值規則/// </summary>public class ExportFormater<T> : ExportFormater where T : class{ /// <summary> /// 明細區取值函數 /// </summary> public List<DetailCellValueFormater<T>> DetailCellValueFormaters { get; private set; } /// <summary> /// 實例化 /// </summary> public ExportFormater() { DetailCellValueFormaters = new List<DetailCellValueFormater<T>>(); }}/// <summary>/// 應用散列單元格格式/// </summary>/// <param name="formater">格式化規則</param>/// <param name="sheet">當前sheet</param>private static void ApplyDispersedCell(ExportFormater formater, HSSFSheet sheet){ if (formater.DispersedCellFormaters != null && formater.DispersedCellFormaters.Count > 0) { formater.DispersedCellFormaters.ForEach(r => { var tempRow = sheet.GetRow(r.CellPoint.X); var tempCell = tempRow.GetCell(r.CellPoint.Y); var txt = tempCell.StringCellValue; if (string.IsNullOrWhiteSpace(txt)) { tempCell.SetCellValue(Convert.ToString(r.CellValue)); } else { //替換模板 tempCell.SetCellValue(txt.Replace(r.FormaterString, Convert.ToString(r.CellValue))); } }); }}/// <summary> /// 應用圖片單元格 /// </summary> /// <param name="formater">格式化處理器</param> /// <param name="workbook"></param> /// <param name="sheet"></param> private static void ApplyImgCell(ExportFormater formater, HSSFWorkbook workbook, HSSFSheet sheet) { if (formater.ImageCellFormaters.Count <= 0) { return; } var patriarch = sheet.CreateDrawingPatriarch(); formater.ImageCellFormaters.ForEach(t => { if (t.Img != null) { var imgData = t.Img.ToByte(); //- 圖片輸出的位置這么計算的: //- 假設我們要將圖片放置于第 5(E) 列的第 2 行 //- 對應索引為是 4 : 1 (默認位置) //- 放置的位置就等于(默認位置)到(默認位置各自加上一行、一列) var imgPath = new HSSFClientAnchor( 1, 1, //- 上左 到 上右 的位置,是基于下面的行列位置
新聞熱點
疑難解答