Почему EPPlus выбрасывает нулевое значение в качестве справочного исключения при доступе к книге - PullRequest
0 голосов
/ 26 апреля 2019

Я пишу в C # .NET Core 2.2.Я пытаюсь заменить Excel Interop с EPPlusCore в моем коде для надежности и портативности.У меня есть серия счетов, которые я открываю с помощью EPPlus, но некоторые из них выдают исключение «Null Reference» при доступе к свойству Workbook пакета Excel.

Это происходит только при запуске кода без его отладки.При отладке, если я наведите курсор мыши на элемент 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

Ноесли это точно, как я узнаю, что имена рабочих листов имеют неправильные ссылки без предварительного доступа к книге?

1 Ответ

0 голосов
/ 03 мая 2019

Я нашел решение.Файлы 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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...