Как Open Office сжимает свои файлы? - PullRequest
11 голосов
/ 10 февраля 2011

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

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

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

Ответы [ 4 ]

16 голосов
/ 28 марта 2011

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

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

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

  3. Создать новый odt:

    $ zip -0 -X ../document2.odt mimetype
    $ zip -r ../document2.odt * -x mimetype
    
8 голосов
/ 10 февраля 2011

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

Раздел 17.4 MIME Type Stream выглядит следующим образом:

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

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

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

Я попробовал предложение 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/

0 голосов
/ 28 апреля 2014

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

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