为什么 SuperDoc 只显示最后一张图片:DOCX 内部结构调查

发布: (2026年3月3日 GMT+8 00:20)
8 分钟阅读
原文: Dev.to

I’m sorry, but I don’t have access to the full text of the article at the link you provided, so I can’t translate it for you. If you paste the content you’d like translated here, I’ll be happy to help.

症状

生成的报告包含多个属性图片,排列成网格。

编辑器中预期SuperDoc 中的实际结果
图片 1 → 插槽 1插槽 1 → 最后一个图片
图片 2 → 插槽 2插槽 2 → 最后一个图片
图片 3 → 插槽 3插槽 3 → 最后一个图片

奇怪的是:

  • Microsoft Word → 正确
  • LibreOffice → 正确
  • Google Docs → 正确
  • SuperDoc 编辑器 → 错误

因此 DOCX 本身是有效的;问题出现在特定编辑器上。

环境

工具版本
SuperDoc1.16.x
docx-templates4.15.0
Node20.x

图片是使用 docx-templates 循环插入的,并通过 docxUrl 加载到编辑器中。

首次检查:DOCX 是否损坏?

初始假设:DOCX 生成可能出现问题。

验证步骤

  1. 在 Word 中打开 – ✅
  2. 在 LibreOffice 中打开 – ✅
  3. 转换为 PDF – ✅
  4. 上传至 Google Docs – ✅

在所有地方均正确渲染,编辑器内部外。
结论: 基本排除了 DOCX 损坏的可能。

深度调试方法

由于 DOCX 文件本质上是 ZIP 压缩包,我解压并检查了原始 XML:

word/document.xml
word/_rels/document.xml.rels
word/media/

目标是查看图像在内部是如何被引用的。

发现 1:非标准的关系 ID

通常 DOCX 使用类似 rId1rId2rId3 的关系 ID。
生成的 DOCX 中出现了基于哈希的 ID,例如:

执行的测试 – 将所有关系 ID 改为标准的 rId1rId2 … 并更新引用。

结果: 编辑器行为未改变;所有图像槽仍然显示最后一张图像。
结论: 关系 ID 不是主要原因。

发现 2:媒体文件名

生成的文件名类似:

template_document.xml_img2073076884.jpg

而不是常见的 image1.jpgimage2.jpg

执行的测试 – 将它们重命名为标准格式并更新引用。

结果: 在编辑器中仍然出现问题。

结论: 文件名约定不是导致问题的原因。

发现 3:表格中的图像?

怀疑表格单元格内的图像被扁平化或合并。

检查: 原始 XML 结构——图像已经位于独立的段落中,并未嵌套在复杂的表格绘图结构里。

结果: 未发现结构性问题。

发现 4:Base64 外部引用

将图像转换为 base64 编码的外部引用,以排除编辑器内部的媒体文件解析问题。

结果: 仍然出现故障——所有槽位仍显示最后一张图像。

结论: 问题出在编辑器对绘图节点身份的解释方式,而不是图像的存储或引用方式。

目前最有力的线索(未验证)

在检查每个图像的 drawing XML 时,出现了一个模式:

每个图像的 id="0"

根据 OOXML 规范,此属性在文档内的每个 drawing 对象必须是 唯一的
docx-templates 似乎为所有生成的图像分配了 id="0"

工作假设: SuperDoc 使用 ProseMirror(或类似的引擎)进行渲染。如果解析器依赖 pic:cNvPr/@id 来区分 drawing 节点,重复的 ID 可能导致它将所有图像视为同一个节点,最后加载的图像会“赢得”每个槽位。

注意: 这只是一个假设,并非已确认的修复。下一步是对 docx-templates 的输出进行补丁,注入唯一的顺序 ID,进行干净的服务器重启,并验证结果。之前一次失败的测试是因为使用了旧的编译代码,服务器在重建后没有重新启动。

到目前为止已尝试的操作

尝试内容结果
从表格中提取图像未改变
将关系 ID 重命名为 rId1/rId2未改变
将媒体文件名重命名为 image1.jpg未改变
将图像转换为 base64 外部引用未改变
检查绘图 XML发现所有图像都有重复的 id="0"
修补为唯一 ID尚未完全验证

当前状态

问题仍在调查中。

主要假设: 所有图像中重复的 pic:cNvPr/@id="0" 导致编辑器将它们折叠为单个节点。

后续步骤

  1. 向绘图 XML 注入唯一 ID。
  2. 完整重启服务器。
  3. 进行彻底验证(在 SuperDoc、Word、LibreOffice、Google Docs 中打开 DOCX)。

本次调试会话的经验教训

  1. 如果在 Word 中能正常工作,也可能是错误的
    Word 会默默容忍许多 OOXML 违规。编辑器和转换器更为严格。不要假设 Word 的渲染等同于正确。

  2. 始终内部检查 DOCX
    将 DOCX 当作 ZIP 文件处理。解压后检查 XML,搜索模式,验证结构——调试会快得多。

  3. 渲染引擎表现不同

工具严格程度
Word非常宽容
Google Docs中等
LibreOffice严格
编辑器引擎非常严格

特定编辑器的 bug 往往源于规范的结构假设,而 Word 则悄悄忽略这些假设。

为什么我要记录这个

这个 bug 仍未解决,但调试过程揭示了一个可能的根本原因(重复的 pic:cNvPr/@id)。分享这段经历可能会帮助其他遇到类似编辑器特定渲染怪异的用户,同时也提醒大家在“在 Word 中看起来没问题”之外,对 DOCX 输出进行验证。

如果你也遇到过 DOCX 图像渲染的类似行为,我真的很想听听你的发现。

0 浏览
Back to Blog

相关文章

阅读更多 »

流程幻觉:当文档取代决策

过程的扩展 在成熟的组织中,process 很少被视为敌人。它更像是一种安慰。 - 更多的 documentation 承诺带来清晰。 - 更多的……