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

使用OpenXmlPowerTools修改Word内容后合并报错:文件包含损坏数据

解决OpenXmlPowerTools合并Word模板时的“文件包含损坏数据”错误

问题背景

原本使用OpenXmlPowerTools合并Word模板的代码运行正常:

var sources = new List<Source>();
foreach (var fileName in fileName_List)
{
     using (FileStream stream = System.IO.File.Open(filename, FileMode.Open))
     {
        var memoryStream= new MemoryStream();
        stream.CopyTo(memoryStream);
        sources.Add(new Source(new WmlDocument("", memoryStream), true));
     }
}
var mergedDoc = DocumentBuilder.BuildDocument(sources);
mergedDoc.SaveAs(resultFile);

但为了在合并前修改每个文件的占位符,调整代码后,调用mergedDoc.SaveAs(resultFile)时抛出错误:File contains corrupted data

调整后的代码:

foreach (var filename in fileName_List)
{
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(filename, true))
    using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
    {
        var docText = sr.ReadToEnd();
        docText = docText.Replace("PlaceHolder", "NewValue");
        using (var memoryStream= GenerateStreamFromString(docText))
        {
            sources.Add(new Source(new WmlDocument("", memoryStream), true));
        }
    }
}
public static MemoryStream GenerateStreamFromString(string s)
{
    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}

尝试改用ASCII编码将文本转为字节数组,错误依旧:

var docText = sr.ReadToEnd();
docText = docText.Replace("PlaceHolder", "NewValue");
byte[] bytes = Encoding.ASCII.GetBytes(docText);
sources.Add(new Source(new WmlDocument("", bytes), true));

问题原因

直接通过StreamReader读取MainDocumentPart的流并做文本替换,会破坏Word文档的OpenXML结构:

  • Word的MainDocumentPart是XML格式,直接读写文本可能破坏XML的编码声明、命名空间或结构完整性
  • 使用StreamWriter或ASCII编码写入时,会改变原文档的编码格式,导致生成的文档不符合OpenXML规范,最终被判定为损坏数据

正确解决方案

必须通过OpenXML API操作文档内容,而非直接读写文本流。修改占位符的正确代码如下:

var sources = new List<Source>();
foreach (var filename in fileName_List)
{
    // 复制原文件到内存流,避免修改原文件
    using (var originalStream = new MemoryStream())
    {
        using (var fileStream = File.OpenRead(filename))
        {
            fileStream.CopyTo(originalStream);
        }
        originalStream.Position = 0;

        // 打开内存中的Word文档进行修改
        using (var wordDoc = WordprocessingDocument.Open(originalStream, true))
        {
            var mainPart = wordDoc.MainDocumentPart;
            var body = mainPart.Document.Body;

            // 遍历所有文本节点替换占位符
            foreach (var text in body.Descendants<Text>())
            {
                if (text.Text.Contains("PlaceHolder"))
                {
                    text.Text = text.Text.Replace("PlaceHolder", "NewValue");
                }
            }

            // 保存修改并重置流位置
            wordDoc.Save();
            originalStream.Position = 0;

            // 将修改后的流转为WmlDocument加入合并列表
            sources.Add(new Source(new WmlDocument("", originalStream), true));
        }
    }
}

var mergedDoc = DocumentBuilder.BuildDocument(sources);
mergedDoc.SaveAs(resultFile);

补充说明

  • 若占位符位于段落、表格等复杂结构中,可根据实际场景调整遍历逻辑,比如定位特定的Paragraph或Run节点
  • 直接操作XML文本极易引入编码、格式错误,始终优先使用OpenXML SDK提供的API修改文档内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:20:29