C# 在ASP.NET核心应用程序中进行二次读取时NPOI失败

C# 在ASP.NET核心应用程序中进行二次读取时NPOI失败,c#,asp.net-core,filestream,npoi,C#,Asp.net Core,Filestream,Npoi,在我的ASP.NET核心应用程序中,我正在使用NPOI读取Excel文件。工作簿的创建方式如下: public void ImportFile() { using var fileStream = new FileStream("path_to_file.xlsm", FileMode.Open, FileAccess.Read, FileShare.ReadWrite); var workbook = WorkbookFact

在我的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
,它使用
打包在
中-我还与ResourceManager进行了检查,在调用之间无法访问文件)

我真的不知道哪个引用是
null
它不是
单元格
对象本身
-我可以通过调试器访问它的属性。整个工作簿似乎也被正确加载(同样,通过调试器访问它)

若它是相关的,那个么无法读取的单元格将保留对另一个工作表上单元格的引用,它的类型将设置为Date

在第一次调用ImportFile()方法时,一切正常。那么, 对它的每次后续调用都会导致一个错误- 函数在ReadDateTimeAt中引发NullReferenceException cell.DateCellValue。只有重新启动整个应用程序才有帮助

我确实再现了你的错误。这应该是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));

        }

谢谢你,你帮助我最终解决了这个问题,这是我一个人做不到的。只需注意一点:对于我的案例(公式单元格),需要有一个名为的求值器,类似于:
if(cell.CellType==CellType.formula){evaluator.EvaluateInCell(cell);}
其中,求值器是XSSFFormulaEvaluator对象,否则总是选择开关的defult子句。事实证明,在第二次读取过程中,由于某种原因,公式是未计算的(正如您所说,可能是一个内部NPOI错误-我已经为此打开了一个实例)。