3

我正在尝试从 excel 模板中清除行。在此之前的代码通过并基于模板创建工作簿。该代码可以生成没有错误的精细 excel 文件。只有在添加这部分时我才会遇到问题:

Sheet theSheet = workbookPart.Workbook.Descendants<Sheet>()
    .Where(s => s.Name == task).FirstOrDefault();

if (theSheet != null)
{
    WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(theSheet.Id);

    SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();

    var rows = sheetData.Elements<Row>().Where(r => r.RowIndex > 1).ToArray();

    for (int x = 0; x < rows.Count(); x++)
    {
        ((Row)rows[x]).Remove();
    }

    worksheetPart.Worksheet.Save();
}

它成功清除了行。但是,当我在 excel 中打开文件时,我收到以下错误:

Excel 在“excel.xlsx”中发现了不可读的内容。是否要恢复此工作簿的内容?...

单击是提供以下详细信息:

<repairedRecords summary="Following is a list of repairs:">
    <repairedRecord>Repaired Records: Cell information from /xl/worksheets/sheet1c.xml part</repairedRecord>
    <repairedRecord>Repaired Records: Cell information from /xl/worksheets/sheet1d.xml part</repairedRecord>
    <repairedRecord>Repaired Records: Cell information from /xl/worksheets/sheet1b.xml part</repairedRecord>
    <repairedRecord>Repaired Records: Cell information from /xl/worksheets/sheet1a.xml part</repairedRecord>
    <repairedRecord>Repaired Records: Cell information from /xl/worksheets/sheet26.xml part</repairedRecord>
    <repairedRecord>Repaired Records: Cell information from /xl/worksheets/sheet1f.xml part</repairedRecord>
    <repairedRecord>Repaired Records: Cell information from /xl/worksheets/sheet1e.xml part</repairedRecord>
</repairedRecords>

如果我在“Open XML SDK 2.5 Productivity Tool”中打开 Excel 文件并验证它。它提供了更多信息:

Error Node Type: Worksheet
Error Part: /xl/worksheets/sheet1a.xml (this is the only line chat changes and it corresponds to the above errors)
Error Node Path: /x:worksheet[1]
Related Node Type: OpenXmlUnknownElement
Related Part: 
Description: The element has invalid child element 'http://schemas.openxmlformats.org/sheadsheetml/2006/main:row'.

如果我打开此代码正在修改的原始 Excel 文件,则 sheet1a/sheet1b 等不存在。他们来自哪里?有什么我想念的吗?当我所做的只是删除行时,这些工作表如何包含无效的行元素?感谢您的任何建议。

编辑:sheet1a.xml 的精简形式:

    <?xml version="1.0" encoding="utf-8"?>
<x:worksheet xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <x:dimension ref="A1:AK180" />
    <x:sheetViews>
        <x:sheetView workbookViewId="0" />
    </x:sheetViews>
    <x:sheetFormatPr defaultRowHeight="15" />
    <x:cols>
        <x:col min="1" max="1" width="13.85546875" bestFit="1" customWidth="1" />
    </x:cols>
    <x:sheetData>
        <x:row>
            <x:c r="A1" t="inlineStr">
                <x:is>
                    <x:t>TestResultFileId</x:t>
                </x:is>
            </x:c>
            </x:row>
        <x:row r="2">
            <x:c r="A2" t="inlineStr">
                <x:is>
                    <x:t>6F2DFA01-27EE-E211-8250-0025906392BB</x:t>
                </x:is>
            </x:c>
        </x:row>
    </x:sheetData>
    <x:row r="1" spans="1:37">
        <x:c r="A1" t="s">
            <x:v />
        </x:c>
        </x:row>
    <x:conditionalFormatting sqref="A1:AK1048576">
        <x:cfRule type="expression" dxfId="7" priority="1">
            <x:formula />
        </x:cfRule>
    </x:conditionalFormatting>
    <x:pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3" />
</x:worksheet>
4

1 回答 1

4

基于工作表的 XML,这部分:

<x:row r="1" spans="1:37">
    <x:c r="A1" t="s">
        <x:v />
    </x:c>
</x:row>

不应存在​​于 SheetData 元素之外。事实上,似乎有一个重复,因为

<x:row>
    <x:c r="A1" t="inlineStr">
        <x:is>
            <x:t>TestResultFileId</x:t>
        </x:is>
    </x:c>
</x:row>

也存在。请注意,“实际”标题 Row 没有分配 RowIndex,但根据“A1”的 CellReference,此特定行位于第 1 行。

请注意:

var rows = sheetData.Elements<Row>().Where(r => r.RowIndex > 1).ToArray();

可能会忽略没有分配 RowIndex 的任何 Row 对象(虽然我没有测试过......)。这可能发生。Excel 应该已经分配了一个值,但任何第三方软件都不一定要这样做(因为 Open XML 规范声明 RowIndex 是一个可选属性)。

我不知道为什么在 SheetData 之外有一个 Row 对象。检查原始模板 Excel 文件是否没有此“SheetData 对象之外的行对象”案例。如果是这样,那么原始模板文件首先是错误的。

您可能需要首先考虑将第一行存储在单独的变量中的选项。然后清除 SheetData 的所有子元素。然后 Append() 第一行。这可能更容易。您可以像这样消灭孩子(在此处插入糟糕的育儿笑话):

sheetData.RemoveAllChildren();
于 2013-07-26T16:36:32.790 回答