C# NPOI Excel应用

左心房为你撑大大i 提交于 2019-12-26 17:11:19

参考链接

https://www.cnblogs.com/tangpeng97/p/7839189.html
https://www.cnblogs.com/chenyanbin/archive/2019/05/10/10832614.html

准备工作

  • 安装好插件后,需要重写方法 //年代有点久,忘记为什么要重写了
        /// <summary>
        /// 重写Npoi方法
        /// </summary>
        public class NpoiMemoryStream : MemoryStream
        {
            public NpoiMemoryStream()
            {
                AllowClose = true;
            }

            public bool AllowClose { get; set; }

            public override void Close()
            {
                if (AllowClose)
                    base.Close();
            }
        }

Excel文件转DataTable

注意点

  • xlsx和xls 需要分别对应两个类型,xlsx对应XSSFWorkbook,xls对应HSSFWorkbook

根据文件路径得到Excel转Datatable

                XSSFWorkbook workbook = new XSSFWorkbook("D:\\test.xlsx");//这段没测试,应该可以用
                NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0);
                DataTable dt = new DataTable(sheet.SheetName);

                // write header row
                IRow headerRow = sheet.GetRow(0);
                foreach (ICell headerCell in headerRow)
                {
                    dt.Columns.Add(headerCell.ToString());
                }

                // write the rest
                int rowIndex = 0;
                foreach (IRow row in sheet)
                {
                    // skip header row
                    if (rowIndex++ == 0) continue;
                    DataRow dataRow = dt.NewRow();
                    dataRow.ItemArray = row.Cells.Select(c => c.ToString()).ToArray();
                    dt.Rows.Add(dataRow);
                }
                return dt;

根据文件转换成字节流生成DataTable

        /// <summary>
        /// 根据上传文件得到DataTable
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static DataTable GetDataTableByExcelFile(HttpPostedFileBase file)
        {
            DataTable result = new DataTable();
            if (file.FileName.EndsWith(".xlsx"))
            {
                result = GetDataTableByStream(file.InputStream, ".xlsx");
                return result;
            }
            else if (file.FileName.EndsWith(".xls"))
            {
                result = GetDataTableByStream(file.InputStream, ".xls");
                return result;
            }
            else
                throw new Exception("文件格式不正确,只允许.xlsx或.xls");
        }
        
        /// <summary>
        /// 根据字节流生成DataTable,默认只取第一张表格
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static DataTable GetDataTableByStream(Stream stream,string type)
        {
            DataTable dt = new DataTable();
            NPOI.SS.UserModel.ISheet sheet;
            switch (type)
            {
                case ".xlsx":
                    {
                        XSSFWorkbook workbook = new XSSFWorkbook(stream);
                        sheet = workbook.GetSheetAt(0);
                        dt = new DataTable(sheet.SheetName);
                        break;
                    }
                case ".xls":
                    {
                        HSSFWorkbook workbook = new HSSFWorkbook(stream);
                        sheet = workbook.GetSheetAt(0);
                        dt = new DataTable(sheet.SheetName);
                        break;
                    }
                default:
                    {
                        throw new Exception("传入参数不正确");
                    }
            }
            // write header row
            IRow headerRow = sheet.GetRow(0);
            foreach (ICell headerCell in headerRow)
            {
                dt.Columns.Add(headerCell.ToString());
            }

            // write the rest
            int rowIndex = 0;
            foreach (IRow row in sheet)
            {
                // skip header row
                if (rowIndex++ == 0) continue;
                DataRow dataRow = dt.NewRow();
                dataRow.ItemArray = row.Cells.Select(c => c.ToString()).ToArray();
                dt.Rows.Add(dataRow);
            }
            return dt;

        }

调用方式

    DataTable dt =GetDataTableByExcelFile(file);

根据DataTable生成Excel文件

  • 可传入单个DataTable或者List
        /// <summary>
        /// 根据DataTable 生成Excel
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static NpoiMemoryStream GetExcelFile( DataTable source)
        {
     
            //创建Excel文件的对象,XLSX 
            XSSFWorkbook book = new XSSFWorkbook();
            //添加一个sheet
            ISheet sheet = book.CreateSheet($"OA导出");

            //行下标记录
            int rowIndex = 0;
            //创建首行
            IRow row0 = sheet.CreateRow(rowIndex++);
            ////创建单元格
            //ICell cell0 = row0.CreateCell(0);
            ////设置单元格内容


            //cell0.CellStyle.Alignment = HorizontalAlignment.CenterSelection;

            //cell0.SetCellValue("料品情况查询");
            //sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, source.Columns.Count));

           // IRow row1 = sheet.CreateRow(rowIndex++);
            for (var i = 0; i < source.Columns.Count; i++)
            {
                row0.CreateCell(i).SetCellValue(source.Columns[i].ToString());
            }


            for (var i = 0; i < source.Rows.Count; i++)
            {

                IRow rowTemp = sheet.CreateRow(rowIndex++);

                for (var j = 0; j < source.Columns.Count; j++)
                {

                    if (source.Rows[i][j].GetType().Name == "Decimal")
                    {
                        rowTemp.CreateCell(j).SetCellValue(Convert.ToDouble(source.Rows[i][j]));
                    }
                    else
                    {
                        rowTemp.CreateCell(j).SetCellValue(source.Rows[i][j].ToString());
                    }

                }
            }



            for (int columnNum = 0; columnNum < source.Columns.Count; columnNum++)
            {
                int columnWidth = sheet.GetColumnWidth(columnNum) / 256;//获取当前列宽度  
                for (int rowNum = 1; rowNum <= sheet.LastRowNum; rowNum++)//在这一列上循环行  
                {
                    IRow currentRow = sheet.GetRow(rowNum);
                    ICell currentCell = currentRow.GetCell(columnNum);
                    int length = Encoding.UTF8.GetBytes(currentCell.ToString()).Length;//获取当前单元格的内容宽度  
                    if (columnWidth < length + 1)
                    {
                        columnWidth = length + 1;
                    }//若当前单元格内容宽度大于列宽,则调整列宽为当前单元格宽度,后面的+1是我人为的将宽度增加一个字符  
                }
                //sheet.SetColumnWidth(columnNum, columnWidth * 256);
                if (columnWidth > 255)
                {
                    columnWidth = 254;
                }
                else
                {
                    sheet.SetColumnWidth(columnNum, columnWidth * 256);
                }
   
            }
            var ms = new NpoiMemoryStream();
            ms.AllowClose = false;
            book.Write(ms);
            ms.Flush();
            ms.Seek(0, SeekOrigin.Begin);
            ms.AllowClose = true;

            return ms;
        }

        /// <summary>
        /// 根据多个DataTable 生成一个Excel多个表
        /// </summary>
        /// <param name="sources"></param>
        /// <returns></returns>
        public static NpoiMemoryStream GetExcelFile(List<DataTable> sources)
        {

            //创建Excel文件的对象,XLSX 
            XSSFWorkbook book = new XSSFWorkbook();
            int flag = 1;
            foreach(DataTable source in sources)
            {
                //添加一个sheet
                ISheet sheet = book.CreateSheet($"OA导出"+flag);

                //行下标记录
                int rowIndex = 0;
                //创建首行
                IRow row0 = sheet.CreateRow(rowIndex++);
                ////创建单元格
                //ICell cell0 = row0.CreateCell(0);
                ////设置单元格内容


                //cell0.CellStyle.Alignment = HorizontalAlignment.CenterSelection;

                //cell0.SetCellValue("料品情况查询");
                //sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, source.Columns.Count));

                // IRow row1 = sheet.CreateRow(rowIndex++);
                for (var i = 0; i < source.Columns.Count; i++)
                {
                    row0.CreateCell(i).SetCellValue(source.Columns[i].ToString());
                }


                for (var i = 0; i < source.Rows.Count; i++)
                {

                    IRow rowTemp = sheet.CreateRow(rowIndex++);

                    for (var j = 0; j < source.Columns.Count; j++)
                    {

                        if (source.Rows[i][j].GetType().Name == "Decimal")
                        {
                            rowTemp.CreateCell(j).SetCellValue(Convert.ToDouble(source.Rows[i][j]));
                        }
                        else
                        {
                            rowTemp.CreateCell(j).SetCellValue(source.Rows[i][j].ToString());
                        }

                    }
                }
                for (int columnNum = 0; columnNum < source.Columns.Count; columnNum++)
                {
                    int columnWidth = sheet.GetColumnWidth(columnNum) / 256;//获取当前列宽度  
                    for (int rowNum = 1; rowNum <= sheet.LastRowNum; rowNum++)//在这一列上循环行  
                    {
                        IRow currentRow = sheet.GetRow(rowNum);
                        ICell currentCell = currentRow.GetCell(columnNum);
                        int length = Encoding.UTF8.GetBytes(currentCell.ToString()).Length;//获取当前单元格的内容宽度  
                        if (columnWidth < length + 1)
                        {
                            columnWidth = length + 1;
                        }//若当前单元格内容宽度大于列宽,则调整列宽为当前单元格宽度,后面的+1是我人为的将宽度增加一个字符  
                    }
                    //sheet.SetColumnWidth(columnNum, columnWidth * 256);
                    if (columnWidth > 255)
                    {
                        columnWidth = 254;
                    }
                    else
                    {
                        sheet.SetColumnWidth(columnNum, columnWidth * 256);
                    }

                }
                flag++;
            }
            var ms = new NpoiMemoryStream();
            ms.AllowClose = false;
            book.Write(ms);
            ms.Flush();
            ms.Seek(0, SeekOrigin.Begin);
            ms.AllowClose = true;

            return ms;
        }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!