生成的docx文件已损坏

时间:2016-07-18 10:05:27

标签: ruby-on-rails ruby xml openxml docx

我有一个传统的Rails应用程序,可以生成docx文件。它只使用xml模板,而不是任何宝石。模板是使用ERB语法编写的。

问题是生成的文件被标记为"已损坏"通过MS Office Word,虽然Linux上的LibreOffice打开它完美无瑕。但是,恢复MS Office Word后似乎打开文件而没有任何内容丢失。

我在pastebin上粘贴了完整的XML模板。

调试时我发现,没有块,从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 %>

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

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

更新 我试图纠正,由马丁P.建议,但没有运气。这是我生成的文件和恢复版本之间的差异(在右侧恢复)

Diff screenshot

3 个答案:

答案 0 :(得分:1)

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

(1)wp:inline需要包含wp:docPridname属性的descr元素。

<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 %>

如果你看看你的差异,你可能会看到这些元素被添加。

答案 1 :(得分:0)

MS Office Word替换r:embed的值这一事实表明本文档的关系文件中没有@Id="image_1"的定义。相关关系文件可能是word/_rels/document.xml.rels

答案 2 :(得分:0)

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

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

然而,Martin P.建议的补充也是必要的(我怎么能相信他?),因为没有它们,结果文件仍然会被破坏,但是会有另一条错误消息。

感谢所有想帮助我的人。我希望,这个答案可以帮助将来的某个人。