生成的 docx 文件已损坏

Generated docx file is corrupted

我有一个遗留的 Rails 应用程序,可以生成 docx 文件。它仅使用 xml 模板,而不是任何 gem。模板是使用 ERB 语法编写的。

问题是生成的文件被 MS Office Word 标记为 "corrupted",尽管 Linux 上的 LibreOffice 可以完美打开它。但是,在恢复 MS Office Word 后,似乎也可以打开文件而没有任何内容丢失。

我将完整的 XML 模板粘贴到 pastebin

在调试时我发现,没有块,从 602 行开始,一切正常。所以我不明白 XML 的那个特定部分有什么问题。为了方便起见,我会把它贴在这里

<% [task[:design_front], task[:design_back]].compact.each do |img_data| %>

            <w:r>
              <w:rPr>
                <w:rFonts w:ascii="Arial" w:eastAsia="Times New Roman" w:hAnsi="Arial" w:cs="Arial" />
                <w:noProof />
                <w:sz w:val="18" />
                <w:szCs w:val="18" />
                <w:lang w:eastAsia="ru-RU" />
              </w:rPr>
              <w:drawing>
                <wp:inline distT="0" distB="0" distL="0" distR="0">
                  <wp:extent cx="<%= img_data[:width] * 7400 %>" cy="<%= img_data[:height] * 7400 %>" />
                  <wp:effectExtent l="0" t="0" r="0" b="0" />
                  <wp:cNvGraphicFramePr>
                    <a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="0" />
                  </wp:cNvGraphicFramePr>
                  <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
                    <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                      <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
                        <pic:nvPicPr>
                          <pic:cNvPicPr>
                            <a:picLocks noChangeAspect="0" noChangeArrowheads="0" />
                          </pic:cNvPicPr>
                        </pic:nvPicPr>
                        <pic:blipFill>
                          <a:blip r:embed="<%= img_data[:id] %>" cstate="print">
                            <a:extLst>
                              <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                                <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0" />
                              </a:ext>
                            </a:extLst>
                          </a:blip>
                        </pic:blipFill>
                        <pic:spPr bwMode="auto">
                          <a:xfrm>
                            <a:off x="0" y="0" />
                            <a:ext cx="<%= img_data[:width] * 7400 %>" cy="<%= img_data[:width] * 7400 %>" />
                          </a:xfrm>
                          <a:prstGeom prst="rect">
                            <a:avLst />
                          </a:prstGeom>
                          <a:noFill />
                          <a:ln>
                            <a:noFill />
                          </a:ln>
                        </pic:spPr>
                      </pic:pic>
                    </a:graphicData>
                  </a:graphic>
                </wp:inline>
              </w:drawing>
            </w:r>

          <% end %>

我尝试将恢复的文件与我的文件进行比较,但没有发现任何重要差异。我现在没有那个差异,但如果需要我可以重现它。

有人能给我指路吗? :) 我做错了什么?

更新 我试图根据 Martin P. 的建议进行更正,但没有成功。这是我生成的文件和恢复版本(在右侧恢复)之间的差异

据我所知,您缺少两个元素和一些属性。

(1) wp:inline 需要有一个包含 idnamedescr 属性的 wp:docPr 元素。

<wp:docPr id="<% id %>" name="<% picture_name %>" descr="<% full_file_path_to_the_picture %>"/>

(2) pic:nvPicPr 元素需要有一个包含相同属性的 pic:cNvPr 元素。

<pic:cNvPr id="<% id %>" name="<% picture_name %>" descr="<% full_file_path_to_the_picture %>"/>

当然你必须插入缺失的变量(<% .. %>)。

这里我用注释标记了插入元素的行:

<% [task[:design_front], task[:design_back]].compact.each do |img_data| %>
            <w:r>
              <w:rPr>
                <w:rFonts w:ascii="Arial" w:eastAsia="Times New Roman" w:hAnsi="Arial" w:cs="Arial" />
                <w:noProof />
                <w:sz w:val="18" />
                <w:szCs w:val="18" />
                <w:lang w:eastAsia="ru-RU" />
              </w:rPr>
              <w:drawing>
                <wp:inline distT="0" distB="0" distL="0" distR="0">
                  <wp:extent cx="<%= img_data[:width] * 7400 %>" cy="<%= img_data[:height] * 7400 %>" />
                  <wp:effectExtent l="0" t="0" r="0" b="0" />
<!-- insert wp:docPr here -->
                  <wp:cNvGraphicFramePr>
                    <a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="0" />
                  </wp:cNvGraphicFramePr>
                  <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
                    <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                      <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
                        <pic:nvPicPr>
                          <pic:cNvPicPr>
<!-- insert pic:cNvPr here -->
                            <a:picLocks noChangeAspect="0" noChangeArrowheads="0" />
                          </pic:cNvPicPr>
                        </pic:nvPicPr>
                        <pic:blipFill>
                          <a:blip r:embed="<%= img_data[:id] %>" cstate="print">
                            <a:extLst>
                              <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                                <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0" />
                              </a:ext>
                            </a:extLst>
                          </a:blip>
                        </pic:blipFill>
                        <pic:spPr bwMode="auto">
                          <a:xfrm>
                            <a:off x="0" y="0" />
                            <a:ext cx="<%= img_data[:width] * 7400 %>" cy="<%= img_data[:width] * 7400 %>" />
                          </a:xfrm>
                          <a:prstGeom prst="rect">
                            <a:avLst />
                          </a:prstGeom>
                          <a:noFill />
                          <a:ln>
                            <a:noFill />
                          </a:ln>
                        </pic:spPr>
                      </pic:pic>
                    </a:graphicData>
                  </a:graphic>
                </wp:inline>
              </w:drawing>
            </w:r>

          <% end %>

如果您查看差异,您可能会看到添加了这些元素。

MS Office Word 替换了 r:embed 的值表明在该文档的关系文件中没有 @Id="image_1" 的定义。相关关系文件大概是word/_rels/document.xml.rels.

经过数小时的调试,找到了答案。

这个谜题的最后一部分是文件 [Content_Types].xml。它包含行 <Default Extension="jpeg" ContentType="image/jpeg" />,但我的图像有 .jpg 扩展名。我将 Extension 属性更改为 jpg 并且错误消失了。

但是,Martin P. 建议的添加也是必要的(顺便说一句,我怎么能相信他?),因为没有它们,生成的文件仍然损坏,但还有另一条错误消息。

感谢所有试图帮助我的人。我希望这个答案对以后的人有所帮助。