16

我正在尝试以编程方式创建 Open Office 电子表格,但由于某种原因,只需压缩包含所有必要文件的文件夹就会使 Open Office 将文件标记为已损坏。

我是怎么做到的?我首先在 Open Office 中创建了一个包含一些值的普通电子表格。保存后,我将扩展名更改为 .zip 并复制该文件夹。然后我使用命令行 zip 压缩第二个文件夹并将文件扩展名更改为 .ods。尝试打开生成的文件时,我从 Open Office 收到错误消息,指出文件已损坏。

Open Office 是否使用特殊的压缩算法?执行“文件 test.ods”将其显示为压缩的 zip,那么 Open Office 在压缩例程中添加了什么以使其工作?

4

5 回答 5

21

文档在这里。这个步骤对我有用:

  1. 将原始文档文件(它是一个普通的 zip 文件)解压缩到某个目录:

    $ mkdir document
    $ cd document
    $ unzip ../document.odt
    
  2. 修改未压缩的数据。

  3. 创建一个新的 odt:

    $ zip -0 -X ../document2.odt mimetype
    $ zip -r ../document2.odt * -x mimetype
    
于 2011-03-28T15:43:37.200 回答
9

OASIS OpenOffice 规范的第 17 节定义了如何打包 OpenDocument 包。

第 17.4 节 MIME 类型流如下所示:

如果使用包的文档的 MIME 类型存在,那么包 应该包含一个名为“mimetype”的流。这个流应该是包的 zip 文件的第一个流,它不能被压缩,它不能在它的头中使用“额外字段”(参见 [ZIP])。

目的是允许通过“幻数”机制来识别打包文件,例如 Unix 的文件/幻数实用程序。如果 ZIP 文件在文件开头包含未压缩的流,并且头部中没有额外数据,则可以在固定位置找到流名称和流内容。更具体地说,人们会发现:

  • 所有 zip 文件的位置 0 处的字符串 'PK'
  • 所有此类包文件的位置 30 处的字符串“mimetype”
  • mimetype 本身位于此类包的第 38 位。
于 2011-02-10T13:19:40.570 回答
6

我尝试过 tokland 的建议,但我发现 LibreOffice 4 需要特定的顺序(仅适用于第一个?):

  1. mimetype(未压缩)
  2. meta.xml
  3. settings.xml
  4. content.xml
  5. Thumbnails/thumbnail.png
  6. Configurations2/images/Bitmaps/
  7. Configurations2/popupmenu/
  8. Configurations2/toolpanel/
  9. Configurations2/statusbar/
  10. Configurations2/progressbar/
  11. Configurations2/toolbar/
  12. Configurations2/menubar/
  13. Configurations2/accelerator/current.xml
  14. Configurations2/floater/
  15. styles.xml
  16. META-INF/manifest.xml

我创建了一个脚本来执行该folder2od.sh

#!/bin/sh

# Convert folder (unzipped OpenDocument file) to OpenDocument file (odt, ods, etc.)
# Usage: ./folder2od.sh "path/to/folder" "file.odt"

cmdfolder=$(cd `dirname "$0"`; pwd -P)
folder=$(cd `dirname "$2"`; pwd -P)
file=$(basename "$2")
absfile="$folder/$file"

cd "$1"
zip -0 -X "$file" "mimetype"

list=$(cat <<'END_HEREDOC'
meta.xml
settings.xml
content.xml
Thumbnails/thumbnail.png
Configurations2/images/Bitmaps/
Configurations2/popupmenu/
Configurations2/toolpanel/
Configurations2/statusbar/
Configurations2/progressbar/
Configurations2/toolbar/
Configurations2/menubar/
Configurations2/accelerator/current.xml
Configurations2/floater/
styles.xml
META-INF/manifest.xml
END_HEREDOC
)

for f in $list
do
    zip "$absfile" "$f"
done

cd "$cmdfolder"

我在这里找到了一些有趣的信息:http: //www.jejik.com/articles/2010/03/how_to_correctly_create_odf_documents_using_zip/

于 2013-04-27T23:43:56.653 回答
1

即使这是旧的,也是在 2021 年,操作打开的文档和以前一样容易,如果它是使用 microsoft office、office 365、google docs、libreoffice 或 openoffice 生成的:

  1. 复印你的文件

  2. 将复制文档的扩展名重命名为 .zip(因为每个打开的文档都是一个 zip 文件!)

  3. 使用文档名称创建一个文件夹,不带扩展名

  4. 将步骤 2) 中重命名的文档(zip 文件)复制到此文件夹中

  5. 提取此文件夹中的(文档)zip文件

  6. 删除压缩文件!

  7. ...根据需要更改 xml 数据和二进制对象

  8. 将所有文件标记为该文件夹中的文件夹并将它们添加到新的 zip 文件中(仅使用标准 zip 压缩!)

  9. 现在你应该在你之前在 setp 3 中创建的文件夹中有一个新的 zip 文件)

  10. 将此新 zip 文件的扩展名重命名为 o.odt 或 .odp 或任何原始打开文档类型,您在步骤 2 中重命名)

  11. 尝试在任何能够处理打开文档文件的办公软件中打开这个新的、重命名的打开文档

请记住:

a) 每个打开的文档都是一个(压缩的)zip 文件

b) zip 文件包含代表本文档结构和文本内容的 xml 文件,还包含带有二进制数据(对象)的 supfolders,例如媒体数据(图像、音频或视频数据和 ole 对象),其中一些可能在 xml 文件中显示为 base64 编码。

c) 您可以将每个打开的文档的内容提取到一个新文件夹中

d) 永远不要压缩放置所有数据的文件夹,以创建新的 zip 文件/打开文档文件。仅压缩此文件夹的内容,以创建有效的打开文档并将如此创建的 zip 文件重命名为他使用的原始源文件的打开文档扩展名!

资料来源:https ://en.wikipedia.org/wiki/OpenDocument_technical_specification

可用于操作打开的文档文件的工具:

a) https://7-zip.de/download.html(解压和压缩)

b) https://notepad-plus-plus.org/downloads/(编辑 XML 内容)

c)https://www.bulkrenameutility.co.uk/(如果您不知道windows、linux下的命令,可以批量重命名文件和文件夹...参见:https ://unix.stackexchange.com/questions/181141 /rename-multiple-files-with-mv-to-change-the-extension )

于 2021-05-13T10:01:59.113 回答
0

shell 脚本也对我有用 :) 在解压缩 odt 文件后,我在压缩备份时遇到了问题。猜猜清单部分是缺少的。

然而,上面的 shell 脚本没有处理内联图片/图形,所以我做了一些对我有用的小调整(另外,脚本有一个错误,即 END_HEREDOC 不在专用行上):

#!/bin/sh

# Convert folder (unzipped OpenDocument file) to OpenDocument file (odt, ods, etc.)
# Usage: ./folder2od.sh "path/to/folder" "file.odt"

cmdfolder=$(cd `dirname "$0"`; pwd -P)
folder=$(cd `dirname "$2"`; pwd -P)
file=$(basename "$2")
absfile="$folder/$file"

cd "$1"
zip -0 -X "$file" "mimetype"

list=$(cat <<'END_HEREDOC'
meta.xml
settings.xml
content.xml
Pictures/
Thumbnails/
Configurations2/
styles.xml
manifest.rdf
META-INF/manifest.xml
END_HEREDOC
)

for f in $list
do
    zip -r "$absfile" "$f"
done

cd "$cmdfolder"
于 2014-04-28T19:17:35.293 回答