使用C#结合OpenXml合并两个Word文档仅返回首个文档的问题咨询
问题原因
你的代码逻辑框架没有问题,仅输出第一个文档内容的核心原因是:
- 你将返回流的操作放在了
WordprocessingDocument的using块内部,此时OpenXml的修改还没有完全刷入内存流,using块结束时对象释放才会把所有变更写入流 - 部分第三方Word阅读器不支持AltChunk的动态渲染,只有微软Office系列软件能正确识别AltChunk嵌入的文档内容
修正后可运行代码
private static byte[] Merge(byte[] dest, byte[] src) { string altChunkId = "AltChunkId" + DateTime.Now.Ticks.ToString(); var memoryStreamDest = new MemoryStream(); memoryStreamDest.Write(dest, 0, dest.Length); memoryStreamDest.Seek(0, SeekOrigin.Begin); using (WordprocessingDocument doc = WordprocessingDocument.Open(memoryStreamDest, true)) { MainDocumentPart mainPart = doc.MainDocumentPart; Paragraph para = new Paragraph(new Run((new Break() { Type = BreakValues.Page }))); mainPart.Document.Body.InsertAfter(para, mainPart.Document.Body.LastChild); //插入源文件到目标文件 AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart( AlternativeFormatImportPartType.WordprocessingML, altChunkId); using (MemoryStream mem = new MemoryStream()) { mem.Write(src, 0, (int)src.Length); mem.Seek(0, SeekOrigin.Begin); chunk.FeedData(mem); } AltChunk altChunk = new AltChunk(); altChunk.Id = altChunkId; mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Descendants<Paragraph>().Last()); mainPart.Document.Save(); } // 移动到using块外部,等文档对象释放完成后再读取流内容 return memoryStreamDest.ToArray(); }
补充优化建议
- 如果需要兼容所有Word阅读器,可以在插入AltChunk后额外调用代码将AltChunk转换为原生的OpenXml文档元素,消除对Office动态渲染的依赖
- 如果两个文档存在同名样式冲突,合并后会默认采用目标文档的样式定义,需要保留源文档样式的话可以提前将源文档的样式节点复制到目标文档的样式部分
- 合并前可以增加二进制流合法性校验,避免传入损坏的Word文档导致嵌入内容识别失败
内容的提问来源于stack exchange,提问作者Yuno
相关产品推荐
相关产品推荐

