当前位置 博文首页 > DisonTangor:C#开发之基于NPOI的操作Excel开发体验

    DisonTangor:C#开发之基于NPOI的操作Excel开发体验

    作者:DisonTangor 时间:2021-06-16 18:25

    最近遇到一个数据导入的需求,语言是.net framework 4.7的C#。但是,这次主要探讨NPOI的体验,原则就是向前兼容。所以采用.xls的支持。网上的资料,我稍微整合了一些。
    最近遇到一个数据导入的需求,语言是.net framework 4.7的C#。但是,这次主要探讨NPOI的体验,原则就是向前兼容。所以采用.xls的支持。网上的资料,我稍微整合了一些。

    #1 单元格下拉框

    在开发中我们会遇到为单元格设置下拉框。一般可以编写如下:

    var cellRanges = new CellRangeAddressList(firstRow, lastRow, firstCol, latsCol);
    DVConstraint constraint = DVConstraint.CreateExplicitListConstraint(stringArray);
    HSSFDataValidation validate = new HSSFDataValidation(cellRanges, constraint);
    validate.ShowProptBox = true;
    sheet.AddValidationData(validate);

    但是,如果字符串数组存在长度限制,如NPOI导出Excel时下拉列表值超过255的问题(String literals in formulas can't be bigger than 255 characters ASCII)
    解决方案

    通过额外新建Excel的Sheet页保存下拉内容,并转换为下拉框数据。

    ISheet hidden = workbook.CreateSheet(columnName);
    IRow row = null;
    ICell cell = null;
    for (int i = 0; i < stringArray.Length; i++)
    {
        row = hidden.CreateRow(i);
        cell = row.CreateCell(0);
        cell.SetCellValue(stringArray[i]);
    }
    IName namedCell = workbook.CreateName();
    namedCell.NameName = column.ColumnName;
    // 注意下面的语法是Excel的公式,建议不要落掉一个`$`,很多文档都要所遗漏。
    namedCell.RefersToFormula = $"{columnName}!$A$1:$A${stringArray.Length}";
    DVConstraint constraint =  DVConstraint.CreateFormulaListConstraint(columnName);
    CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, latsCol);
    HSSFDataValidation validate = new HSSFDataValidation(addressList, constraint);
    sheet.AddValidationData(dataValidate);
    

    #2 添加批注

    代码如下:

    HSSFPatriarch patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch();
    // 这个代码参数不要写成固定的,它用来定位你的批注的位置和大小。
    HSSFComment comment = 
        (HSSFComment)patriarch.CreateCellComment(new HSSFFClientAnchor(0, 0, 255,255, col1, 0, col1 + 2, 5));
    comment.Author = "Dison";
    comment.String = new HSSFRichTextString($"内容");
    cell.CellComment = comment;
    

    #3 读取数据

    如何解析公式的结果

    代码如下:

    if (row.GetCell(i).CellType.Equals(CellType.Formula))
    {
        var data = row.GetCell(i).RichStringCellValue;
    }
    

    如果希望读取公式也可以如下:

    var data = row.GetCell(i).ToString();

    但是需要注意结果没有等号“=”, 这里我是演示,所以写了局部变量。

    日期格式 MM-dd-yy 转 yyyy-MM-dd

    由于Excel的数字和日期都是Numeric格式,;处理如下:

    if (row.GetCell(i).CellType.Equals(CellType.Numeric))
    {
        ICell cell = row.GetCell(i);
        short format = cell.CellStyle.DataFormat;
        if (format != 0)
        {
            var data = cell.DateCellValue.ToString("yyyy-MM-dd");
        }
        else 
        {
            var data = cell.NumericCellValue;
        }
    }
    

    结语

    NPOI还是一个相对成熟的Excel操作库。网上的资料确实写的比较潦草。但是作为程序员,必须学会耐心,尤其是debug。

    参考文档

    • POI导出Excel时下拉列表值超过255的问题(String literals in formulas can't be bigger than 255 characters ASCII)
    • NPOI 导出添加批注功能
    • C# NPOI 日期格式
    bk