• C#NPOI操作Excel,实现Excel数据导入导出(支持多个sheet)


     

    首先在项目中引用NPOI,通过管理NuGet程序包,搜索NPOI,选择版本2.3.0(支持.NET Framework 4.0)根据自己项目选择适当版本。

    1.NpoiExcelHelper.cs  Npoi操作Excel类

    using System.Data;
    using System.IO;
    using NPOI.SS.UserModel;
    using NPOI.XSSF.UserModel;
    using NPOI.HSSF.UserModel;
    
        /// 
        /// Npoi操作Excel类
        /// 
        public static class NpoiExcelHelper
        {
            /// 
            /// 根据Excel文件类型返回IWorkbook
            /// 
            /// 文件路径/文件名称(含后缀名)
            /// Excel行数
            /// Excel列数
            /// 第一行是否是标题
            /// 
            public static IWorkbook GetWorkbook(string fileName, out int rowNum, out int colNum, bool isFirstRowColumn = true)
            {
                bool isXlsx = Path.GetExtension(fileName).Equals(".xlsx");
                if (isXlsx)
                {
                    if (isFirstRowColumn)
                    {
                        rowNum = 1048575;
                    }
                    else
                    {
                        rowNum = 1048576;
                    }
                    colNum = 16384;
                }
                else
                {
                    if (isFirstRowColumn)
                    {
                        rowNum = 65535;
                    }
                    else
                    {
                        rowNum = 65536;
                    }
                    colNum = 256;
                }
                
                if (File.Exists(fileName))
                {
                    
                    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                    {
                        if (isXlsx)
                        {
                            return new XSSFWorkbook(fs);
                        }
                        else
                        {
                            return new HSSFWorkbook(fs);
                        }
                    }
                }
                else
                {
                    if (isXlsx)
                    {
                        return new XSSFWorkbook();
                    }
                    else
                    {
                        return new HSSFWorkbook();
                    }
                }
            }
    
            /// 
            /// 将DataTable中的数据导入到excel中(第一行是标题)
            /// 支持根据Excel数据自动分页(多个Sheet)
            /// 
            /// DataTable
            /// 文件路径/文件名称(含后缀名)
            /// 字段对应中文 顺序需要跟Excel中数据顺序一致
            /// Excel中Sheet名称(多个sheet时 名字后面自动加上数字序号)
            /// 
            public static byte[] DataTableToExcel(DataTable dt, string fileName, string[,] columnFieldText = null, string sheetName = null)
            {
                int rowNum = 0;
                int colNum = 0;
                IWorkbook workbook = GetWorkbook(fileName, out rowNum, out colNum);
                
                var recordNum = dt.Rows.Count;
                int totalPage = recordNum % rowNum == 0 ? recordNum / rowNum : recordNum / rowNum + 1;
    
                for (var p = 0; p < totalPage; p++)
                {
                    if (string.IsNullOrEmpty(sheetName))
                    {
                        sheetName = dt.TableName;
                    }
    
                    if (totalPage > 1)
                    {
                        if (string.IsNullOrEmpty(sheetName))
                        {
                            sheetName = "Sheet";
                        }
    
                        sheetName = sheetName + (p + 1).ToString();
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(sheetName))
                        {
                            sheetName = "Sheet1";
                        }
                    }
    
                    ISheet sheet = workbook.CreateSheet(sheetName);//创建工作表
    
                    #region 标题
                    IRow row = sheet.CreateRow(0);//在工作表中添加一行
                    if (columnFieldText != null)
                    {
                        var dataColumn = columnFieldText.GetLength(0);
                        if (dataColumn <= colNum)
                        {
                            for (int m = 0; m < dataColumn; m++)
                            {
                                ICell cell = row.CreateCell(m);//在行中添加一列
                                cell.SetCellValue(columnFieldText[m, 1]);//设置列的内容
                            }
                        }
                        else
                        {
                            //数据列数超过了Excel的列数
                        }
                    }
                    else
                    {
                        var dataColumn = dt.Columns.Count;
                        if (dataColumn <= colNum)
                        {
                            for (int i = 0; i < dataColumn; i++)
                            {
                                ICell cell = row.CreateCell(i);//在行中添加一列
                                cell.SetCellValue(dt.Columns[i].ColumnName);//设置列的内容     
                            }
                        }
                        else
                        {
                            //数据列数超过了Excel的列数
                        }
                    }
                    #endregion
                    #region 填充数据
    
                    int startIndex = p * rowNum;
                    int endindex = (p + 1) * rowNum - 1;
                    if (endindex >= recordNum)
                    {
                        endindex = recordNum - 1;
                    }
    
                    for (int i = startIndex; i <= endindex; i++)//遍历DataTable行
                    {
                        DataRow dataRow = dt.Rows[i];
                        
                        row = sheet.CreateRow(i - startIndex + 1);//在工作表中添加一行
    
                        if (columnFieldText != null)
                        {
                            var dataColumn = columnFieldText.GetLength(0);
                            if (dataColumn <= colNum)
                            {
                                for (int m = 0; m < dataColumn; m++)
                                {
                                    ICell cell = row.CreateCell(m);//在行中添加一列
                                    cell.SetCellValue(dataRow[columnFieldText[m, 0]].ToString());//设置列的内容
                                }
                            }
                            else
                            {
                                //数据列数超过了Excel的列数
                            }
                        }
                        else
                        {
                            var dataColumn = dt.Columns.Count;
                            if (dataColumn <= colNum)
                            {
                                for (int j = 0; j < dt.Columns.Count; j++)//遍历DataTable列
                                {
                                    ICell cell = row.CreateCell(j);//在行中添加一列
                                    cell.SetCellValue(dataRow[j].ToString());//设置列的内容     
                                }
                            }
                            else
                            {
                                //数据列数超过了Excel的列数
                            }
                        }
                    }
                    #endregion
                }
                #region 输出Excel
                using (MemoryStream stream = new MemoryStream())
                {
                    workbook.Write(stream);
                    return stream.ToArray();
                }
                #endregion
            }
    
            /// 
            /// 将excel中的数据导入到DataTable中(第一行是标题)
            /// 支持多个sheet数据导入(建议多个sheet的数据格式保持一致,将没有数据的sheet删除)
            /// 
            /// 文件路径(含文件名称后缀名)
            /// 字段对应中文 顺序需要跟Excel中数据顺序一致
            /// 指定Excel中Sheet名称 如果为null时,读取所有sheet中的数据
            /// 返回的DataTable
            public static DataTable ExcelToDataTable(string fileName, string[,] columnFieldText = null, string sheetName = null)
            {
                DataTable data = new DataTable();
                int rowNum = 0;
                int colNum = 0;
                IWorkbook workbook = GetWorkbook(fileName, out rowNum, out colNum);
    
                for (int e = 0; e < workbook.NumberOfSheets; e++)
                {
                    ISheet sheet = workbook.GetSheetAt(e);
                    if (sheet != null)
                    {
                        var currentSheetIndex = 0;
                        if (!string.IsNullOrEmpty(sheetName))
                        {
                            if (sheet.SheetName == sheetName)
                            {
                                currentSheetIndex = e;
                            }
                        }
    
                        IRow firstRow = sheet.GetRow(0);
                        if (firstRow != null)
                        {
                            int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
    
                            var dataColumn = columnFieldText != null ? columnFieldText.GetLength(0) : cellCount;
                            int startRow = sheet.FirstRowNum;
                            if (dataColumn <= colNum)
                            {
                                if (e == currentSheetIndex)
                                {
                                    for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
                                    {
                                        ICell cell = firstRow.GetCell(i);
                                        if (cell != null)
                                        {
                                            string cellValue = cell.StringCellValue;
                                            if (cellValue != null)
                                            {
                                                DataColumn column = new DataColumn((columnFieldText != null ? columnFieldText[i, 0] : cellValue));
                                                data.Columns.Add(column);
                                            }
                                        }
                                    }
                                }
    
                                startRow = sheet.FirstRowNum + 1;
    
                                //最后一列的标号
                                int rowCount = sheet.LastRowNum;
                                for (int i = startRow; i <= rowCount; ++i)
                                {
                                    IRow row = sheet.GetRow(i);
                                    if (row == null) continue; //没有数据的行默认是null       
    
                                    DataRow dataRow = data.NewRow();
                                    for (int j = row.FirstCellNum; j < cellCount; ++j)
                                    {
                                        if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
                                            dataRow[j] = row.GetCell(j).ToString();
                                    }
                                    data.Rows.Add(dataRow);
                                }
                            }
                            else
                            {
                                //数据列数超过了Excel的列数
                            }
                        }
    
                        if (!string.IsNullOrEmpty(sheetName))
                        {
                            if (sheet.SheetName == sheetName)
                            {
                                break;
                            }
                        }
                    }
                }
                return data;
            }
        }
    View Code

    2.WEB项目的调用方法:

    (1)数据导出到Excel中(支持根据DataTable数据及Excel自动分成多个Sheet)

     调用方法:

    复制代码
                    int record = 500;
                    DataTable data = CreateDataTable(record);
    
                    string fileName = "客户明细_" + DateTime.Now.ToString("MMddhhmmss") + ".xls";
                    string sheetName = "客户明细";
    
                    string[,] columnFieldText = new[,]{
                        { "ID", "编号" },
                        { "Name", "姓名" },
                        { "CreateTime", "创建时间" }
                    };
    
                    //string[,] columnFieldText = null;
    
                    var buf = NpoiExcelHelper.DataTableToExcel(data, fileName, columnFieldText, sheetName);
    
                    Response.Buffer = true;
                    Response.Clear();
                    Response.ClearHeaders();
                    Response.ClearContent();
                    Response.Charset = "UTF8";
                    Response.ContentEncoding = Encoding.UTF8;
                    Response.ContentType = "application/vnd.ms-excel";
                    string browser = Request.Browser.Browser;
                    if (browser.Contains("InternetExplorer"))
                        Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
                    else
                        Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
    
                    Response.AddHeader("Content-Length", buf.Length.ToString());
    
                    Response.Flush();
                    Response.BinaryWrite(buf);                    
    复制代码
    复制代码
            /// 
            /// 创建DataTable对象
            /// 
            public DataTable CreateDataTable(int record)
            {
                //创建DataTable
                DataTable dt = new DataTable("NewDt");
    
                //创建自增长的ID列
                DataColumn dc = dt.Columns.Add("ID", Type.GetType("System.Int32"));
                dc.AutoIncrement = true;  //自动增加
                dc.AutoIncrementSeed = 1; //起始为1
                dc.AutoIncrementStep = 1; //步长为1
                dc.AllowDBNull = false;  //非空
    
                //创建其它列表
                dt.Columns.Add(new DataColumn("Name", Type.GetType("System.String")));
                dt.Columns.Add(new DataColumn("CreateTime", Type.GetType("System.DateTime")));
    
                DataRow dr;
                for (int i = 0; i < record; i++)
                {
                    dr = dt.NewRow();
                    dr["Name"] = "名字" + i.ToString();
                    dr["CreateTime"] = DateTime.Now;
                    dt.Rows.Add(dr);
                }
                return dt;
            }    
    复制代码

    (2)Excel中数据导入DataTable中(支持指定Sheet名称 / 多个数据格式一致的Shee)

    复制代码
                    string fileName = "客户明细_0213023109.xls";
                    string sheetName = "客户明细1";
    
                    string[,] columnFieldText = new[,]{
                        { "ID", "编号" },
                        { "Name", "姓名" },
                        { "CreateTime", "创建时间" }
                    };
    
                    //string[,] columnFieldText = null;
    
                    var dt = NpoiExcelHelper.ExcelToDataTable(Server.MapPath(fileName), columnFieldText, sheetName);
    复制代码

    以上基本实现WEB通过NPOI操作Excel数据导入导出的功能。其他可自行研究。

  • 相关阅读:
    ZYNQ7020:PS控制PL动态调整PWM占空比
    数据组合利器:从入门到精通Python中的zip()函数应用
    ubuntu20.04官方安装I219-V驱动
    Mozilla 紧急修补 Firefox 和 Thunderbird 中的 WebP 严重零日漏洞
    DMA和burst不是一个概念
    数据结构与算法(C语言版)P3.2---链表之带头双向循环链表的实现
    RustDesk 搭建一个自己的远程桌面中继服务器
    C语言——九九乘法表
    内网渗透之内网信息收集(二)
    C语言 找出数组中最大的数(输入10个数)
  • 原文地址:https://www.cnblogs.com/wsk198726/p/17120104.html