通用的C#導出Excel 支持2003及2007以上版本

將數據導出到Excel,供用戶下載是常常要使用到的一個功能,我這裏進行了一些封裝,目前已知足項目中導出的需求,使用DataReader導出Excel,支持自定義多表頭,使用委託處理字段格式化及字段值的計算;前端

導出執行的代碼以下:數據庫

        /// <summary>
        /// 將DataReader數據寫入到 excel book 中
        /// 通常數據量小的導出用這個就能夠啦
        /// </summary>
        /// <param name="dataReader"></param>
        /// <param name="book">Excel Book</param>
        /// <param name="excelName">excelName文件名字</param>
        /// <param name="sheetSize">每一個Sheet放多少條記錄</param>
        /// <param name="excelHeaderModels">Excel表頭實體,Select字段能夠從這裏獲取</param>
        /// <param name="func">字段格式化委託函數</param>
        /// <param name="funcCalc">字段的值計算委託函數</param>
        /// <returns></returns>
        public Hashtable CommonDataWrite2Sheet(IDataReader dataReader, IWorkbook book, string excelName, int sheetSize, List<ExcelHeaderModel> excelHeaderModels = null, Func<string, object, string> func = null, Func<string, object, IDataReader, object> funcCalc = null)
        {
            string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, BusinessSystemInfo.ExportDir, DateTime.Now.ToString(BaseSystemInfo.DateFormat));
            string fileName = Path.Combine(filePath, excelName);
            //建立表頭
            int totalCount = 1;
            //表頭的要去掉 不然默認的是65535條記錄 一個表頭 因此從1開始
            if (excelHeaderModels != null)
            {
                totalCount = excelHeaderModels.Max(c => c.RowStart) + 1;
            }
            Hashtable ht = new Hashtable();
            //給book 建立Sheet
            int sheetIndex = 0;
            string sheetName = "sheet";
            ISheet sheet = book.CreateSheet(sheetName + sheetIndex);
            //在建立的sheet裏面建立表頭
            CreateHeader(dataReader, book, excelHeaderModels, sheet);
            //寫入到book中 逐行
            while (dataReader.Read())
            {
                // 輸出的總數量大於每頁數量(如65535),換一頁寫入 2003版本的纔會要求限制每sheet放65535條記錄
                if (book.GetType() == typeof(HSSFWorkbook))
                {
                    if (totalCount > sheetSize)
                    {
                        //換一頁寫
                        sheetIndex++;
                        totalCount = 0;
                        sheet = book.CreateSheet(sheetName + sheetIndex);
                        CreateHeader(dataReader, book, excelHeaderModels, sheet);
                    }
                }
                //建立Excel的行這一行是sheet建立的第rowIndex++行
                IRow excelRow = sheet.CreateRow(totalCount);
                for (int i = 0; i < dataReader.FieldCount; i++)
                {
                    //在rowIndex++行的給第j列 寫入 dt的第i行第j列的值
                    ICell cell = excelRow.CreateCell(i);
                    string colName = dataReader.GetName(i);
                    object value = dataReader.GetValue(i);
                    if (funcCalc != null)
                    {
                        value = funcCalc(colName, value, dataReader);
                    }
                    SetCellValue(func, cell, value, colName);
                }
                //自動調整單元格大小 有些耗時
                //for (int i = 0; i < dataReader.FieldCount; i++)
                //{
                //    sheet.AutoSizeColumn(i,true);
                //}
                totalCount++;
            }

            // book寫入到文件中
            WriteToFile(book, fileName);

            //獲取擴展名
            //string fileExt = Path.GetExtension(fileName);
            //using (ZipFile zip = ZipFile.Create(fileName.Replace(fileExt, ".zip")))
            //{
            //    zip.BeginUpdate();
            //    zip.SetComment("這是個人壓縮包");
            //    zip.Add(fileName);       //添加一個文件
            //    zip.CommitUpdate();
            //}

            fileName = fileName.Replace(AppDomain.CurrentDomain.BaseDirectory + "", "");
            ht.Add("Code", "1");
            ht.Add("Detail", "數據導出完畢,請下載。");
            ht.Add("fileName", fileName);
            ht.Add("Count", totalCount);
            return ht;
        }
WriteToFile 將book寫入到文件的方法,注意,這裏使用了 ms.ToArray()
        /// <summary>
        /// Excel book寫入到Excel文件
        /// </summary>
        /// <param name="book"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private bool WriteToFile(IWorkbook book, string fileName)
        {
            bool result = true;
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    string filePath = Path.GetDirectoryName(fileName);
                    if (filePath != null && !Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    book.Write(ms);
                    var buf = ms.ToArray();
                    using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(buf, 0, buf.Length);
                        fs.Flush();
                    }
                }
            }
            catch (Exception e)
            {
                LogHelper.WriteErrorLog(e.Message, e);
                result = false;
            }
            finally
            {
                GC.Collect();
            }
            return result;
        }

ExcelHeaderModel 是定義的表頭實體,支持自定義多表頭,以下:函數

    /// <summary>
    /// 導出配置
    /// 
    /// 修改紀錄
    /// 
    /// 2015-12-19版本:1.0 SongBiao 建立文件。     
    /// 
    /// <author>
    ///     <name>SongBiao</name>
    ///     <date>2015-12-19</date>
    /// </author>
    /// </summary>
    [Serializable]
    public class ExcelHeaderModel
    {
        /// <summary>
        /// 數據庫裏面的字段名稱
        /// </summary>
        public string SrcName { get; set; }

        /// <summary>
        /// 名稱
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 行開始
        /// </summary>
        public int RowStart { get; set; }

        /// <summary>
        /// 行結束
        /// </summary>
        public int RowEnd { get; set; }

        /// <summary>
        /// 列開始
        /// </summary>
        public int ColStart { get; set; }

        /// <summary>
        /// 列結束
        /// </summary>
        public int ColEnd { get; set; }

        /// <summary>
        /// 是否顯示在表頭 有些字段不須要顯示 可是須要用來作計算
        /// </summary>
        [DefaultValue(false)]
        public bool Hidden { get; set; }
    }

Controller中的業務調用ui

        /// <summary>
        /// 導出操做,支持導出當前頁,導出所有,導出文件格式excel2003,excel2007及以上
        /// </summary>
        /// <param name="searchModel"></param>
        /// <param name="pager"></param>
        /// <param name="sort"></param>
        /// <param name="direction"></param>
        /// <param name="isPage">true:導出當前頁,false:導出所有</param>
        /// <returns></returns>
        [CustomerResource("ExportData")]
        public ActionResult ExportData(PriceSearchEntity searchModel, QuiGridPager pager, string sort, string direction,bool isPage)
        {
            PriceManager priceManager = new PriceManager(BusinessDbHelper, UserInfo);
            // 使用DataReader導出
            IDataReader dr ;
            //要導出的字段
            string selectField = GetExportField();
            string tableName = PriceEntity.TableName + " A";
            // 導出當前頁
            if (isPage)
            {
                dr = priceManager.ExecuteReaderByPage(searchModel,tableName, pager, sort, direction, selectField);
            }
            else
            {
                dr = priceManager.ExecuteReader(searchModel, tableName, sort, direction, selectField);
            }
            using (dr)
            {
                IWorkbook book = new HSSFWorkbook();
                // 2007的導出
                // IWorkbook book = new XSSFWorkbook();//.xlsx

                string fileName = UserInfo.NickName+"_數據導出-" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".xls";

                // GetSelectField()
                // 導出的文件自動壓縮 
                // var hashTable = new ExportHelper().DataWrite2Excel(dr, book, fileName, 5, 65530, null, null, null);

                //通常用這個
                var hashTable = new ExportHelper().CommonDataWrite2Sheet(dr, book, fileName, 65530);
                hashTable.Add("TotalTime", CalcTimeSpan(StartTime));
                return Json(hashTable, JsonRequestBehavior.AllowGet);
            }
        }

這裏使用了通用權限系統的權限控制功能及底層的數據訪問功能,解決導出權限控制的問題。spa

代碼裏可根據須要控制輸出的文件使用Excel2003仍是Excel2007的文件格式。excel

前端導出完成展現的效果:code

相關文章
相關標籤/搜索