Запись в OpenDocumentFormat в Ruby без гемов (часть 1)

Обычно для записи информации в файлы формата XLSX или ODF при использовании Ruby применяют гемы. RPG Maker же является такой средой, в которой подключение гемов возможно пока только теоретически, на практике обычный require может привести к различным ошибкам, а способ, описанный мной, еще до конца не протестирован.

По этой причине, я начал писать скрипт самостоятельно. Код жутко наивный, скорость выполнения низкая, но работать должно.

Уточнение информации

Во-первых, я слышал, что нужный мне формат файла (а я выбрал ODS - файл с таблицами для OpenOffice.org Calc) - это ничто иное, кроме как обычный арзив в формате ZIP с переименованным расширением. Проверим!


Создал файл, забил в него него тестовые данные:
Сохранил его как File.ods и открыл папку с ним. Теперь поставим ему другое расширение - zip, попробуем распаковать.
---->>---->>

 Открываю его архиватором и смотрю содержимое.
Да, так и есть! Это просто архив с кучей файлов с настройками. Большинство настроек выставлены по умолчанию, ведь я почти ничего не менял.

Подготовка и планирование

Осмотрев все файлы из всех папок было установлено:
  • Все читабельное содержимое документа содержится в файле content.xml как данные формата XML
  • В Thumbnails лежит файл формата PNG с изображением содержимого для отображения в Проводнике
  • Все остальное - куча настроек
Следовательно:
  • Мы пишем скрипт, который переписывает content.xml
  • Создаем Bitmap, рисуем в нем что-нибудь (что угодно) и сохраняем его при помощи Bitmap Export (ссылка на источник)
  • Все остальное будет записываться как есть, без изменений.
Почему же я не хочу менять какие-либо настройки? Потому что не вижу в этом смысла. Все, что мне нужно на данный моменты - записывать данные в этом формате, а не делать ко всему этому еще и красивую вёрстку.

Что мне понадобится в работе:
  • любой установленный архиватор, скопированный в папку с проектом
  • редактор скриптов
  • командная строка
В качестве архиватора я взял 7-zip, редактор скриптов - Gemini. Командная строка понадобится для запуска команд упаковки/распаковки архиватором.

Содержимое класса ODS

  • константы настроек: 
    • команда для вызова упаковки файлов в архив (для экспорта данных)
    • команда для вызова распаковки архива в файлы (для импорта данных)
  • write - запись файлов с упаковкой в ods, содержит вызов таких методов:
    • write_metainf
    • write_styles
    • write_settings
    • write_thumbnails
    • write_content
    • write_mimetype
  • read - распаковка ods и чтение содержимого, содержит вызов методов:
    • read_content
  • sheet - доступ к массиву страниц (класс Sheets)
  • sheets - массив названий страниц
  • класс Sheets - содержит массив из страниц (класс Sheet), содержит
    • [] - доступ к определенному элементу или создание нового (если такой страницы под этим номером еще не было)
    • name - название страницы под указанным номером
    • names - массив имен страниц
    • to_a - массив самих страниц
  • класс Sheet - содержит всю информацию о ячейках на странице
Запись различных данных разделена на несколько методов для будущих модификаций, мало ли понадобятся какие-либо настройки. Чтение производится только из content.xml.

Первые попытки

Вначале я реализовал запись самым наивным способом - просто копировал содержимое тех файлов, менять которые не собирался и вставлял в то место в коде, которое отвечает за последующее воссоздание файла со всем содержимым в процессе записи.
Выглядело это следующим образом:
Стыд и позор за такой код! Каюсь
Я знаю, это невероятно ужасно, поэтому, скопировав таким же образом примерно три или четыре файла, я решил пойти и разобраться, что это за файлы и можно ли обойтись без них.

Выход нашелся спустя несколько часов вдумчивого чтения всех файлов по очереди. Заключается он в том, что все файлы, которые используются документом, прописывается в файле manifest.xml, который лежит в META-INF. Аккуратно поудалял указатели на бесполезные файлы, также стерев эти самые файлы, собрал файл и попробовал открыть его. И... все открылось! Тогда я понял, что это прорыв, именно то решение, которое мне и нужно.
Удаляем все лишнее из манифеста
А также - из папки
Также я начал ставить эксперименты над упрощением содержимого файла content.xml, но вдруг обнаружил, что наступила ночь и время идти спать. Завтра уже приступлю к коду и посмотрю, что из этого выйдет.

Комментарии

  1. а экспортировал бы в csv, уже давно закончил бы)

    ОтветитьУдалить
    Ответы
    1. мне важен не только результат, но и сам путь, по которому я пройду до него)) чем больше интересного встретиться мне и чем больше будет поставлено экспериментов, тем больше опыта ^_^

      Удалить
    2. ну да, а на пенсии (когда получишь достаточно тебе опыта) развернешься)))

      Удалить

Отправить комментарий

Популярные сообщения из этого блога

Генератор названий оружия

Создание компонента Delphi

Идеи: Генератор сказки