我正在C#.NET Core 2.2中进行编码。我正尝试在我的代码中用EPPlusCore替换Excel Interop,以确保可靠性和可移植性。我有使用EPPlus打开的一系列发票,但是其中一些在访问Excel软件包的Workbook属性时会引发“空引用”异常。
这仅在运行代码而不调试时发生。调试时,如果将鼠标悬停在ExcelPackage项上,它将刷新对工作簿的引用,并且我可以运行其余代码。
public object[,] GetExcelDataEpplus(string filePath, int index,
bool sheetByName = false, string name = null, string password = null)
{
var remoteFileInfo = new FileInfo(filePath);
if (!remoteFileInfo.Exists)
{
throw new Exception("File does not exist: " + filePath);
}
var currentPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp-excel");
if (!Directory.Exists(currentPath))
{
Directory.CreateDirectory(currentPath);
}
var localFileInfo = new FileInfo(Path.Combine(currentPath, remoteFileInfo.Name));
if (!localFileInfo.Exists)
{
File.Copy(filePath, localFileInfo.FullName);
}
object[,] values = null;
try
{
if (!File.Exists(localFileInfo.FullName))
{
_logger.LogInformation(DbLog, "Cannot find file : " + localFileInfo.FullName);
return null;
}
else
{
_logger.LogInformation(DbLog, "Found file : " + localFileInfo.FullName);
}
_logger.LogInformation(DbLog, "Initializing EPPlus...");
using (var package = string.IsNullOrEmpty(password)
? new ExcelPackage(localFileInfo)
: new ExcelPackage(localFileInfo, password))
{
_logger.LogInformation(DbLog, "Opening Workbook...");
//todo Error Thrown Here
try
{
package.Workbook.FormulaParserManager.LoadFunctionModule(new ImporterFunctionModule());
}
catch (Exception e)
{
_logger.LogWarning(DbLog, e, $"Could not load workbook : Loading file again...");
try
{
System.Threading.Thread.Sleep(1000);
package.Workbook.FormulaParserManager.LoadFunctionModule(new ImporterFunctionModule());
}
catch (Exception ex)
{
_logger.LogError(DbLog, ex, "Could not load workbook");
throw;
}
}
var workbook = package.Workbook;
_logger.LogInformation(DbLog, $"Calculating formulas...");
workbook.Calculate();
_logger.LogInformation(DbLog, "Finding Worksheet...");
var worksheet = sheetByName ? workbook.Worksheets.FirstOrDefault(x => x.Name == name) : workbook.Worksheets[index];
if (worksheet == null)
{
throw new Exception($"Could not find worksheet : {name}");
}
_logger.LogInformation(DbLog, $"Reading from worksheet : {worksheet.Name}...");
var start = worksheet.Dimension.Start;
var end = worksheet.Dimension.End;
values = worksheet.Cells[start.Row, start.Column, end.Row, end.Column].ToMultiDimensionalArray();
}
}
catch (Exception e)
{
_logger.LogError(DbLog, e, $"GetExcelInvoiceDataEpplus from {filePath} ({localFileInfo.FullName})"); //todo propogate error
}
finally
{
File.Delete(localFileInfo.FullName);
}
var rowCount = values?.GetLength(0) ?? 0;
_logger.LogInformation(DbLog, $"EPPLus found {rowCount} rows in the spreadsheet");
return values;
}
在大多数文件上,这可以正常工作,并且我从指定的工作表选项卡中获得了值的多维数组。但是,在某些文件上,它不起作用,我不知道为什么。
我能够找到的最接近的类似问题是:https://github.com/JanKallman/EPPlus/issues/416
但是,如果这是正确的话,我怎么不先访问工作簿就知道哪些工作表名称具有错误的引用?
答案 0 :(得分:0)
我找到了解决方案。出现问题的excel文件大于平均文件。
解决方案是等待更长的时间。
try
{
package.Workbook.FormulaParserManager.LoadFunctionModule(new ImporterFunctionModule());
}
catch (Exception e)
{
for (var i=1; i < 6; i++)
{
_logger.LogWarning(DbLog, e, $"Could not load workbook : Loading file again (Attempt #{i})...");
try
{
System.Threading.Thread.Sleep(2000);
package.Workbook.FormulaParserManager.LoadFunctionModule(new ImporterFunctionModule());
break;
}
catch (Exception ex)
{
if (i < 5) continue;
_logger.LogError(DbLog, ex, "Could not load workbook after 5 attempts");
throw;
}
}
}