Ячейка формулы извлекает значение таблицы стилей xml, когда ячейка имеет несколько стилей в EPPlus - PullRequest
0 голосов
/ 15 марта 2019

Я не знаю, сталкивался ли кто-нибудь с этой проблемой раньше. По сути, я читаю значение ячейки формулы. Исходная ячейка имеет два стиля шрифта Calibri и Arial. В таких случаях он каким-то образом пытается сохранить стиль, а значение читается как таблица стилей XML (пример ниже).

В моем случае мне наплевать на стиль. Есть ли способ игнорировать стиль при чтении ячеек?

<r xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <t>XS-1000</t>
</r>
<r xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <rPr>
        <b />
        <i />
        <sz val="18" />
        <rFont val="Arial" />
        <family val="2" />
    </rPr>
    <t>i</t>
</r>
<r xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <rPr>
        <b />
        <sz val="18" />
        <rFont val="Arial" />
        <family val="2" />
    </rPr>
    <t>™ ANALYZERS</t>
</r>

Вот код для чтения строк Excel:

private List<string> ReadRow(ExcelRange cells, int row, int startColumn, int numberOfCols, bool skipEmptyCol = false)
{
    if (row < 1)
        throw new ArgumentException("invalid start line.", "startLine");

    if (startColumn < 1)
        throw new ArgumentException("invalid start column.", "startColumn");

    if (numberOfCols < 1)
        throw new ArgumentException("invalid number of columns.", "numberOfCols");

    var rowData = new List<string>();
    int currentColumn = startColumn;

    while ((startColumn + numberOfCols > currentColumn))
    {
        var cellValueString = "";
        var cellValue = (cells[row, currentColumn].Value ?? "").ToString();

        if (string.IsNullOrWhiteSpace(cellValueString) && !skipEmptyCol) { break; }

        rowData.Add(cellValueString);
        currentColumn++;
    }

    return rowData;
}

Это формула в ячейке, значение которой читается из:

=SUBSTITUTE(SUBSTITUTE('XEC PDF'!A3, "HEMATOLOGY CONTROL FOR ","")," and ","/") 

1 Ответ

0 голосов
/ 26 марта 2019

Таким образом, проблема заключалась в том, что в ячейке было 2 разных стиля шрифта («TM» был надстрочным, все остальное было нормальным). При выполнении метода ExcelWorkbook.Calculate () он преобразует значение ячейки с помощью тегов xml для сохранения стилей. В моем случае я извлекаю значения с помощью формул, и эти надстрочные индексы требуются только для отображения в отчетах. Поэтому мое решение состоит в том, чтобы очистить эти richText, вернуть нормальные значения и запустить Calculate (). Кроме того, я столкнулся с другой проблемой при чтении из объединенной ячейки, она просто взрывается. Поэтому я добавил решение к этому ниже.

** Вы также можете извлекать значения из текста в формате XML, добавляя теги и анализируя, чтобы получить значения (которые вы можете добавить в свои общедоступные свойства элементов данных). Я разместил решение в нижней части.

        internal ImportFormulaSheetResponse ImportFormulaSheet(string formulaFilePath)
        {
            var impFormRes = new ImportFormulaSheetResponse();

            try
            {
                using (var workbookFormula = new ExcelPackage(new FileInfo(formulaFilePath)))
                using (var workbookOriginal = CreateExcelPackage(this.Stream))
                {
                    List<string> sheetNames = new List<string>();
                    List<string> formulaSheets = new List<string>();

                    foreach (var worksheet in workbookOriginal.Workbook.Worksheets)
                    {
                        List<int> parameterCols = new List<int> { 1, 2, 17 };

                        int rowCount = worksheet.Dimension.End.Row;
                        foreach(int col in parameterCols)
                        {
                            for (int row = 14; row < rowCount; row++)
                            {
                                if (worksheet.Cells[row, col].IsRichText)
                                {
                                    //removing super/sub script formatting from RichText Cell property
                                    var celVal = worksheet.Cells[row, col].Value;
                                    if (worksheet.Cells[row, col].Merge == true)
                                    {
                                        string range = GetMergedRange(worksheet, row, col);
                                        worksheet.Cells[range].Merge = false;
                                    }
                                    worksheet.Cells[row, col].Clear();
                                    worksheet.Cells[row, col].Value = celVal;
                                }
                            }
                        }
                    }

                    foreach (var worksheet in workbookFormula.Workbook.Worksheets)
                    {
                        if (worksheet.Name.Contains("Formula"))
                        {
                            workbookOriginal.Workbook.Worksheets.Add(worksheet.Name, worksheet);
                            formulaSheets.Add(worksheet.Name);
                        }
                        else
                        {
                            sheetNames.Add(worksheet.Name);
                        }
                    }

                    //Calculate so the formula references have updated values
                    workbookOriginal.Workbook.Calculate();
                    workbookOriginal.Save();
                    this.Stream = workbookOriginal.Stream;

                    return impFormRes;
                }
            }
            catch (Exception ex)
            {
                impFormRes.Notifications.AddError(ex.Source, ex.Message);
                return impFormRes;
            }
        }

        /// <summary>
        /// Find the merged range a specific cell it belongs to
        /// </summary>
        /// <returns>merged cell string</returns>
        internal string GetMergedRange(ExcelWorksheet worksheet, int row, int col)
        {
            ExcelWorksheet.MergeCellsCollection mergedCells = worksheet.MergedCells;
            foreach (var merged in mergedCells)
            {
                ExcelRange range = worksheet.Cells[merged];
                ExcelCellAddress cell = new ExcelCellAddress(row, col);
                if (range.Start.Row <= cell.Row && range.Start.Column <= cell.Column)
                {
                    if (range.End.Row >= cell.Row && range.End.Column >= cell.Column)
                    {
                        return merged.ToString();
                    }
                }
            }
            return "";
        }

/////////////////////////////////////////////////////////////////

    public class ExcelImport
    {
        //workbook.Calculate() generates xml style tag around a cell with multiple styling
        //so add root tag to make it a proper xml document, parse and read root value
        if (rowData[2].Contains("<"))
        {
            string myXML = "<root>" + rowData[2] + "</root>";
            XDocument doc = XDocument.Parse(myXML);
            InstrumentName = doc.Root.Value;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...