Как Open Office сжимает свои файлы?

Я пытаюсь создать электронную таблицу Open Office программно, но по какой-то причине просто сжимать папку со всеми необходимыми файлами делает Open Office флаговым файлом как поврежденным.

Как я дошел до этого? Я начал с создания обычной таблицы в Open Office с некоторыми значениями в ней. После сохранения измените расширение на .zip и сделайте копию папки. Затем я сжимаю вторую папку с помощью командной строки zip и изменяю расширение файла на .ods. При попытке открыть полученный файл я получаю сообщение об ошибке из Open Office, в котором файл поврежден.

Использует ли Open Office специальный алгоритм сжатия? Выполнение "файла test.ods" показывает его как сжатый zip, так что добавляет Open Office во время процедуры сжатия, чтобы заставить его работать?

Ответ 1

Это сработало для меня:

  • Раскройте исходный файл документа (обычный файл zip) в какой-либо каталог:

    $ mkdir document
    $ cd document
    $ unzip ../document.odt
    
  • Измените несжатые данные.

  • Создайте новый odt:

    $ zip -0 -X ../document2.odt mimetype
    $ zip -r ../document2.odt * -x mimetype
    

Ответ 2

Раздел 17 OASIS Спецификация OpenOffice определяет, как пакеты пакета OpenDocument должны быть упакованы.

Раздел 17.4. Тип потока MIME читается следующим образом:

Если тип MIME для документа, который существует использование пакетов, затем пакет ДОЛЖЕН содержать поток, называемый "mimetype". Этот поток ДОЛЖЕНпервый поток пакета zip файл, он НЕ ДОЛЖЕН быть сжатым, и он НЕ ДОЛЖЕН использовать дополнительный поле 'в его заголовке (см. [ZIP])..

Цель состоит в том, чтобы разрешить упакованные файлы быть идентифицированным через магию число "механизмов, таких как Unix's файл/волшебная утилита. Если файл ZIP содержит поток в начале файл, который несжатый, и имеет никаких дополнительных данных в заголовке, затем имя потока и содержимое потока могут можно найти в фиксированных положениях. Больше в частности, можно найти:

  • строка 'PK' в позиции 0 всех zip файлов
  • строка 'mimetype' в позиции 30 всех таких файлов пакета
  • сам миметик в позиции 38 такого пакета.

Ответ 3

Я попробовал предложение tokland, но я основал, что LibreOffice 4 требует определенного порядка (только для первых?):

  • mimetype (несжатый)
  • 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

Я создаю script для этого 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/

Ответ 4

Мне тоже помогла оболочка script:) У меня возникли проблемы с резервным копированием, после распаковки файла odt. Угадайте, какая манифестная часть пропала.

Однако оболочка script не обрабатывала встроенные изображения/графику, поэтому я сделал некоторые небольшие корректировки, которые работали на меня (также, у script была ошибка в том, что 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"