为什么.NET OpenXML SDK';的SpreadsheetDocument.Open()方法引发NullR

本文关键字:Open 方法 NullR SpreadsheetDocument OpenXML NET SDK 为什么 | 更新日期: 2023-09-27 18:27:06

我完全被这件事难住了,整个上午在谷歌上都找不到任何东西。

我有一个看起来或多或少像这样的方法:

public void Open(string fileName, bool isEditable)
{
    if(this.Document != null) this.Document.Close();
    this.Document = SpreadSheetDocument.Open(fileName, isEditable);
}

它只比这稍微复杂一点(例如,如果arg为null或ZLS,则使用先前设置的文件名的规定),但与这里的问题无关。

当我运行这段代码时,我在方法的最后一行得到了一个NullReferenceException。根据MSDN文档,此方法应该抛出的唯一异常是ArgumentNullException或OpenXMLPackageException。该文件没有在任何其他应用程序中打开,我已经尝试将其移动到不同的位置,以防出现权限问题,而且它绝对是一个格式良好的.xslx文件,创建并保存在Excel中。

如果它不明显,这是我编写的助手类的一部分,目的是减少打开电子表格和提取数据时的工作量,主要用于导入Access这样简单的情况这Document"是SpreadsheetDocument类型的属性。以下是异常详细信息:

System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=DocumentFormat.OpenXml
StackTrace:
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.get_FileOpenAccess()
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.SavePartContents()
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Dispose(Boolean disposing)
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Dispose()
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Close()
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Load()
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.OpenCore(String path, Boolean readWriteMode)
   at DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open(String path, Boolean isEditable, OpenSettings openSettings)
   at DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open(String path, Boolean isEditable)
   at CorbLib.OXML.Spreadsheets.XLDoc.Open(String fileName, Boolean isEditable) in C:'[path removed]'XLDoc.cs:line 37
   at CorbLib.OXML.Spreadsheets.XLDoc.GetCell(String sheetName, String cellRef) in C:'[path removed]'XLDoc.cs:line 48
   at CorbLib.OXML.Spreadsheets.XLDoc.GetCellsFromRange(String range, Boolean leaveOpen) in C:'[path removed]'XLDoc.cs:line 139
   at CorbLib.OXML.Spreadsheets.XLDoc.GetCellValues(String range, Boolean leaveOpen) in C:'[path removed]'XLDoc.cs:line 116
   at ConsoleApplication1.Program.Main(String[] args) in C:'[path removed]'Program.cs:line 14
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
InnerException: 

任何援助都会非常有帮助。

编辑:根据已接受答案中的注释,我已将上述方法修改如下。。。

public void Open(string fileName, bool isEditable)
{
    /*unimportant bits*/
    var fs = new FileStream(this.FullPath, FileMode.Open, FileAccess.Read);
    this.Document = SpreadsheetDocument.Open(fs, this.IsEditable);
}

现在效果很好。

为什么.NET OpenXML SDK';的SpreadsheetDocument.Open()方法引发NullR

我认为这是DocumentFormat.OpenXml库中的一个错误。在Load函数中有一个catch块,它首先调用Close方法:

try
{
    // Some stuff
}
catch (OpenXMLPackageException)
{
    Close();
    throw;
}

当捕捉到异常时,会调用Close()方法,但如果在之前发生,则会完全初始化,Close方法本身会抛出NullReferenceException,从而隐藏原始异常。

您可能会在Visual Studio的输出窗口中看到问题所在。您应该能够在使用Visual Studio进行调试时捕捉到正确的错误附加(至少您将阅读原始异常消息)。