OpenXML Spreadsheet删除行会导致excel无法读取的内容错误

时间:2013-07-22 14:54:00

标签: c# excel openxml worksheet

我正在尝试清除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>

1 个答案:

答案 0 :(得分:3)

基于工作表的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>

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

请注意:

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

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

我不知道为什么在SheetData之外有一个Row对象。检查原始模板Excel文件是否没有此“SheetData对象之外的行对象”大小写。如果是,则原始模板文件首先出错。

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

sheetData.RemoveAllChildren();