【问题标题】:Specific order of xmlelements in Excel OpenXml Workbook classExcel OpenXml Workbook 类中 xmlelements 的特定顺序
【发布时间】:2015-06-12 07:39:17
【问题描述】:

我通过 OpenXml 创建 PowerPoint 演示文稿。演示文稿的幻灯片丰富了嵌入的对象。通常嵌入 Excel 文档。除了准备好嵌入的图像和文档外,Excel 还需要在 PowerPoint 中打开文档时向用户显示哪个区域的另一个信息。

可以通过将OleSize 类添加到工作簿部分来将此信息添加到 Excel 工作簿中。请忽略此代码不会检查该片段是否存在,这肯定会导致问题。这只是一个简单的例子。

    var oleSize = new OleSize() {Reference = "A1:H12"};
    var workbook = document.WorkbookPart.Workbook;
    workbook.Append(oleSize);

当刚刚添加到工作簿类的 OpenXmlElements 列表的末尾时,Excel 将显示一个错误消息对话框,指出文件已损坏,无法修复。将此元素直接放在 PivotCache OpenXmlElement 之后确实可以作为一种解决方法。现在我体验到,当 OpenXmlElement 在 OleSize 之前可用时,Excel 也会引发该消息。

我找不到任何有关该特定类的 OpenXmlElements 订单必要性的信息。

非常感谢任何提示。

【问题讨论】:

    标签: c# excel openxml


    【解决方案1】:

    您在答案中列出的顺序是正确的。在您参考的 OpenXML 规范文档中,Workbook 有一个 XSD(第 3936 页),这表明该订单确实是强制性的,因为它被定义为 Sequence

    <xsd:complexType name="CT_Workbook">
        <xsd:sequence>
            <xsd:element name="fileVersion" type="CT_FileVersion" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="fileSharing" type="CT_FileSharing" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="workbookPr" type="CT_WorkbookPr" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="workbookProtection" type="CT_WorkbookProtection" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="bookViews" type="CT_BookViews" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="sheets" type="CT_Sheets" minOccurs="1" maxOccurs="1"/>
            <xsd:element name="functionGroups" type="CT_FunctionGroups" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="externalReferences" type="CT_ExternalReferences" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="definedNames" type="CT_DefinedNames" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="calcPr" type="CT_CalcPr" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="oleSize" type="CT_OleSize" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="customWorkbookViews" type="CT_CustomWorkbookViews" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="pivotCaches" type="CT_PivotCaches" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="smartTagPr" type="CT_SmartTagPr" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="smartTagTypes" type="CT_SmartTagTypes" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="webPublishing" type="CT_WebPublishing" minOccurs="4129 0" maxOccurs="1"/>
            <xsd:element name="fileRecoveryPr" type="CT_FileRecoveryPr" minOccurs="0" maxOccurs="unbounded"/>
            <xsd:element name="webPublishObjects" type="CT_WebPublishObjects" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
        </xsd:sequence>
        <xsd:attribute name="conformance" type="s:ST_ConformanceClass"/>
    </xsd:complexType>
    

    如果您有兴趣,我有一个答案 here,它显示了一种将项目添加到文件中正确位置的方法。

    【讨论】:

    • 正是我想要的。谢谢!实际上我不明白为什么需要强制命令,但我他们有充分的理由:-)
    • 实际上在您的实现中存在一个小故障。查找前一个元素时,for each 需要一个 break 语句:OpenXmlElement preceedingElement = null;foreach (var item in worksheetPart.Worksheet.ChildElements.Reverse()){if (elements.Contains(item.GetType())){preceedingElement = item;break;} } 跨度>
    • 感谢@HolgerLeichsenring - 我已经修复了另一个问题的代码示例,因为您说得非常对。我也觉得顺序很重要,但也许它可以在阅读时带来一些优化?
    【解决方案2】:

    在深入研究 OpenXml 规范第 4 版后,我发现了以下信息:

    sml_CT_Workbook =
         4261 attribute conformance { s_ST_ConformanceClass }?,
         4262 element fileVersion { sml_CT_FileVersion }?,
         4263 element fileSharing { sml_CT_FileSharing }?,
         4264 element workbookPr { sml_CT_WorkbookPr }?,
         4265 element workbookProtection { sml_CT_WorkbookProtection }?,
         4266 element bookViews { sml_CT_BookViews }?,
         4267 element sheets { sml_CT_Sheets },
         4268 element functionGroups { sml_CT_FunctionGroups }?,
         4269 element externalReferences { sml_CT_ExternalReferences }?,
         4270 element definedNames { sml_CT_DefinedNames }?,
         4271 element calcPr { sml_CT_CalcPr }?,
         4272 element oleSize { sml_CT_OleSize }?,
         4273 element customWorkbookViews { sml_CT_CustomWorkbookViews }?,
         4274 element pivotCaches { sml_CT_PivotCaches }?,
         4275 element smartTagPr { sml_CT_SmartTagPr }?,
         4276 element smartTagTypes { sml_CT_SmartTagTypes }?,
         4277 element webPublishing { sml_CT_WebPublishing }?,
         4278 element fileRecoveryPr { sml_CT_FileRecoveryPr }*,
         4279 element webPublishObjects { sml_CT_WebPublishObjects }?,
         4280 element extLst { sml_CT_ExtensionList }?
    

    没有信息表明这是保证订单还是预期订单,但只进行了一些测试,它看起来很有希望(我检查了该订单的测试工作簿之一的工作簿 openxml 片段)

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <x:workbook xmlns:x15ac="http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main" mc:Ignorable="x15" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
        <x:fileVersion appName="xl" lastEdited="6" lowestEdited="5" rupBuild="14420" />
        <x:workbookPr defaultThemeVersion="124226" />
        <mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
            <mc:Choice Requires="x15">
                <x15ac:absPath xmlns:x15ac="http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac" url="{path}" />
            </mc:Choice>
        </mc:AlternateContent>
        <x:bookViews>
            <x:workbookView xWindow="240" yWindow="90" windowWidth="23580"  windowHeight="10110" />
        </x:bookViews>
        <x:sheets>
            <x:sheet name="PRINT" sheetId="1" r:id="rId1" />
            <x:sheet name="PRINT2" sheetId="4" r:id="rId2" />
            <x:sheet name="Data" sheetId="5" state="veryHidden" r:id="rId3" />
            <x:sheet name="PRINT3" sheetId="6" r:id="rId4" />
        </x:sheets>
        <x:definedNames>
            <x:definedName name="Measures">Books!$C$4</x:definedName>
            <x:definedName name="_xlnm.Print_Area" localSheetId="0">PRINT!$A$1:$G$25</x:definedName>
        </x:definedNames>
        <x:calcPr calcId="152511" calcMode="manual" calcOnSave="0" />
        <x:oleSize ref="A1:G25" />
    </x:workbook>
    

    所以我会尝试最好的猜测。

    【讨论】:

      猜你喜欢
      • 2022-01-23
      • 1970-01-01
      • 2013-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多