ASP.NET 核心应用中的第二次读取 NPOI 失败
NPOI fails on second read in ASP.NET Core app
在我的 ASP.NET 核心应用程序中,我正在使用 NPOI 读取 Excel 文件。工作簿是这样创建的:
public void ImportFile()
{
using var fileStream = new FileStream("path_to_file.xlsm", FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
var workbook = WorkbookFactory.Create(fileStream);
// all the reads and persistence stuff
}
所有读取都是这样执行的:
public static DateTime ReadDateTimeAt(IRow row, int columnIndex)
{
var cell = row.GetCell(columnIndex, MissingCellPolicy.CREATE_NULL_AS_BLANK);
try
{
return cell.DateCellValue;
}
catch
{
// handling logic
}
}
第一次调用方法 ImportFile()
时一切正常。然后,对它的每次后续调用都会导致错误 - NullReferenceException
被 cell.DateCellValue
抛入 ReadDateTimeAt
函数。只有重新启动整个应用程序才有帮助。
为什么可以呢?我是不是没有正确地释放一些资源(我想我这样做了,但我认为我应该释放的唯一一个是 FileStream
,它被打包在 using
中 - 我还检查了 ResourceManager 和文件调用之间不访问)?
我真的分不清哪个参考文献是 null
。 它不是 Cell
对象本身 - 我可以通过调试器访问它的属性。整个工作簿似乎也已正确加载(同样,通过调试器访问它)。
如果相关,读取失败的单元格将引用另一个 Sheet 上的单元格,其类型设置为日期。
On the first call to method ImportFile() it all works just fine. Then,
each subsequent call to it results in an error -
NullReferenceException is thrown in ReadDateTimeAt function by
cell.DateCellValue. Only restart of the whole app helps.
我确实重现了你的错误。这应该是NPOI的内部错误。
可以使用以下方法解决
public static string GetStringValue(ICell cell)
{
switch (cell.CellType)
{
case CellType.Numeric:
if (DateUtil.IsCellDateFormatted(cell))
{
return DateTime.FromOADate(cell.NumericCellValue).ToString();
//try
//{
// return cell.DateCellValue.ToString();
//}
//catch (NullReferenceException)
//{
// return DateTime.FromOADate(cell.NumericCellValue).ToString();
//}
}
return cell.NumericCellValue.ToString();
case CellType.String:
return cell.StringCellValue;
case CellType.Boolean:
return cell.BooleanCellValue.ToString();
default:
return string.Empty;
}
}
ReadDateTimeAt 方法:
public static DateTime ReadDateTimeAt(IRow row, int columnIndex)
{
var cell = row.GetCell(columnIndex, MissingCellPolicy.CREATE_NULL_AS_BLANK);
return DateTime.Parse(GetStringValue(cell));
}
在我的 ASP.NET 核心应用程序中,我正在使用 NPOI 读取 Excel 文件。工作簿是这样创建的:
public void ImportFile()
{
using var fileStream = new FileStream("path_to_file.xlsm", FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
var workbook = WorkbookFactory.Create(fileStream);
// all the reads and persistence stuff
}
所有读取都是这样执行的:
public static DateTime ReadDateTimeAt(IRow row, int columnIndex)
{
var cell = row.GetCell(columnIndex, MissingCellPolicy.CREATE_NULL_AS_BLANK);
try
{
return cell.DateCellValue;
}
catch
{
// handling logic
}
}
第一次调用方法 ImportFile()
时一切正常。然后,对它的每次后续调用都会导致错误 - NullReferenceException
被 cell.DateCellValue
抛入 ReadDateTimeAt
函数。只有重新启动整个应用程序才有帮助。
为什么可以呢?我是不是没有正确地释放一些资源(我想我这样做了,但我认为我应该释放的唯一一个是 FileStream
,它被打包在 using
中 - 我还检查了 ResourceManager 和文件调用之间不访问)?
我真的分不清哪个参考文献是 null
。 它不是 Cell
对象本身 - 我可以通过调试器访问它的属性。整个工作簿似乎也已正确加载(同样,通过调试器访问它)。
如果相关,读取失败的单元格将引用另一个 Sheet 上的单元格,其类型设置为日期。
On the first call to method ImportFile() it all works just fine. Then, each subsequent call to it results in an error - NullReferenceException is thrown in ReadDateTimeAt function by cell.DateCellValue. Only restart of the whole app helps.
我确实重现了你的错误。这应该是NPOI的内部错误。
可以使用以下方法解决
public static string GetStringValue(ICell cell)
{
switch (cell.CellType)
{
case CellType.Numeric:
if (DateUtil.IsCellDateFormatted(cell))
{
return DateTime.FromOADate(cell.NumericCellValue).ToString();
//try
//{
// return cell.DateCellValue.ToString();
//}
//catch (NullReferenceException)
//{
// return DateTime.FromOADate(cell.NumericCellValue).ToString();
//}
}
return cell.NumericCellValue.ToString();
case CellType.String:
return cell.StringCellValue;
case CellType.Boolean:
return cell.BooleanCellValue.ToString();
default:
return string.Empty;
}
}
ReadDateTimeAt 方法:
public static DateTime ReadDateTimeAt(IRow row, int columnIndex)
{
var cell = row.GetCell(columnIndex, MissingCellPolicy.CREATE_NULL_AS_BLANK);
return DateTime.Parse(GetStringValue(cell));
}