【问题标题】:Specify header for SectionProperty in OpenXml在 OpenXml 中指定 SectionProperty 的标头
【发布时间】:2021-10-22 16:01:00
【问题描述】:

我正在通过附加新的部分/段落/其他内容来更改现有的 docx 文件。 (基本上,现有文件是空的,除了有一个空段落和一个页眉/页脚。想法是将其用作模板。)

我正在添加这样的新内容:

using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(sourceDocx, true))
        {
            var headerPart = wordprocessingDocument.MainDocumentPart.AddNewPart<HeaderPart>();
            headerPart.Header = new Header(new Paragraph(new Run(new Text("Hallo"))));
            string headerId = wordprocessingDocument.MainDocumentPart.GetIdOfPart(headerPart);

            Body body = wordprocessingDocument.MainDocumentPart.Document.Body;
            RemoveLastEmptyParagraph(body);

            //var sectionProperties = body.Elements<SectionProperties>();
            //foreach (var section in sectionProperties)
            //{
            //  section.RemoveAllChildren<HeaderReference>();
            //}

            var firstsection = body.GetFirstChild<SectionProperties>();
            var defaultPageSize = firstsection.Descendants<PageSize>().FirstOrDefault();
            var pageMargins1 = firstsection.Descendants<PageMargin>().FirstOrDefault();

            body.AppendChild(new Paragraph(new Run(new Text("A4"))));
            body.AppendChild(new Paragraph(new ParagraphProperties(CreateSectionBreak(null, defaultPageSize, pageMargins1))));

            body.AppendChild(new Paragraph(new Run(new Text("A3"))));
            body.AppendChild(new Paragraph(new ParagraphProperties(CreateSectionBreakA3(headerId))));

            body.AppendChild(new Paragraph(new Run(new Text("A4"))));

        }
    private static void RemoveLastEmptyParagraph(Body body)
    {
        Paragraph lastParagraph = null;
        foreach (var element in body.ChildElements)
        {
            if (element is Paragraph paragraph)
            {
                lastParagraph = paragraph;
            }
        }

        lastParagraph?.Remove();
    }

    private SectionProperties CreateSectionBreak(string headerId, PageSize pageSize, PageMargin margins)
    {
        var section = new SectionProperties();

        if (headerId != null)
        {
            section.AddChild(new HeaderReference() { Id = headerId, Type = HeaderFooterValues.Default });
        }

        section.AddChild(new SectionType { Val = SectionMarkValues.NextPage });
        section.AddChild((PageSize)pageSize.Clone());
        section.AddChild((PageMargin)margins.Clone());

        return section;
    }

    private SectionProperties CreateSectionBreakA3(string headerId)
    {
        if (headerId == null) throw new ArgumentNullException(nameof(headerId));

        var pageSize = new PageSize();
        pageSize.Width = (UInt32)(42.0 * 566.92556267362);
        pageSize.Height = (UInt32)(29.7 * 566.92556267362);
        pageSize.Orient = new EnumValue<PageOrientationValues>(PageOrientationValues.Landscape);

        var margin = new PageMargin();
        margin.Top = (Int32)(1.0 * 566.92556267362);
        margin.Left = (Int32)(1.0 * 566.92556267362);
        margin.Right = (Int32)(1.0 * 566.92556267362);
        margin.Bottom = (Int32)(1.0 * 566.92556267362);
        margin.Header = (Int32)(1.0 * 566.92556267362);
        margin.Footer = (Int32)(1.0 * 566.92556267362);

        return CreateSectionBreak(headerId, pageSize, margin);
    }

但是,新的/更改的标题永远不会出现在第二部分中。使用 ProductivityTool 查看 docx 文件时,我可以看到标题引用是 SectionProperty 的一部分 - 但它根本没有以 word 显示。 Word 正在为文档中的所有 3 个部分使用预先存在的标题。

在设置新的 HeaderReference 实例之前,我已经尝试从文档中删除所有实例(注释掉的代码),但这并没有帮助:在这种情况下,Word 根本不会显示任何标题。所以似乎我以某种错误的方式添加了“新”。不幸的是,每个处理标题的示例都在处理只有一个标题的文档。我找不到一个处理仅在特定部分中使用的标题。

知道如何正确设置 SectionProperty 的 HeaderReference 吗?

【问题讨论】:

    标签: c# openxml docx openxml-sdk sections


    【解决方案1】:

    所以,基本上,问题在于一个 SectionProperties 实例,它作为第一个子元素直接放置在 body 元素的下方。只要这是文档的一部分,所有其他元素都会被忽略。需要像这样删除这个实例(例如:在调用 RemoveLastEmptyParagraph() 之后):

                var sectionProperties = body.Elements<SectionProperties>().Last(); 
                body.RemoveChild(sectionProperties);
    

    一旦删除,添加的标题就会以文字显示。如果想要在文档末尾保留“默认”标题(一旦删除 SectionProperties 就会消失),可以简单地将删除的 SectionProperties 添加到正文的末尾作为最后一个子项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-02
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 2014-04-27
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      相关资源
      最近更新 更多