Почему Open XML генерирует ячейки не в порядке? - PullRequest
0 голосов
/ 06 августа 2020

Раньше я сталкивался с проблемами, связанными с записью в документ Excel не по порядку, нарушая документ Excel. Я добавил коллекцию обновлений и сортирую их по индексу столбца на основе ответа, данного в этом вопросе . Я регистрировал записи несколько раз и вижу, что они происходят по порядку ...

Updating cell AG5, column index 32
Updating cell AH5, column index 33
Updating cell AI5, column index 34
Updating cell AK5, column index 36
Updating cell AL5, column index 37
Updating cell AO5, column index 40
Updating cell AP5, column index 41

Однако документ, в котором они заканчиваются, выглядит так ...

<x:row r="5" spans="1:129" x14ac:dyDescent="0.35">
    <x:c r="A5" t="str">
        <x:v>-</x:v>
    </x:c>
    <x:c r="B5" t="str">
        <x:v>1234</x:v>
    </x:c>
    <x:c r="C5" t="str">
        <x:v>-</x:v>
    </x:c>
    <x:c r="D5" t="str">
        <x:v>-</x:v>
    </x:c>
    <x:c r="E5" t="str">
        <x:v>-</x:v>
    </x:c>
    <x:c r="F5" t="str">
        <x:v>-</x:v>
    </x:c>
    <x:c r="G5" s="3" t="str">
        <x:v>-</x:v>
    </x:c>
    <x:c r="H5" t="str">
        <x:v>-</x:v>
    </x:c>
    <x:c r="AJ5" s="2" t="str">
        <x:v>10203</x:v>
    </x:c>
    <x:c r="AK5" s="2" t="str">
        <x:v>10204</x:v>
    </x:c>
    <x:c r="AL5" s="2" t="str">
        <x:v>10205</x:v>
    </x:c>
    <x:c r="AM5" s="36" />
    <x:c r="AN5" s="36" />
    <x:c r="AO5" s="36" t="str">
        <x:v>10206</x:v>
    </x:c>
    <x:c r="AP5" s="36" t="str">
        <x:v>10207</x:v>
    </x:c>
    <x:c r="AQ5" s="36" t="str">
        <x:v>10329</x:v>
    </x:c>
    <x:c r="AR5" s="36" t="str">
        <x:v>10208</x:v>
    </x:c>
    <x:c r="AS5" s="36" t="str">
        <x:v>10209</x:v>
    </x:c>
    <x:c r="AT5" s="36" />
    <x:c r="AU5" s="36" t="str">
        <x:v>10210</x:v>
    </x:c>
    <x:c r="AV5" s="36" t="str">
        <x:v>10211</x:v>
    </x:c>
    <x:c r="AW5" s="36" t="str">
        <x:v>10212</x:v>
    </x:c>
    <x:c r="AX5" s="36" />
    <x:c r="AY5" s="36" />
    <x:c r="AZ5" s="36" />
    <x:c r="BA5" s="36" />
    <x:c r="BB5" s="36" />
    <x:c r="BC5" s="36" />
    <x:c r="BD5" s="36" />
    <x:c r="BE5" s="36" />
    <x:c r="AG5" t="str">
        <x:v>10335</x:v>
    </x:c>
    <x:c r="AH5" t="str">
        <x:v>10201</x:v>
    </x:c>
    <x:c r="AI5" t="str">
        <x:v>10202</x:v>
    </x:c>
</x:row>

Следует отметить, что AG5, AH5 и AI5 перемещаются после BE5. В excel AG-AI пусто и Excel сообщает о проблемах. Если вы откроете это на диске Google, вы получите некоторое представление о том, как Google анализирует файлы Excel, потому что AG5 интерпретируется как BF5 (предположительно потому, что он появляется после BE5 в xml). Удивительно (а может и нет), но у Libre Office нет проблем с правильным отображением данных. Думаю, из Microsoft, Google и Libre Office они единственные, кто удосужился прочитать метку столбца 'r'.

Предположительно, этот фрагмент кода собран из переполнения стека, поэтому я думаю, что могу поделиться Это. Может, что-то кому-то покажется странным. Вот функция для получения ячейки (этот проект фактически работает путем создания копии шаблона):

public static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex)
{
    Row row = null;
    SheetData sheetData = worksheet.GetFirstChild<SheetData>();

    row = sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex == rowIndex);
    if (row == null)
    {
        row = new Row() { RowIndex = rowIndex };
        sheetData.Append(row);
    }

    var cellReference = columnName + rowIndex;  // e.g., A1

    var cell = row.Elements<Cell>()
       .FirstOrDefault(c => c.CellReference.Value == cellReference);
    if (cell == null)
    {
        cell = new Cell() { CellReference = cellReference };
        if (row.ChildElements.Count < GetColumnIndex(columnName))
            row.AppendChild(cell);
        else
            row.InsertAt(cell, GetColumnIndex(columnName));
    }

    return cell;
}

и функция записи в эти ячейки:

public void UpdateCell(WorksheetPart worksheetpart, string text, string cellType, uint rowIndex, string columnName)
{
    try
    {
        if (worksheetpart != null)
        {
            Cell cell = GetCell(worksheetpart.Worksheet,
                                     columnName, rowIndex);

            cell.CellValue = new CellValue(text);
            switch (cellType)
            {
                case "Boolean":
                    cell.DataType =
                        new EnumValue<CellValues>(CellValues.Boolean);
                    break;
                case "String":
                    cell.DataType =
                        new EnumValue<CellValues>(CellValues.String);
                    break;
                case "Number":
                    cell.DataType =
                        new EnumValue<CellValues>(CellValues.Number);
                    break;
                /* Not working...
                                        case "Date":
                                            cell.DataType = 
                                                new EnumValue<CellValues>(CellValues.Date);
                                            break;
                */
                default:
                    cell.DataType =
                        new EnumValue<CellValues>(CellValues.String);
                    break;
            }

            // Save the worksheet.
            worksheetpart.Worksheet.Save();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error in UpdateCell: {1}", ex.Message);
    }

}

Затем с помощью этого серия функций просто:

UpdateCell(worksheetPart, value, "String", row, col);

и по какой-то причине, которая мне еще не ясна, запись в ячейки, которые у меня есть в указанном выше порядке (из журнала), дает мне документ с показанным xml внутренности, которые не могут быть прочитаны в Excel. Если кто-то знаком с проблемой или может предложить предположение, я был бы признателен. Я исчерпал свои догадки, чтобы попытаться. Спасибо!

...