NPOI无法正确读取带有公式的单元格的值

Can't read a value of the cell with a formula inside properly by NPOI

我在 C# 中写入,并使用 NPOI.SS.UserModel 编写程序以从 Excel 上的单元格获取值。

问题出在含有公式的单元格上。我正在尝试从公式单元格中获取结果值,但我做不到。

公式为:

=LOOKUP(CA36,{0,40,50,60,70,80,90;"D","C","B2","B1","A2","A1","S"})

而且,单元格的格式是:

Format Cells > Number > Category=General

要从公式单元格中读取值,有 2 种模式。 1 是按原样读取 excel 时。 2 是在编辑 excel 后读取 excel(例如在 A1 单元格中填写一些字母等)。 1和2之间的值读取方式不同

此外,一旦我将excel设置为2状态,公式单元格的所有读数都成功了。

此程序必须在 1 状态时从公式单元格中获取正确的结果值。但是我得到 0 个数字。

在我将excell状态设为2状态后,我可以得到正确的字符串值(例如“D”)。

我不知道为什么会出现这种差异。

供您参考, 当状态为 1:

cell.CellType==CellType.Formula
cell.CachedFormulaResultType==CellType.Numeric
cell.NumericCellValue=0

当2的stete:

cell.CellType==CellType.Formula
cell.CachedFormulaResultType==CellType.String
cell.StringCellValue="D"

代码如下: var book = WorkbookFactory.Create(this._fileFullPath);

//1枚目のシートを取得
var sheet = book.GetSheetAt(0);

int target_row_count = 50;
int target_col_count = 100;

List<CellData> cellDatas = new List<CellData>();

for (int i = 0; i < target_row_count; i++)
{
    int rowPosi = i + 1;
    for (int j = 0; j < target_col_count; j++)
    {
        int colPosi = j + 1;

        //テスト
        if (rowPosi == 36 && colPosi == 82) {
            Console.WriteLine("");
        }

        string value = "";

        var row = sheet.GetRow(i);
        if (row != null) {
            ICell cell = row.GetCell(j);
            if (cell != null) {
                switch (cell.CellType)
                {
                    case CellType.String:
                        value = cell.StringCellValue;
                        break;
                    case CellType.Numeric:
                        value = cell.NumericCellValue.ToString();
                        break;
                    case CellType.Boolean:
                        value = cell.BooleanCellValue.ToString();
                        break;
                    case CellType.Formula:
                        switch (cell.CachedFormulaResultType) {
                            case CellType.String:
                                value = cell.StringCellValue;
                                break;
                            case CellType.Numeric:
                                value = cell.NumericCellValue.ToString();
                                break;
                            case CellType.Blank:
                                break;
                            default:
                                StringBuilder sb = new StringBuilder();
                                sb.AppendLine($"セルタイプ({cell.CellType})ですが、");
                                sb.AppendLine($"cell.CachedFormulaResultType({cell.CachedFormulaResultType})に該当する処理がありません。");
                                throw new Exception(sb.ToString());
                        }
                        break;
                    case CellType.Blank:
                        break;
                    default:
                        throw new Exception(
                            $"セルタイプ({cell.CellType})に該当する処理がありません。");
                }
                
                CellData cellData = new CellData(
                    new CellPosition(
                        rowPosi,
                        colPosi),
                    value);

                cellDatas.Add(cellData);
            }
        }
    }
}

开门见山,在编辑 Excel 文件的过程中,通过将模块从 ClosedXML 更改为 NPOI 解决了这个问题。

我会解释发生了什么:

  1. 准备了模板Excel文件(以下简称TEMP)。 TEMP 有一个单元格,其中包含我在 OP 中解释的查找公式。
  2. 复制了TEMP并新建了Excel文件(以下简称NEW)。通过 ClosedXML 编辑了 NEW 上的一些单元格。
  3. 阅读 NPOI 的新内容。无法使用查找公式正确读取单元格的单元格值。 (这是OP。)
  4. 更改了步骤 2 过程的程序。使过程由 NPOI 完成,而不是由 ClosedXML 完成。
  5. 使用新修改的程序,创建新文件并读取新文件。使用查找公式从单元格中成功读取单元格值。

程序中混淆了ClosedXML和NPOI的原因。它过去只使用 ClosedXML 模块来编辑和读取 Excel 文件。但是,当发生“另一个”问题(无法使用查找公式从单元格中读取单元格值)时,我将 ClosedXML 的模块更改为 NPOI,仅用于读取 Excel 文件的过程。因为我发现网上有文章指出 ClosedXML 和 Lookup 公式不支持的公式是这样的。但是,对于编辑Excel个文件的过程,看起来没有任何问题,所以我继续使用ClosedXML来编辑Excel个文件。

但是,在这一次的问题中,当您使用 ClosedXML 编辑 Excel 文件时,该文件的单元格中包含不受支持的公式(如查找公式),不知何故公式尚未计算或计算。而且读的时候,不能正确读出计算出来的cellvalue