用另一个 docx 中的标题图像替换 docx 中的标题

问题描述 投票:0回答:2

我目前正在尝试用另一个 docx 中的标题图像替换 docx 中的标题,我遵循了 ms 文档中的 example,但它似乎并非旨在将图像从源文档的标题传输到另一个。

这是目标 docx 发生的情况:

Target docx result

我打开目标 docx zip 并与源 docx 进行比较,发现目标 docx 中缺少多个元素,例如 /media 文件夹和图像、header.xml.rels 以及 [Content_types].xml 文件中的一些详细信息。当我手动移动此副本/编辑此文件时,我能够正确看到图像。

所以我的问题是,如何以编程方式传输这些元素?

这是我当前使用的代码:

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

class Program
{
    static void Main(string[] args) 
    {
        string filepathFrom = "path";
        string filepathTo = "path";
        AddHeaderFromTo(filepathFrom, filepathTo);
    }

    public static void AddHeaderFromTo(string filepathFrom, string filepathTo)
    {
        // Replace header in target document with header of source document.
        using (WordprocessingDocument 
            wdDoc = WordprocessingDocument.Open(filepathTo, true))
        {
            MainDocumentPart mainPart = wdDoc.MainDocumentPart;
            
            // Delete the existing header part.
            mainPart.DeleteParts(mainPart.HeaderParts);

            // Create a new header part.
            HeaderPart headerPart = mainPart.AddNewPart<HeaderPart>();
            
            
            // Get Id of the headerPart.
            string rId = mainPart.GetIdOfPart(headerPart);
            
            // Feed target headerPart with source headerPart.
            using (WordprocessingDocument wdDocSource = WordprocessingDocument.Open(filepathFrom, true))
            {
                HeaderPart firstHeader = wdDocSource.MainDocumentPart.HeaderParts.FirstOrDefault();
            
                wdDocSource.MainDocumentPart.HeaderParts.FirstOrDefault();

                if (firstHeader != null)
                {
                    headerPart.FeedData(firstHeader.GetStream());
                }
            }

            // Get SectionProperties and Replace HeaderReference with new Id.
            IEnumerable<SectionProperties> sectPrs = mainPart.Document.Body.Elements<SectionProperties>();
            foreach (var sectPr in sectPrs)
            {
                // Delete existing references to headers.
                sectPr.RemoveAllChildren<HeaderReference>();

                //Adding Title Page property
                sectPr.PrependChild(new TitlePage());

                // Create the new header reference node.
                sectPr.AppendChild(new HeaderReference() { Id = rId, Type = HeaderFooterValues.First });
            }    
        }
    }
}

c# ms-word openxml openxml-sdk
2个回答
1
投票

我已经尝试了很多事情,并在标题中的图像上浪费了很多时间,对我来说,处理标题中的图像是从标题中已有图像的模板文档开始,用新的复制该文件命名,然后根据需要进行编辑。

我认为库的一部分 open xml 没有制作,自 2021 年 10 月以来在他们的官方 github 中打开了一个相关的问题 https://github.com/dotnet/Open-XML-SDK/issues/1040


0
投票

我正在重新审视这个问题,并在这个答案中找到了对我有用的东西:

https://stackoverflow.com/a/38745157/11213291

这个名为 OpenXmlPowerTools 的库有一个函数 (DocumentBuilder),可用于将页眉和页脚从文档 (Source2.docx) 传输到另一个文档 (Source1.docx)。这是代码:

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Validation;
using OpenXmlPowerTools;

namespace DocumentBuilderExample
{
    class DocumentBuilderExample
    {
        static void Main(string[] args)
        {
            var n = DateTime.Now;
            var tempDi = new DirectoryInfo(string.Format("ExampleOutput-{0:00}-{1:00}-{2:00}-{3:00}{4:00}{5:00}", n.Year - 2000, n.Month, n.Day, n.Hour, n.Minute, n.Second));
            tempDi.Create();

            string source1 = "../../Source1.docx";
            string source2 = "../../Source2.docx";
            List<Source> sources = null;

            // Create new document from 10 paragraphs starting at paragraph 5 of Source1.docx
            sources = new List<Source>()
            {
                new Source(new WmlDocument(source1), false),
                new Source(new WmlDocument(source2), true),
            };
            DocumentBuilder.BuildDocument(sources, Path.Combine(tempDi.FullName, "Out1.docx"));

        }
    }
}

甚至还有一个视频解释了一切:https://www.youtube.com/watch?v=VCShcq8qOg0

© www.soinside.com 2019 - 2024. All rights reserved.