分享我基於NPOI+ExcelReport實現的導入與導出EXCEL類庫:ExcelUtility

来源:http://www.cnblogs.com/zuowj/archive/2016/01/09/5113812.html
-Advertisement-
Play Games

1. ExcelUtility功能:  1.將數據導出到EXCEL(支持XLS,XLSX,支持多種類型模板,支持列寬自適應)  類名:ExcelUtility. Export  2.將EXCEL數據導入到數據對象中(DataTable、Dataset,支持XLS,XLSX) ...


1. ExcelUtility功能:
   1.將數據導出到EXCEL(支持XLS,XLSX,支持多種類型模板,支持列寬自適應)
     類名:ExcelUtility. Export


   2.將EXCEL數據導入到數據對象中(DataTable、Dataset,支持XLS,XLSX)
     類名:ExcelUtility. Import

  類庫項目文件結構如下圖示:

  


 2. ExcelUtility依賴組件:
   1.NPOI 操作EXCEL核心類庫
   2.NPOI.Extend NPOI擴展功能
   3. ExcelReport 基於NPOI的二次擴展,實現模板化導出功能
   4. System.Windows.Forms 導出或導入時,彈出文件選擇對話框(如果用在WEB中可以不需要,但我這裡以CS端為主)

3.使用環境準備:

  1.通過NUGet引用NPOI包、ExcelReport 包;(ExcelReport 存在BUG,可能需要用我項目中修複過後的DLL)

  2.引用ExcelUtility類庫;

4.具體使用方法介紹(示例代碼,全部為測試方法):

導出方法測試:

/// <summary>
        /// 測試方法:測試將DataTable導出到EXCEL,無模板
        /// </summary>
        [TestMethod]
        public void TestExportToExcelByDataTable()
        {
            DataTable dt = GetDataTable();
            string excelPath = ExcelUtility.Export.ToExcel(dt, "導出結果");
            Assert.IsTrue(File.Exists(excelPath));
        }

結果如下圖示:

 

        /// <summary>
        /// 測試方法:測試將DataTable導出到EXCEL,無模板,且指定導出的列名
        /// </summary>
        [TestMethod]
        public void TestExportToExcelByDataTable2()
        {
            DataTable dt = GetDataTable();
            string[] expColNames = { "Col1", "Col2", "Col3", "Col4", "Col5" };
            string excelPath = ExcelUtility.Export.ToExcel(dt, "導出結果", null, expColNames);
            Assert.IsTrue(File.Exists(excelPath));
        }

結果如下圖示:

 

  /// <summary>
        /// 測試方法:測試將DataTable導出到EXCEL,無模板,且指定導出的列名,以及導出列名的重命名
        /// </summary>
        [TestMethod]
        public void TestExportToExcelByDataTable3()
        {
            DataTable dt = GetDataTable();
            string[] expColNames = { "Col1", "Col2", "Col3", "Col4", "Col5" };
            Dictionary<string, string> expColAsNames = new Dictionary<string, string>() { 
                {"Col1","列一"},
                {"Col2","列二"},
                {"Col3","列三"},
                {"Col4","列四"},
                {"Col5","列五"}
            };
            string excelPath = ExcelUtility.Export.ToExcel(dt, "導出結果", null, expColNames,expColAsNames);
            Assert.IsTrue(File.Exists(excelPath));
        }

結果如下圖示:

 

  /// <summary>
        /// 測試方法:測試將DataTable導出到EXCEL,無模板,且指定導出列名的重命名
        /// </summary>
        [TestMethod]
        public void TestExportToExcelByDataTable4()
        {
            DataTable dt = GetDataTable();
            Dictionary<string, string> expColAsNames = new Dictionary<string, string>() { 
                {"Col1","列一"},
                {"Col5","列五"}
            };
            string excelPath = ExcelUtility.Export.ToExcel(dt, "導出結果", null, null, expColAsNames);
            Assert.IsTrue(File.Exists(excelPath));
        }

結果如下圖示:

 

        /// <summary>
        /// 測試方法:測試依據模板+DataTable來生成EXCEL
        /// </summary>
        [TestMethod]
        public void TestExportToExcelWithTemplateByDataTable()
        {
            DataTable dt = GetDataTable();//獲取數據
            string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/excel.xlsx"; //獲得EXCEL模板路徑
            SheetFormatterContainer<DataRow> formatterContainers = new SheetFormatterContainer<DataRow>(); //實例化一個模板數據格式化容器

            PartFormatterBuilder partFormatterBuilder = new PartFormatterBuilder();//實例化一個局部元素格式化器
            partFormatterBuilder.AddFormatter("Title", "IT學員");//將模板表格中Title的值設置為跨越IT學員
            formatterContainers.AppendFormatterBuilder(partFormatterBuilder);//添加到工作薄格式容器中,註意只有添加進去了才會生效

            CellFormatterBuilder cellFormatterBuilder = new CellFormatterBuilder();//實例化一個單元格格式化器
            cellFormatterBuilder.AddFormatter("rptdate", DateTime.Today.ToString("yyyy-MM-dd HH:mm"));//將模板表格中rptdate的值設置為當前日期
            formatterContainers.AppendFormatterBuilder(cellFormatterBuilder);//添加到工作薄格式容器中,註意只有添加進去了才會生效

            //實例化一個表格格式化器,dt.Select()是將DataTable轉換成DataRow[],name表示的模板表格中第一行第一個單元格要填充的數據參數名
            TableFormatterBuilder<DataRow> tableFormatterBuilder = new TableFormatterBuilder<DataRow>(dt.Select(), "name");
            tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<DataRow, object>>{
                {"name",r=>r["Col1"]},//將模板表格中name對應DataTable中的列Col1
                {"sex",r=>r["Col2"]},//將模板表格中sex對應DataTable中的列Col2
                {"km",r=>r["Col3"]},//將模板表格中km對應DataTable中的列Col3
                {"score",r=>r["Col4"]},//將模板表格中score對應DataTable中的列Col
                {"result",r=>r["Col5"]}//將模板表格中result對應DataTable中的列Co5
            });
            formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);//添加到工作薄格式容器中,註意只有添加進去了才會生效

            string excelPath = ExcelUtility.Export.ToExcelWithTemplate<DataRow>(templateFilePath, "table", formatterContainers);
            Assert.IsTrue(File.Exists(excelPath));
        }

模板如下圖示:

結果如下圖示:

 

        /// <summary>
        /// 測試方法:測試依據模板+List來生成EXCEL
        /// </summary>
        [TestMethod]
        public void TestExportToExcelWithTemplateByList()
        {
            List<Student> studentList = GetStudentList();//獲取數據
            string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/excel.xlsx"; //獲得EXCEL模板路徑
            SheetFormatterContainer<Student> formatterContainers = new SheetFormatterContainer<Student>(); //實例化一個模板數據格式化容器

            PartFormatterBuilder partFormatterBuilder = new PartFormatterBuilder();//實例化一個局部元素格式化器
            partFormatterBuilder.AddFormatter("Title", "IT學員");//將模板表格中Title的值設置為跨越IT學員
            formatterContainers.AppendFormatterBuilder(partFormatterBuilder);//添加到工作薄格式容器中,註意只有添加進去了才會生效

            CellFormatterBuilder cellFormatterBuilder = new CellFormatterBuilder();//實例化一個單元格格式化器
            cellFormatterBuilder.AddFormatter("rptdate", DateTime.Today.ToString("yyyy-MM-dd HH:mm"));//將模板表格中rptdate的值設置為當前日期
            formatterContainers.AppendFormatterBuilder(cellFormatterBuilder);//添加到工作薄格式容器中,註意只有添加進去了才會生效

            //實例化一個表格格式化器,studentList本身就是可枚舉的無需轉換,name表示的模板表格中第一行第一個單元格要填充的數據參數名
            TableFormatterBuilder<Student> tableFormatterBuilder = new TableFormatterBuilder<Student>(studentList, "name");
            tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<Student, object>>{
                {"name",r=>r.Name},//將模板表格中name對應Student對象中的屬性Name
                {"sex",r=>r.Sex},//將模板表格中sex對應Student對象中的屬性Sex
                {"km",r=>r.KM},//將模板表格中km對應Student對象中的屬性KM
                {"score",r=>r.Score},//將模板表格中score對應Student對象中的屬性Score
                {"result",r=>r.Result}//將模板表格中result對應Student對象中的屬性Result
            });
            formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);

            string excelPath = ExcelUtility.Export.ToExcelWithTemplate<Student>(templateFilePath, "table", formatterContainers);
            Assert.IsTrue(File.Exists(excelPath));

        }

結果如下圖示:(模板與上面相同)

 

        /// <summary>
        /// 測試方法:測試依據模板+DataTable來生成多表格EXCEL(註意:由於NPOI框架限制,目前僅支持模板文件格式為:xls)
        /// </summary>
        [TestMethod]
        public void TestExportToRepeaterExcelWithTemplateByDataTable()
        {
            DataTable dt = GetDataTable();//獲取數據
            string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/excel2.xls"; //獲得EXCEL模板路徑
            SheetFormatterContainer<DataRow> formatterContainers = new SheetFormatterContainer<DataRow>(); //實例化一個模板數據格式化容器

            //實例化一個可重覆表格格式化器,dt.Select()是將DataTable轉換成DataRow[],rpt_begin表示的模板表格開始位置參數名,rpt_end表示的模板表格結束位置參數名
            RepeaterFormatterBuilder<DataRow> tableFormatterBuilder = new RepeaterFormatterBuilder<DataRow>(dt.Select(), "rpt_begin", "rpt_end");
            tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<DataRow, object>>{
                {"sex",r=>r["Col2"]},//將模板表格中sex對應DataTable中的列Col2
                {"km",r=>r["Col3"]},//將模板表格中km對應DataTable中的列Col3
                {"score",r=>r["Col4"]},//將模板表格中score對應DataTable中的列Col
                {"result",r=>r["Col5"]}//將模板表格中result對應DataTable中的列Co5
            });

            PartFormatterBuilder<DataRow> partFormatterBuilder2 = new PartFormatterBuilder<DataRow>();//實例化一個可嵌套的局部元素格式化器
            partFormatterBuilder2.AddFormatter("name", r => r["Col1"]);//將模板表格中name對應DataTable中的列Col1
            tableFormatterBuilder.AppendFormatterBuilder(partFormatterBuilder2);//添加到可重覆表格格式化器中,作為其子格式化器


            CellFormatterBuilder<DataRow> cellFormatterBuilder = new CellFormatterBuilder<DataRow>();//實例化一個可嵌套的單元格格式化器
            cellFormatterBuilder.AddFormatter("rptdate", r => DateTime.Today.ToString("yyyy-MM-dd HH:mm"));//將模板表格中rptdate的值設置為當前日期
            tableFormatterBuilder.AppendFormatterBuilder(cellFormatterBuilder);//添加到可重覆表格格式化器中,作為其子格式化器

            formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);//添加到工作薄格式容器中,註意只有添加進去了才會生效

            string excelPath = ExcelUtility.Export.ToExcelWithTemplate<DataRow>(templateFilePath, "multtable", formatterContainers);
            Assert.IsTrue(File.Exists(excelPath));
        }

模板如下圖示:(註意:該模板僅支持XLS格式文件,XLSX下存在問題)

結果如下圖示:

以下是模擬數據來源所定義的方法(配合測試):

        private DataTable GetDataTable()
        {
            DataTable dt = new DataTable();
            for (int i = 1; i <= 6; i++)
            {
                if (i == 4)
                {
                    dt.Columns.Add("Col" + i.ToString(), typeof(double));
                }
                else
                {
                    dt.Columns.Add("Col" + i.ToString(), typeof(string));
                }
            }

            for (int i = 1; i <= 10; i++)
            {
                dt.Rows.Add("Name" + i.ToString(), (i % 2) > 0 ? "男" : "女", "科目" + i.ToString(), i * new Random().Next(1, 5), "待定", Guid.NewGuid().ToString("N"));
            }

            return dt;
        }

        private List<Student> GetStudentList()
        {
            List<Student> studentList = new List<Student>();
            for (int i = 1; i <= 10; i++)
            {
                studentList.Add(new Student
                {
                    Name = "Name" + i.ToString(),
                    Sex = (i % 2) > 0 ? "男" : "女",
                    KM = "科目" + i.ToString(),
                    Score = i * new Random().Next(1, 5),
                    Result = "待定"
                });
            }
            return studentList;
        }

        class Student
        {
            public string Name { get; set; }

            public string Sex { get; set; }

            public string KM { get; set; }

            public double Score { get; set; }

            public string Result { get; set; }
        }

導入方法測試:

     /// <summary>
        /// 測試方法:測試將指定的EXCEL數據導入到DataTable
        /// </summary>
        [TestMethod]
        public void TestImportToDataTableFromExcel()
        {
           //null表示由用戶選擇EXCEL文件路徑,data表示要導入的sheet名,0表示數據標題行
           DataTable dt=  ExcelUtility.Import.ToDataTable(null, "data", 0);
           Assert.AreNotEqual(0, dt.Rows.Count);
        }

數據源文件內容如下圖示:

 

下麵貼出該類庫主要源代碼:

ExcelUtility.Export類:

using ExcelReport;
using ExcelUtility.Base;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ExcelUtility
{
    public sealed class Export
    {
        /// <summary>
        /// 由DataSet導出Excel
        /// </summary>
        /// <param name="sourceTable">要導出數據的DataTable</param>
        /// <param name="filePath">導出路徑,可選</param>
        /// <returns></returns>
        public static string ToExcel(DataSet sourceDs, string filePath = null)
        {

            if (string.IsNullOrEmpty(filePath))
            {
                filePath = Common.GetSaveFilePath();
            }

            if (string.IsNullOrEmpty(filePath)) return null;

            bool isCompatible = Common.GetIsCompatible(filePath);

            IWorkbook workbook = Common.CreateWorkbook(isCompatible);
            ICellStyle headerCellStyle = Common.GetCellStyle(workbook,true);
            ICellStyle cellStyle = Common.GetCellStyle(workbook);

            for (int i = 0; i < sourceDs.Tables.Count; i++)
            {
                DataTable table = sourceDs.Tables[i];
                string sheetName = string.IsNullOrEmpty(table.TableName) ? "result" + i.ToString() : table.TableName;
                ISheet sheet = workbook.CreateSheet(sheetName);
                IRow headerRow = sheet.CreateRow(0);
                // handling header.
                foreach (DataColumn column in table.Columns)
                {
                    ICell headerCell = headerRow.CreateCell(column.Ordinal);
                    headerCell.SetCellValue(column.ColumnName);
                    headerCell.CellStyle = headerCellStyle;
                    sheet.AutoSizeColumn(headerCell.ColumnIndex);
                }

                // handling value.
                int rowIndex = 1;
                
                foreach (DataRow row in table.Rows)
                {
                    IRow dataRow = sheet.CreateRow(rowIndex);

                    foreach (DataColumn column in table.Columns)
                    {
                        ICell cell = dataRow.CreateCell(column.Ordinal);
                        cell.SetCellValue((row[column] ?? "").ToString());
                        cell.CellStyle = cellStyle;
                        Common.ReSizeColumnWidth(sheet, cell);
                    }

                    rowIndex++;
                }
            }

            FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            workbook.Write(fs);
            fs.Dispose();
            workbook = null;

            return filePath;

        }

        /// <summary>
        /// 由DataTable導出Excel
        /// </summary>
        /// <param name="sourceTable">要導出數據的DataTable</param>
        /// <param name="colAliasNames">導出的列名重命名數組</param>
        /// <param name="sheetName">工作薄名稱,可選</param>
        /// <param name="filePath">導出路徑,可選</param>
        /// <returns></returns>
        public static string ToExcel(DataTable sourceTable, string[] colAliasNames, string sheetName = "result", string filePath = null)
        {
            if (sourceTable.Rows.Count <= 0) return null;

            if (string.IsNullOrEmpty(filePath))
            {
                filePath = Common.GetSaveFilePath();
            }

            if (string.IsNullOrEmpty(filePath)) return null;

            if (colAliasNames == null || sourceTable.Columns.Count != colAliasNames.Length)
            {
                throw new ArgumentException("列名重命名數組與DataTable列集合不匹配。", "colAliasNames");
            }

            bool isCompatible = Common.GetIsCompatible(filePath);

            IWorkbook workbook = Common.CreateWorkbook(isCompatible);
            ICellStyle headerCellStyle = Common.GetCellStyle(workbook, true);
            ICellStyle cellStyle = Common.GetCellStyle(workbook);

            ISheet sheet = workbook.CreateSheet(sheetName);
            IRow headerRow = sheet.CreateRow(0);
            // handling header.
            foreach (DataColumn column in sourceTable.Columns)
            {
                ICell headerCell = headerRow.CreateCell(column.Ordinal);
                headerCell.SetCellValue(colAliasNames[column.Ordinal]);
                headerCell.CellStyle = headerCellStyle;
                sheet.AutoSizeColumn(headerCell.ColumnIndex);
            }

            // handling value.
            int rowIndex = 1;

            foreach (DataRow row in sourceTable.Rows)
            {
                IRow dataRow = sheet.CreateRow(rowIndex);

                foreach (DataColumn column in sourceTable.Columns)
                {
                    ICell cell = dataRow.CreateCell(column.Ordinal);
                    cell.SetCellValue((row[column] ?? "").ToString());
                    cell.CellStyle = cellStyle;
                    Common.ReSizeColumnWidth(sheet, cell);
                }

                rowIndex++;
            }
            FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            workbook.Write(fs);
            fs.Dispose();

            sheet = null;
            headerRow = null;
            workbook = null;

            return filePath;
        }

        /// <summary>
        /// 由DataGridView導出
        /// </summary>
        /// <param name="grid">要導出的DataGridView對象</param>
        /// <param name="sheetName">工作薄名稱,可選</param>
        /// <param name="filePath">導出路徑,可選</param>
        /// <returns></returns>
        public static string ToExcel(DataGridView grid, string sheetName = "result", string filePath = null)
        {
            if (grid.Rows.Count <= 0) return null;

            if (string.IsNullOrEmpty(filePath))
            {
                filePath = Common.GetSaveFilePath();
            }

            if (string.IsNullOrEmpty(filePath)) return null;

            bool isCompatible = Common.GetIsCompatible(filePath);

            IWorkbook workbook = Common.CreateWorkbook(isCompatible);
            ICellStyle headerCellStyle = Common.GetCellStyle(workbook, true);
            ICellStyle cellStyle = Common.GetCellStyle(workbook);
            ISheet sheet = workbook.CreateSheet(sheetName);

            IRow headerRow = sheet.CreateRow(0);

            for (int i = 0; i < grid.Columns.Count; i++)
            {
                ICell headerCell = headerRow.CreateCell(i);
                headerCell.SetCellValue(grid.Columns[i].HeaderText);
                headerCell.CellStyle = headerCellStyle;
                sheet.AutoSizeColumn(headerCell.ColumnIndex);
            }

            int rowIndex = 1;
            foreach (DataGridViewRow row in grid.Rows)
            {
                IRow dataRow = sheet.CreateRow(rowIndex);
                for (int n = 0; n < grid.Columns.Count; n++)
                {
                    ICell cell = dataRow.CreateCell(n);
                    cell.SetCellValue((row.Cells[n].Value ?? "").ToString());
                    cell.CellStyle = cellStyle;
                    Common.ReSizeColumnWidth(sheet, cell);
                }
                rowIndex++;
            }

            FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            workbook.Write(fs);
            fs.Dispose();

            sheet = null;
            headerRow = null;
            workbook = null;

            return filePath;
        }

        /// <summary>
        /// 由DataTable導出Excel
        /// </summary>
        /// <param name="sourceTable">要導出數據的DataTable</param>
        /// <param name="sheetName">工作薄名稱,可選</param>
        /// <param name="filePath">導出路徑,可選</param>
        /// <param name="colNames">需要導出的列名,可選</param>
        /// <param name="colAliasNames">導出的列名重命名,可選</param>
        /// <returns></returns>
        public static string ToExcel(DataTable sourceTable, string sheetName = "result", string filePath = null, string[] colNames = null, IDictionary<string, string> colAliasNames = null)
        {
            if (sourceTable.Rows.Count <= 0) return null;

            if (string.IsNullOrEmpty(filePath))
            {
                filePath = Common.GetSaveFilePath();
            }

            if (string.IsNullOrEmpty(filePath)) return null;

            bool isCompatible = Common.GetIsCompatible(filePath);

            IWorkbook workbook = Common.CreateWorkbook(isCompatible);
            ICellStyle headerCellStyle = Common.GetCellStyle(workbook, true);
            ICellStyle cellStyle = Common.GetCellStyle(workbook);

            ISheet sheet = workbook.CreateSheet(sheetName);
            IRow headerRow = sheet.CreateRow(0);

            if (colNames == null || colNames.Length <= 0)
            {
                colNames = sourceTable.Columns.Cast<DataColumn>().OrderBy(c => c.Ordinal).Select(c => c.ColumnName).ToArray();
            }

            // handling header.
            for (int i = 0; i < colNames.Length; i++)
            {
                ICell headerCell = headerRow.CreateCell(i);
                if (colAliasNames != null && colAliasNames.ContainsKey(colNames[i]))
                {
                    headerCell.SetCellValue(colAliasNames[colNames[i]]);
                }
                else
                {
                    headerCell.SetCellValue(colNames[i]);
                }
                headerCell.CellStyle = headerCellStyle;
                sheet.AutoSizeColumn(headerCell.ColumnIndex);
            }

            // handling value.
            int rowIndex = 1;

            foreach (DataRow row in sourceTable.Rows)
            {
                IRow dataRow = sheet.CreateRow(rowIndex);

                for (int i = 0; i < colNames.Length; i++)
                {
                    ICell cell = dataRow.CreateCell(i);
                    cell.SetCellValue((row[colNames[i]] ?? "").ToString());
                    cell.CellStyle = cellStyle;
                    Common.ReSizeColumnWidth(sheet, cell);
                }

                rowIndex++;
            }
            FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            workbook.Write(fs);
            fs.Dispose();

            sheet = null;
            headerRow = null;
            workbook = null;

            return filePath;
        }


        /// <summary>
        ///由SheetFormatterContainer導出基於EXCEL模板的文件
        /// </summary>
        /// <param name="templatePath">模板路徑</param>
        /// <param name="sheetName">模板中使用的工作薄名稱</param>
        /// <param name="formatterContainer">模板數據格式化容器</param>
        /// <param name="filePath">導出路徑,可選</param>
        /// <returns></returns>

        public static string ToExcelWithTemplate<T>(string templatePath, string sheetName, SheetFormatterContainer<T> formatterContainer, string filePath = null)
        {

            if (!File.Exists(templatePath))
            {
                throw new FileNotFoundException(templatePath + "文件不存在!");
            }

            if (string.IsNullOrEmpty(filePath))
            {
                filePath = Common.GetSaveFilePath();
            }

            if (string.IsNullOrEmpty(filePath)) return null;

            string templateConfigFilePath = Common.GetTemplateConfigFilePath(templatePath, false);

            var workbookParameterContainer = new WorkbookParameterContainer();
            workbookParameterContainer.Load(templateConfigFilePath);
            SheetParameterContainer sheetParameterContainer = workbookParameterContainer[sheetName];
            ExportHelper.ExportToLocal(templatePath, filePath, new SheetFormatter(sheetName, formatterContainer.GetFormatters(sheetParameterContainer)));

            return filePath;
        }


    }
}

  

ExcelUtility.Import類:

using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using ExcelUtility.Base;

namespace ExcelUtility
{
    public sealed class Import
    {
        /// <summary>
        /// 由Excel導入DataTable
        /// </summary>
        /// <param name="excelFileStream">Excel文件流</param>
        /// <param name="sheetName">Excel工作表名稱</param>
        /// <param name="headerRowIndex">Excel表頭行索引</param>
        /// <param name="isCompatible">是否為相容模式</param>
        /// <returns>DataTable</returns>
        public static DataTable ToDataTable(Stream excelFileStream, string sheetName, int headerRowIndex, bool isCompatible)
        {
            IWorkbook workbook = Common.CreateWorkbook(isCompatible, excelFileStream);
            ISheet sheet = null;
            int sheetIndex = -1;
            if (int.TryParse(sheetName, out sheetIndex))
            {
                sheet = workbook.GetSheetAt(sheetIndex);
            }
            else
            {
                sheet = workbook.GetSheet(sheetName);
            }

            DataTable table = Common.GetDataTableFromSheet(sheet, headerRowIndex);

            excelFileStream.Close();
            workbook = null;
            sheet = null;
            return table;
        }

        /// <summary>
        /// 由Excel導入DataTable
        /// </summary>
        /// <param name="excelFilePath">Excel文件路徑,為物理路徑,可傳空值</param>
        /// <param name="sheetName">Excel工作表名稱</param>
        /// <param name="headerRowIndex">Excel表頭行索引</param>
        /// <returns>DataTable</returns>
        public static DataTable ToDataTable(string excelFilePath, string sheetName, int headerRowIndex)
        {
            if (string.IsNullOrEmpty(excelFilePath))
            {
                excelFilePath = Common.GetOpenFilePath();
            }

            if (string.IsNullOrEmpty(excelFilePath))
            {
                return null;
            }

            using (FileStream stream = System.IO.File.OpenRead(excelFilePath))
            {
                bool isCompatible = Common.GetIsCompatible(excelFilePath);
                return ToDataTable(stream, sheetName, headerRowIndex, isCompatible);
            }
        }

        /// <summary>
        /// 由Excel導入DataSet,如果有多個工作表,則導入多個DataTable
        /// </summary>
        /// <param name="excelFileStream">Excel文件流</param>
        /// <param name="headerRowIndex">Excel表頭行索引</param>
        /// <param name="isCompatible">是否為相容模式</param>
        /// <returns>DataSet</returns>
        public static DataSet ToDataSet(Stream excelFileStream, int headerRowIndex, bool isCompatible)
        {
            DataSet ds = new DataSet();
            IWorkbook workbook = Common.CreateWorkbook(isCompatible, excelFileStream);
            for (int i = 0; i < workbook.NumberOfSheets; i++)
            {
                ISheet sheet = workbook.GetSheetAt(i);
                DataTable table = Common.GetDataTableFromSheet(sheet, headerRowIndex);
                ds.Tables.Add(table);
            }

            excelFileStream.Close();
            workbook = null;

            return ds;
        }

        /// <summary>
        /// 由Excel導入DataSet,如果有多個工作表,則導入多個DataTable
        /// </summary>
        /// <param name="excelFilePath">Excel文件路徑,為物理路徑。可傳空值</param>
        /// <param name="headerRowIndex">Excel表頭行索引</param>
        /// <returns>DataSet</returns>
        public static DataSet ToDataSet(string excelFilePath, int headerRowIndex)
        {
            if (string.IsNullOrEmpty(excelFilePath))
            {
                excelFilePath = Common.GetOpenFilePath();
            }

            if (string.IsNullOrEmpty(excelFilePath))
            {
                return null;
            }

            using (FileStream stream = System.IO.File.OpenRead(excelFilePath))
            {
                bool isCompatible = Common.GetIsCompatible(excelFilePath);
                return ToDataSet(stream, headerRowIndex, isCompatible);
            }
        }

    }
}

Common類根據單元格內容重新設置列寬ReSizeColumnWidth

        /// <summary>
        /// 根據單元格內容重新設置列寬
        /// </summary>
        /// <param name="sheet"></param>
        /// <param name="cell"></param>
        public static void ReSizeColumnWidth(ISheet sheet, ICell cell)
        {
            int cellLength = (Encoding.Default.GetBytes(cell.ToString()).Length + 5) * 256;
            const int maxLength = 255 * 256;
            if (cellLength > maxLength)
            {
                cellLength = maxLength;
            }
            int colWidth = sheet.GetColumnWidth(cell.ColumnIndex);
            if (colWidth < cellLength)
            {
                sheet.SetColumnWidth(cell.ColumnIndex, cellLength);
            }
        }

註意這個方法中,列寬自動設置最大寬度為255個字元寬度。

 

        /// <summary>
        /// 創建表格樣式
        /// </summary>
        /// <param name="sheet"></param>
        /// <returns></returns>
        public static ICellStyle GetCellStyle(IWorkbook workbook, bool isHeaderRow = false)
        {
            ICellStyle style = workbook.CreateCellStyle();

            if (isHeaderRow)
            {
                style.FillPattern = FillPattern.SolidForeground;
                style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
                IFont f = workbook.CreateFont();
                f.Boldweight = (short)FontBoldWeight.Bold;
                style.SetFont(f);
            }

            style.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
            style.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
            style.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
            style.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
            return style;
        }

發文時,部份方法代碼已經更新了,所以實際效果以GIT項目中的為準。

 該類庫源碼已分享到該路徑中:http://git.oschina.net/zuowj/ExcelUtility    GIT Repository路徑:[email protected]:zuowj/ExcelUtility.git


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、業務模塊與數據模塊分離在實際開發中,我們項目的架構業務模塊和數據模塊是分離的,舉個例子,假設我們的項目有"人員管理模塊"和"酒店管理模塊"兩個模塊,按照上一章的介紹,我們會建立下圖所示的項目結構:其中,人員管理模塊的controller、service、dao、mapper都在一個項目中,而在實...
  • 題目:取一個整數a從右端開始的4~7位。程式分析:可以這樣考慮:(1)先使a右移4位。(2)設置一個低4位全為1,其餘全為0的數。可用~(~0>4;c=~(~0<<4);d=b&c;printf("%o\n%o\n",a,d);}
  • haha,貪心,邊界條件折騰了我一會兒 1 #include 2 #include 3 #include 4 #include 5 using namespace std ; 6 7 const int MAXN = 1000000 + 200 ; 8 int N , K ; 9 int dis ....
  • 轉自:http://www.haorooms.com/post/gem_not_use最近在安裝SASS的時候,用到gem命令,但是運行出行如下錯誤!C:\Users\len>gem install sassERROR: While executing gem ... (Gem::RemoteFe....
  • using (Ajax.BeginForm("GetBasicInformation", "Employee", //new AjaxOptions { UpdateTargetId = "basicInfo", //設置HTML元素的ID,從伺服器接收的內容將被插入到該元素中LoadingElem...
  • live() 與bind()作用基本一樣。 最重要區別:live()可以將事件綁定到當前和將來的元素(eg:為id=zy元素綁定點擊事件,而當你用js動態生成一個節點並插入到dom文檔結構中時,如果你是用bind()綁定的,怎麼新插入的節點將不會有該bind綁定事件。而live()則可以); ...
  • 一,c#中的值類型和引用類型 眾所周知在c#中有兩種基本類型,它們分別是值類型和引用類型;而每種類型都可以細分為如下類型: 什麼是值類型和引用類型什麼是值類型:進一步研究文檔,你會發現所有的結構都是抽象類型System.ValueType的直接派生類,而System.ValueType本身又是直接....
  • 一、前言 AgileEAS.NET SOA 中間件平臺是一款基於基於敏捷並行開發思想和Microsoft .Net構件(組件)開發技術而構建的一個快速開發應用平臺。用於幫助中小型軟體企業建立一條適合市場快速變化的開發團隊,以達到節省開發成本、縮短開發時間,快速適應市場變化的目的。 AgileEAS....
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...