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 解决了这个问题。
我会解释发生了什么:
- 准备了模板Excel文件(以下简称TEMP)。 TEMP 有一个单元格,其中包含我在 OP 中解释的查找公式。
- 复制了TEMP并新建了Excel文件(以下简称NEW)。通过 ClosedXML 编辑了 NEW 上的一些单元格。
- 阅读 NPOI 的新内容。无法使用查找公式正确读取单元格的单元格值。 (这是OP。)
- 更改了步骤 2 过程的程序。使过程由 NPOI 完成,而不是由 ClosedXML 完成。
- 使用新修改的程序,创建新文件并读取新文件。使用查找公式从单元格中成功读取单元格值。
程序中混淆了ClosedXML和NPOI的原因。它过去只使用 ClosedXML 模块来编辑和读取 Excel 文件。但是,当发生“另一个”问题(无法使用查找公式从单元格中读取单元格值)时,我将 ClosedXML 的模块更改为 NPOI,仅用于读取 Excel 文件的过程。因为我发现网上有文章指出 ClosedXML 和 Lookup 公式不支持的公式是这样的。但是,对于编辑Excel个文件的过程,看起来没有任何问题,所以我继续使用ClosedXML来编辑Excel个文件。
但是,在这一次的问题中,当您使用 ClosedXML 编辑 Excel 文件时,该文件的单元格中包含不受支持的公式(如查找公式),不知何故公式尚未计算或计算。而且读的时候,不能正确读出计算出来的cellvalue
我在 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 解决了这个问题。
我会解释发生了什么:
- 准备了模板Excel文件(以下简称TEMP)。 TEMP 有一个单元格,其中包含我在 OP 中解释的查找公式。
- 复制了TEMP并新建了Excel文件(以下简称NEW)。通过 ClosedXML 编辑了 NEW 上的一些单元格。
- 阅读 NPOI 的新内容。无法使用查找公式正确读取单元格的单元格值。 (这是OP。)
- 更改了步骤 2 过程的程序。使过程由 NPOI 完成,而不是由 ClosedXML 完成。
- 使用新修改的程序,创建新文件并读取新文件。使用查找公式从单元格中成功读取单元格值。
程序中混淆了ClosedXML和NPOI的原因。它过去只使用 ClosedXML 模块来编辑和读取 Excel 文件。但是,当发生“另一个”问题(无法使用查找公式从单元格中读取单元格值)时,我将 ClosedXML 的模块更改为 NPOI,仅用于读取 Excel 文件的过程。因为我发现网上有文章指出 ClosedXML 和 Lookup 公式不支持的公式是这样的。但是,对于编辑Excel个文件的过程,看起来没有任何问题,所以我继续使用ClosedXML来编辑Excel个文件。
但是,在这一次的问题中,当您使用 ClosedXML 编辑 Excel 文件时,该文件的单元格中包含不受支持的公式(如查找公式),不知何故公式尚未计算或计算。而且读的时候,不能正确读出计算出来的cellvalue