在ASP.NET Core应用中第二次读取NPOI失败

问题描述

在我的ASP.NET Core应用程序中,我正在使用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()时,一切正常。然后,每次对其的后续调用都会导致错误-NullReferenceExceptionReadDateTimeAt函数中引发cell.DateCellValue。仅重新启动整个应用程序会有帮助。

为什么会这样?我是否没有正确释放一些资源(我想可以,但是我认为我应该释放的唯一一个资源是FileStream,该资源打包在using中-我还检查了ResourceManager和文件通话之间无法访问)?

我真的无法确定哪个引用是null它不是Cell对象本身-我可以通过调试器访问其属性。整个工作簿似乎也已正确加载(再次通过调试器对其进行访问)。

如果相关,则无法读取的单元格保留对另一张工作表上单元格的引用,其类型设置为“日期”。

解决方法

在第一次调用方法ImportFile()时,一切正常。然后, 随后的每次调用都会导致错误- NullReferenceException由ReadDateTimeAt函数引发 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));

        }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...