You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过C#代码将源docx页眉图片迁移至目标docx并替换页眉

问题:代码实现Word页眉图片及关联元素迁移

我尝试将一个docx文件的页眉替换为另一个docx文件中的页眉图片,参照微软官方示例编写代码,但示例无法实现页眉图片从源文档到目标文档的完整迁移。

目标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 });
            }    
        }
    }
}

解决方案

原代码仅复制了页眉的XML内容,未处理页眉依赖的图片、关系文件等关联资源。要完整迁移,需要:

  1. 复制页眉部件的所有子部件(如图片对应的ImagePart)
  2. 重新映射部件之间的关系ID,确保引用正确
  3. 让OpenXml SDK自动维护[Content_types].xml的内容

修正后的代码如下:

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Linq;

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

    public static void ReplaceHeaderWithImage(string sourcePath, string targetPath)
    {
        using (var sourceDoc = WordprocessingDocument.Open(sourcePath, false))
        using (var targetDoc = WordprocessingDocument.Open(targetPath, true))
        {
            var sourceMainPart = sourceDoc.MainDocumentPart;
            var targetMainPart = targetDoc.MainDocumentPart;

            // 删除目标文档原有页眉
            targetMainPart.DeleteParts(targetMainPart.HeaderParts);

            // 获取源文档的第一个页眉
            var sourceHeader = sourceMainPart.HeaderParts.FirstOrDefault();
            if (sourceHeader == null) return;

            // 将源页眉复制到目标文档
            var targetHeader = targetMainPart.AddPart(sourceHeader);

            // 复制页眉关联的所有子部件(如图片)
            foreach (var sourceChildPart in sourceHeader.GetPartsOfType<ImagePart>())
            {
                // 创建新的ImagePart并复制内容
                var targetChildPart = targetHeader.AddPart(sourceChildPart);
                // 重新映射关系ID
                var relId = sourceHeader.GetIdOfPart(sourceChildPart);
                targetHeader.DeleteReferenceRelationship(relId);
                targetHeader.CreateRelationshipToPart(targetChildPart, relId);
            }

            // 更新文档节属性,关联新页眉
            var sectProps = targetMainPart.Document.Body.Elements<SectionProperties>().ToList();
            if (!sectProps.Any())
            {
                // 如果文档没有节属性,创建一个
                var newSectProp = new SectionProperties();
                targetMainPart.Document.Body.Append(newSectProp);
                sectProps.Add(newSectProp);
            }

            foreach (var sectPr in sectProps)
            {
                sectPr.RemoveAllChildren<HeaderReference>();
                sectPr.PrependChild(new TitlePage());
                sectPr.AppendChild(new HeaderReference
                {
                    Id = targetMainPart.GetIdOfPart(targetHeader),
                    Type = HeaderFooterValues.First
                });
            }

            // 保存更改
            targetMainPart.Document.Save();
        }
    }
}

关键说明

  • 使用AddPart方法复制页眉部件,而非FeedData,这样能保留部件的关系结构
  • 遍历并复制页眉下的所有ImagePart,确保图片资源被迁移
  • 重新映射关系ID,避免引用失效
  • 自动处理[Content_types].xml:OpenXml SDK会在添加新部件时自动更新该文件,无需手动编辑

内容的提问来源于stack exchange,提问作者Guilherme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:52:47