【.NET Core】【ClosedXML】셀 값 가져오기 1

소개



ClosedXML을 사용하여 Excel에서 값을 가져올 때 값이 실제 값과 다를 때가 있습니다.
나는 그들이 언제 일어날 것인지 알고 싶습니다.
  • GitHub - ClosedXML/ClosedXML: ClosedXML is a .NET library for reading, manipulating and writing Excel 2007+ (.xlsx, .xlsm) files. It aims to provide an intuitive and user-friendly interface to dealing with the underlying OpenXML API.

  • 환경


  • .NET Core 버전 3.1.402
  • ClosedXML 버전 0.95.3

  • 기본 프로젝트


    ISpreadsheet ValueGetter.vs



    using System.Collections.Generic;
    namespace FileAccesses
    {
        public interface ISpreadsheetValueGetter
        {
            Dictionary<string, string> LoadSample();
        }
    }
    

    스프레드시트 ValueGetter.vs



    using System.Collections.Generic;
    using ClosedXML.Excel;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    
    namespace FileAccesses
    {
        public class SpreadsheetValueGetter: ISpreadsheetValueGetter
        {
            private readonly ILogger<SpreadsheetValueGetter> _logger;
            private readonly string _filePath;
            public SpreadsheetValueGetter(ILogger<SpreadsheetValueGetter> logger,
                IConfiguration config)
            {
                _logger = logger;
                _filePath = config["SampleFilePath"];
            }
            public Dictionary<string, string> LoadSample()
            {
                using(var book = new XLWorkbook(_filePath))
                {
                    var sheet = GetTargetSheet(book);
                    if (sheet == null)
                    {
                        return new Dictionary<string, string>();
                    } 
                    return GetCellValues(sheet);
                }
            }
            private IXLWorksheet? GetTargetSheet(XLWorkbook book)
            {
                // Get Worksheet from Workbook
            }
            private Dictionary<string, string> GetCellValues(IXLWorksheet sheet)
            {
                // Get cell values
            }
        }
    }
    

    명명된 셀로 워크시트 가져오기



    통합 문서에 이름이 지정된 셀 이름으로 워크시트를 얻으려면 이 작업을 수행할 수 있습니다.

    스프레드시트 ValueGetter.vs



    ...
            private IXLWorksheet? GetTargetSheet(XLWorkbook book)
            {
                var result = book.Cell("NameOnBook");
                return result?.Worksheet;
            }
    ...
    

    워크시트에 이름이 있으면 이런 식으로 얻을 수 있습니다.
    (나는 그것이 최선의 방법이 아닐까봐 두렵다)

    스프레드시트 ValueGetter.vs



    ...
            private IXLWorksheet? GetTargetSheet(XLWorkbook book)
            {
                return (book.Worksheets.FirstOrDefault(s =>
                        s.Cell("NameOnSheet") != null));
            }
    ...
    

    셀 값 가져오기



    대부분의 값과 Excel 기능(예: "VLOOKUP", "SUM"등)은 "GetFormattedString"으로 가져올 수 있습니다.

    string cellValue = sheet.Cell(2, 2).GetFormattedString();
    

    또한 "1.00"등과 같은 셀 형식을 얻습니다.

    그러나 일부 값, 수식 또는 함수는 "GetFormattedString"으로 얻은 값과 일치하지 않습니다.

    그래서 나는 값을 얻기 위해 몇 가지 방법을 시도하고 문제를 피하는 방법을 생각합니다.

    스프레드시트 ValueGetter.vs



    ...
            private Dictionary<string, string> GetCellValues(IXLWorksheet sheet)
            {
                var results = new Dictionary<string, string>();
                AddCellValue(results, sheet.Cell(2, 2), sheet, "error");
    
                return results;
            }
            private void AddCellValue(Dictionary<string, string> dictionary,
                IXLCell cell,
                IXLWorksheet sheet, 
                string name)
            {
                dictionary.Add($"{name}_FormattedString", cell.GetFormattedString());
                dictionary.Add($"{name}_CachedValue", cell.CachedValue?.ToString() ?? "");
                dictionary.Add($"{name}_ValueCached", cell.ValueCached ?? "");
                dictionary.Add($"{name}_DataType", cell.DataType.ToString());
                dictionary.Add($"{name}_FormulaAi", cell.FormulaA1);
            }
    ...
    

    수식의 문법적 실수



    실제 값



    =s
    

    엑셀에 표시



    #NAME?
    

    암호



    ...
            private Dictionary<string, string> GetCellValues(IXLWorksheet sheet)
            {
                var results = new Dictionary<string, string>();
                AddCellValue(results, sheet.Cell(2, 2), sheet, "error");        
                return results;
            }
    ...
    

    결과



    {
        "error_FormattedString": "s",
        "error_CachedValue": "s",
        "error_ValueCached": "#NAME?",
        "error_DataType": "Text",
        "error_FormulaAi": "{s}"
    }
    

    밸류캐시



    이 샘플에서는 "ValueCached"를 통해 Excel에 표시된 값만 가져올 수 있습니다.
    가장 중요한 문제는 더 이상 사용되지 않는다는 것입니다.

    그러나 컴파일러는 "ValueCached"대신 "CachedValue"를 사용하도록 제안하지만 이 경우 결과는 동일하지 않습니다.

    적어도 실수를 알고 ""를 셀 값으로 설정하는 경우를 구별하고 싶습니다.

    Excel 함수의 오류 가져오기



    평가 공식을 사용하여 오류를 얻을 수 있습니다.

    ...
                try
                {
                    var calcResult = sheet.Evaluate(cell.FormulaA1);
                    dictionary.Add($"{name}_Evaluate", calcResult?.ToString()?? "null");   
                }
                catch(Exception ex)
                {
                    dictionary.Add($"{name}_Evaluate_Error", ex.Message);
                }
    ...
    

    결과



    {
    ...
        "error_Evaluate_Error": "Identifier expected."
    }
    

    오류



    "IFERROR"함수를 사용하고 잘못된 수식으로 작성된 셀을 첫 번째 인수로 설정하면 더 복잡한 문제가 발생합니다.

    실제 값



    =IFERROR(B2,-1)
    

    엑셀에 표시



    -1
    

    암호



    ...
            private Dictionary<string, string> GetCellValues(IXLWorksheet sheet)
            {
                var results = new Dictionary<string, string>();
    ...
                AddCellValue(results, sheet.Cell(2, 3), sheet, "ifError");        
                return results;
            }
    ...
    

    결과



    {
    ...
        "ifError_FormattedString": "s",
        "ifError_CachedValue": "s",
        "ifError_ValueCached": "-1",
        "ifError_DataType": "Text",
        "ifError_FormulaAi": "IFERROR(B2,-1)"
    }
    

    이 문제는 수식을 평가하여 해결할 수 없습니다.
    결과가 "0"이기 때문입니다.

    셀이 "IFERROR"함수를 사용할 때 모든 참조 셀 수식을 평가해야 합니까?

    좋은 웹페이지 즐겨찾기