• 使用NPOI进行Excel数据的导入导出


    一、概述

    NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目, 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。

    完整教程:https://www.cnblogs.com/atao/archive/2009/11/15/1603528.html

    1、操作Excel的类库:

    3、引用DLL

    使用时需引用需要引用所有5个dll

    • ICSharpCode.SharpZipLib.dll
    • NPOI.dll
    • NPOI.OOXML.dll
    • NPOI.OpenXml4Net.dll
    • NPOI.OpenXmlFormats.dll

    image

    程序集构成

    image

     image

    二、通过NPOI,将Excel文件导到数据表DataTable

    DataTable dt = ImportToTable("00.xls");
    if (dt != null)
    {
        Console.Write(dt.Rows.Count);
        Console.ReadKey();
    }

    public static DataTable ImportToTable(string fileName)
    {
        DataTable dt = new DataTable();
        IWorkbook workbook;
        string fileExt = Path.GetExtension(fileName).ToLower();
        using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
        {
            //XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式
            if (fileExt == ".xlsx")
            {
                workbook = new XSSFWorkbook(fs);
            }
            else if (fileExt == ".xls")
            {
                workbook = new HSSFWorkbook(fs);
            }
            else
            {
                workbook = null;
                return null;
            }
    
            ISheet sheet = workbook.GetSheetAt(0);//Sheet总数量:workbook.NumberOfSheets
    
            //表头  
            IRow header = sheet.GetRow(sheet.FirstRowNum);
            for (int i = 0; i < header.LastCellNum; i++)
            {
                object obj = GetValueType(header.GetCell(i));
                if (obj == null || obj.ToString() == string.Empty)
                {
                    dt.Columns.Add(new DataColumn("Columns" + i.ToString()));
                }
                else
    
                    dt.Columns.Add(new DataColumn(obj.ToString()));
            }
            //数据  
            for (int i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++)
            {
                DataRow dr = dt.NewRow();
                bool hasValue = false;
                IRow row = sheet.GetRow(i);
                for (int j = row.FirstCellNum; j < row.LastCellNum; j++)
                {
                    dr[j] = GetValueType(sheet.GetRow(i).GetCell(j));
                    if (dr[j] != null && dr[j].ToString() != string.Empty)
                    {
                        hasValue = true;
                    }
                }
                if (hasValue)
                {
                    dt.Rows.Add(dr);
                }
            }
    
            return dt;
        }
    
    }
    /// <summary>
    /// 获取单元格类型
    /// </summary>
    /// <param name="cell"></param>
    /// <returns></returns>
    /// 
    static object GetValueType(ICell cell)
    {
        if (cell == null)
            return null;
        switch (cell.CellType)
        {
            case CellType.Blank: //BLANK:  
                return null;
            case CellType.Boolean: //BOOLEAN:  
                return cell.BooleanCellValue;
            case CellType.Numeric: //NUMERIC:  
                return cell.NumericCellValue;
            case CellType.String: //STRING:  
                return cell.StringCellValue;
            case CellType.Error: //ERROR:  
                return cell.ErrorCellValue;
            case CellType.Formula: //FORMULA:  
            default:
                return "=" + cell.CellFormula;
        }
    }
    }

    四、常见用法:

    1、查找

    IEnumerator rows = sheet.GetEnumerator();
    while (rows.MoveNext())
    {
        IRow row = (HSSFRow)rows.Current;
        ICell cell = row.GetCell(0);
        if (cell != null && cell.StringCellValue == "XX")
        {
            return row.GetCell(1).StringCellValue;
        }
    }

    2、插入图片

    IWorkbook workbook = new HSSFWorkbook();
    
    //add picture data to this workbook.
    byte[] bytes = System.IO.File.ReadAllBytes(@"00.jpg");
    int pictureIdx = workbook.AddPicture(bytes, PictureType.JPEG);
    
    //create sheet
    ISheet sheet = workbook.CreateSheet("Sheet1");
    
    // Create the drawing patriarch.  This is the top level container for all shapes. 
    IDrawing patriarch = sheet.CreateDrawingPatriarch();
    
    //add a picture
    HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 0, 0, 0, 1, 3);
    IPicture pict = patriarch.CreatePicture(anchor, pictureIdx);
    
    //保存为Excel文件  
    using (FileStream fs = new FileStream("00_new.xls", FileMode.Create, FileAccess.Write))
    {
        workbook.Write(fs);
    }

    五、填充Excel模板

    IWorkbook workbook;
    using (FileStream fs = new FileStream("模板文件.xls", FileMode.Open, FileAccess.Read))
    {
        workbook = new HSSFWorkbook(fs);
    }
    
    ISheet cloneSheet = workbook.CloneSheet(workbook.GetSheetIndex("Sheet1"));//复制第一个模板Sheet
    cloneSheet.ForceFormulaRecalculation = true;
    workbook.SetSheetName(workbook.GetSheetIndex(cloneSheet), "SheetClone");//设置新SheetName
    
    cloneSheet.GetRow(4).GetCell(1).SetCellValue("a");//为已经存在的单元格赋值
    
    IRow row = cloneSheet.GetRow(15);
    if (row == null)
        row = cloneSheet.CreateRow(15);
    ICell cell = row.GetCell(7);
    if (cell == null)
        cell = row.CreateCell(7);
    cell.SetCellValue("XX");// 为不存在的单元格,先新建再赋值
    
    cloneSheet.ShiftRows(51, 60, 34);//51-60行(尾部)整体移动34行,腾出更多控件插入多行数据
    workbook.RemoveSheetAt(workbook.GetSheetIndex("Sheet1"));//移除原模板Sheet
    
    FileStream fs_new = new FileStream(DateTime.Now.Ticks + ".xls", FileMode.Create);
    workbook.Write(fs_new);
    fs_new.Close();

    六、DataTable导出到Excel文件

    1、直接导出到Excel:

    调用方式:

    ExportToExcel(dt, "00_new.xls");

    代码

    public static void ExportToExcel(DataTable dt, string fileName)
    {
        IWorkbook workbook;
        string fileExt = Path.GetExtension(fileName).ToLower();
        //XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式
        if (fileExt == ".xlsx")
        {
            workbook = new XSSFWorkbook();
        }
        else if (fileExt == ".xls")
        {
            workbook = new HSSFWorkbook();
        }
        else
        {
            workbook = null;
            return;
        }
    
        ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(dt.TableName);
    
        //表头  
        IRow row = sheet.CreateRow(0);
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            ICell cell = row.CreateCell(i);
            cell.SetCellValue(dt.Columns[i].ColumnName);
        }
    
        //数据  
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            IRow row1 = sheet.CreateRow(i + 1);
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                ICell cell = row1.CreateCell(j);
                cell.SetCellValue(dt.Rows[i][j].ToString());
            }
        }
    
        //保存为Excel文件  
        using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
        {
            workbook.Write(fs);
        }
    }

    2、将DataTable导出到Excel:先导出到MemoryStream

    public static MemoryStream ExportToExcel(DataTable dt, string HeaderText)
    {
        var workbook = new HSSFWorkbook();
        ISheet sheet = workbook.CreateSheet(string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName);
    
        //右击文件“属性”信息
        #region 文件属性信息
        {
            var dsi = PropertySetFactory.CreateDocumentSummaryInformation();
            dsi.Company = "NPOI";
            workbook.DocumentSummaryInformation = dsi;
    
            SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
            si.Author = "文件作者信息";
            si.ApplicationName = "创建程序信息";
            si.LastAuthor = "最后保存者信息";
            si.Comments = "作者信息";
            si.Title = "标题信息";
            si.Subject = "主题信息";
            si.CreateDateTime = DateTime.Now;
            workbook.SummaryInformation = si;
        }
        #endregion
    
        //格式
        var dateStyle = workbook.CreateCellStyle();
        var format = workbook.CreateDataFormat();
        dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");//日期格式
    
        //取得列宽
        var arrColWidth = new int[dt.Columns.Count];
        foreach (DataColumn item in dt.Columns)
        {
            arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
        }
        for (var i = 0; i < dt.Rows.Count; i++)
        {
            for (var j = 0; j < dt.Columns.Count; j++)
            {
                int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length;
                if (intTemp > arrColWidth[j])
                {
                    arrColWidth[j] = intTemp;
                }
            }
        }
        int rowIndex = 0;
        foreach (DataRow row in dt.Rows)
        {
            #region 表头 列头
            if (rowIndex == 65535 || rowIndex == 0)
            {
                if (rowIndex != 0)
                {
                    sheet = workbook.CreateSheet();//超过65535行,则新建一个Sheet
                }
    
                #region 表头及样式
                {
                    var headerRow = sheet.CreateRow(0);
                    headerRow.HeightInPoints = 25;
                    headerRow.CreateCell(0).SetCellValue(HeaderText);
                    //CellStyle
                    ICellStyle headStyle = workbook.CreateCellStyle();
                    headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中    
                    headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 
                                                                            // 设置单元格的背景颜色(单元格的样式会覆盖列或行的样式)    
                    headStyle.FillForegroundColor = (short)11;
                    //定义font
                    IFont font = workbook.CreateFont();
                    font.FontHeightInPoints = 20;
                    font.Boldweight = 700;
                    headStyle.SetFont(font);
                    headerRow.GetCell(0).CellStyle = headStyle;
                    sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, dt.Columns.Count - 1));//合并区域
                }
                #endregion
    
    
                #region 列头及样式
                {
                    var headerRow = sheet.CreateRow(1);
                    //CellStyle
                    ICellStyle headStyle = workbook.CreateCellStyle();
                    headStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;// 左右居中    
                    headStyle.VerticalAlignment = VerticalAlignment.Center;// 上下居中 
                                                                            //定义font
                    IFont font = workbook.CreateFont();
                    font.FontHeightInPoints = 10;
                    font.Boldweight = 700;
                    headStyle.SetFont(font);
    
                    foreach (DataColumn column in dt.Columns)
                    {
                        headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                        headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
                        sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);//设置列宽
                    }
                }
                #endregion
    
                rowIndex = 2;//数据行RowIndex为2(表头和列头个占一行)
            }
            #endregion
    
    
            #region 内容
            var dataRow = sheet.CreateRow(rowIndex);
            foreach (DataColumn column in dt.Columns)
            {
                var newCell = dataRow.CreateCell(column.Ordinal);
    
                string drValue = row[column].ToString();
    
                switch (column.DataType.ToString())
                {
                    case "System.String"://字符串类型
                        newCell.SetCellValue(drValue);
                        break;
                    case "System.DateTime"://日期类型
                        DateTime dateV;
                        DateTime.TryParse(drValue, out dateV);
                        newCell.SetCellValue(dateV);
    
                        newCell.CellStyle = dateStyle;//格式化显示
                        break;
                    case "System.Boolean"://布尔型
                        bool boolV = false;
                        bool.TryParse(drValue, out boolV);
                        newCell.SetCellValue(boolV);
                        break;
                    case "System.Int16"://整型
                    case "System.Int32":
                    case "System.Int64":
                    case "System.Byte":
                        int intV = 0;
                        int.TryParse(drValue, out intV);
                        newCell.SetCellValue(intV);
                        break;
                    case "System.Decimal"://浮点型
                    case "System.Double":
                        double doubV = 0;
                        double.TryParse(drValue, out doubV);
                        newCell.SetCellValue(doubV);
                        break;
                    case "System.DBNull"://空值处理
                        newCell.SetCellValue("");
                        break;
                    default:
                        newCell.SetCellValue("");//设置单元格公式:newCell.SetCellFormula("SUM($B0:$D0)")
                        break;
                }
    
            }
            #endregion
    
            rowIndex++;
        }
        //自动列宽
        for (int i = 0; i <= dt.Columns.Count; i++)
            sheet.AutoSizeColumn(i, true);
    
        using (MemoryStream ms = new MemoryStream())
        {
            workbook.Write(ms);
            ms.Flush();
            ms.Position = 0;
            return ms;
        }
    }

    3、应用

    1、Web导出

    public static void ExportToExcelByWeb(DataTable dt, string HeaderText, string FileName)
    {
        HttpContext context = HttpContext.Current;
        context.Response.ContentType = "application/vnd.ms-excel";
        context.Response.ContentEncoding = Encoding.UTF8;
        context.Response.Charset = "UTF-8";
        context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", HttpUtility.UrlEncode(FileName, Encoding.UTF8)));
        byte[] data = ExportToExcel(dt, HeaderText).GetBuffer();//Read()方法也可以
        context.Response.BinaryWrite(data);//     或者: context.Response.OutputStream.Write(data,0,data.Length)
        context.Response.End();
    }

    2、Winform导出

    public static void ExportToExcel(DataTable dt, string HeaderText, string FileName)
    {
        using (MemoryStream ms = ExportToExcel(dt, HeaderText))
        {
            using (FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write))
            {
                byte[] data = ms.ToArray();//跟GetBuffer()对比,速度稍慢,但无空数据
                fs.Write(data, 0, data.Length);
                fs.Flush();
            }
        }
    }

    GridView导出到Excel

    Web中的GridView可直接导出到Excel:renderControl()

  • 相关阅读:
    使用FolderBrowserDialog组件选择文件夹
    使用OpenFileDialog组件打开多个文
    使用OpenFileDialog组件打开对话框
    获取弹出对话框的相关返回值
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1137 Final Grading (25 分)
    PAT 甲级 1137 Final Grading (25 分)
  • 原文地址:https://www.cnblogs.com/springsnow/p/13123912.html
Copyright © 2020-2023  润新知