NPOI MVC 模型導出Excel通用類


通用類:

public enum DataTypeEnum
    {
        Int = 0,
        Float = 1,
        Double = 2,
        String = 3,
        DateTime = 4,
        Date = 5
    }
    public class ExportFieldInfo
    {
        /// <summary>
        /// 字段名,用於反射獲取值
        /// </summary>
        public string FieldName { get; set; }
        /// <summary>
        /// 中文名,用於導出標題
        /// </summary>
        public string DisplayName { get; set; }
        /// <summary>
        /// 數據類型,用於強制轉換,並進行格式化,其實利用反射也可以獲取到數據類型,此處因為要處理Date和Date的顯示格式
        /// </summary>
        public DataTypeEnum DataType { get; set; }
    }
    public class ExcelHelper<T>
    {
        /// <summary>
        /// 導出到內存流
        /// </summary>
        /// <param name="datas">需要導出的模型列表</param>
        /// <param name="fieldInfies">導出的字段列表信息</param>
        /// <param name="sheetRows">每個工作表的行數</param>
        /// <returns></returns>
        public static MemoryStream ToExcel(List<T> datas, List<ExportFieldInfo> fieldInfies, int sheetRows = 65536)
        {
            //創建Excel文件的對象
            NPOI.HSSF.UserModel.HSSFWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook();
            //需要生成工作溥總簿
            int sheetCount = datas.Count / sheetRows + 1;
            int rowCount = datas.Count;
            for (int i = 0; i < sheetCount; i++)
            {
                //添加一個sheet
                NPOI.SS.UserModel.ISheet sheet = book.CreateSheet("Sheet" + Convert.ToString(i));
                //給sheet添加第一行的頭部標題
                NPOI.SS.UserModel.IRow rowTitle = sheet.CreateRow(0);
                for (int k = 0; k < fieldInfies.Count; k++)
                {
                    rowTitle.CreateCell(k).SetCellValue(fieldInfies.ElementAt(k).DisplayName);
                }
                //處理Excel一張工作簿只能放65536行記錄的問題
                //因為頭部占一行,所以要減1
                for (int j = 0; j < sheetRows - 1; j++)
                {
                    //將數據逐步寫入sheet各個行
                    NPOI.SS.UserModel.IRow rowtemp = sheet.CreateRow(j + 1);
                    int dataIndex = i * (sheetRows - 1) + j;
                    for (int k = 0; k < fieldInfies.Count; k++)
                    {
                        //獲取類型
                        Type type = datas[dataIndex].GetType(); 
                        //獲取指定名稱的屬性
                        System.Reflection.PropertyInfo propertyInfo = type.GetProperty(fieldInfies.ElementAt(k).FieldName); 
                        //獲取屬性值
                        var value = propertyInfo.GetValue(datas[dataIndex], null); 
                        switch (fieldInfies.ElementAt(k).DataType)
                        {
                            case DataTypeEnum.Int:
                                rowtemp.CreateCell(k).SetCellValue(Convert.ToInt32(value));
                                break;
                            case DataTypeEnum.Float:
                                rowtemp.CreateCell(k).SetCellValue(Convert.ToDouble(value));
                                break;
                            case DataTypeEnum.Double:
                                rowtemp.CreateCell(k).SetCellValue(Convert.ToDouble(value));
                                break;
                            case DataTypeEnum.String:
                                rowtemp.CreateCell(k).SetCellValue(Convert.ToString(value));
                                break;
                            case DataTypeEnum.DateTime:
                                rowtemp.CreateCell(k).SetCellValue(Convert.ToDateTime(value).ToString("yyyy-MM-dd HH:mm:ss.SSS"));
                                break;
                            case DataTypeEnum.Date:
                                rowtemp.CreateCell(k).SetCellValue(Convert.ToDateTime(value).ToString("yyyy-MM-dd"));
                                break;
                            default:
                                break;
                        }
                    }
                    //所有記錄循環完成
                    if (i * (sheetRows - 1) + (j +1) == rowCount)
                    {
                        // 寫入到客戶端 
                        System.IO.MemoryStream ms = new System.IO.MemoryStream();
                        book.Write(ms);
                        ms.Seek(0, SeekOrigin.Begin);
                        return ms;
                    }
                }

            }
            return null;
        }
    }

 

調用:

 

/// <summary>
        /// 導出Excel
        /// </summary>
        /// <param name="request">請求參數集合</param>
        /// <returns></returns>
        public FileResult ToExcel(ActiveRecordRequest request)
        {
            //獲取記錄信息
            Response<ActiveRecord> listInfo = this.CrmService.GetActiveRecordList(request);
            //初始化需要導出字段
            List<ExportFieldInfo> fieldInfo = new List<ExportFieldInfo>();
            fieldInfo.Add(new ExportFieldInfo() {
                FieldName = "ActiveDate",
                DisplayName = "活動日期",
                DataType = DataTypeEnum.Date
            });
            fieldInfo.Add(new ExportFieldInfo()
            {
                FieldName = "ActiveSubject",
                DisplayName = "活動主題",
                DataType = DataTypeEnum.String
            });
            fieldInfo.Add(new ExportFieldInfo()
            {
                FieldName = "Remark",
                DisplayName = "備注",
                DataType = DataTypeEnum.String
            });
            return File(ExcelHelper<ActiveRecord>.ToExcel(listInfo.Data, fieldInfo), "application/vnd.ms-excel", "活動信息表.xls");
        }

js調用:

直接訪問Action即可,貼出我json的一部分,這里不適合你們的應用,就是說明一下調用這個函數即可

//導出到Excel
    ToExcel: function () {
        location.href = "/" + PageParam.Area + "/" + PageParam.AjaxController + "/ToExcel?IsPaging=false";
    }

最后上一張導出結果,因為我測試記錄有39W,一張工作表只能存65536條記錄,所以這里導出成幾個工作表了,一張工作表具體多少記錄你也可以設置最后那個參數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM