PyLOO — Библиотека для генерации отчетов, счетов Libre/Open Office на Python

от автора

Порой возникают задачи, когда возникает необходимость формировать отчеты и прочие документы. В моей практике данная задача возникала не раз.

Проекты, в которых возникала данная задача:

  • складской учет
  • учет объектов недвижимости
  • документооборот

Первый мой опыт был с MS Office, но позже возникла необходимость в разработке кросс-платформенных решений, посему выбор пал на OpenOffice. Т.к. в большинстве случаев нужно было формировать таблицы, то был выбран OpenOffice Calc.

Сперва я решал подобные задачи на С++, разработал библиотеку, которую использовал в разных проектах. Все было хорошо, но чуть ли не каждая минорная версия офиса требовала пересборки библиотеки, а не редко и правки кода. Под каждый дистрибутив и его новую версию приходилось в лучшем случае пересобирать пакеты, править пути с учетом версии офиса, замену OpenOffice на LibreOffice и т.п. А это очень утомительно и отнимает время.

Все эти трудности привели к поиску более простых решений. Я посмотрел список поддерживаемых языков и увидел Python, что меня очень заинтересовало, т.к. уже довольно активно его начал использовать. Нашел простенький пример, попробовал — работает. Проверил на разных версиях и — о, чудо! Без малейших правок один и тот же скрипт работает на разных дистрибутивах и версиях офиса.

Те, кто уже сталкивался с подобными задачами — знает, что ковыряние API дело не благодарное. Посему первым делом я принялся искать уже готовые библиотеки. Наиболее интересным вариантом для меня оказался PyOO. Данная библиотека содержит довольно обширный функционал и довольно проста в использовании. В ней реализованы функции от создания/сохранения документов до объединения ячеек и создания диаграмм. Но… Ни одна из найденных мной библиотек не обеспечивала необходимый мне функционал. Много вкусного, но лишнего для меня.

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

С созданием шаблонов все ясно, но как знать, куда необходимо вставлять данные. Можно использовать индексы (колонка, строка) или имя (например: «E5»).

Но что если для одного отчета необходимо создать несколько шаблонов для генерации документа. Например один шаблон для книжного расположения, второй для альбомного. Но нет никакой гарантии, что и в одном и в другом шаблоне одно и то же поле (данные) необходимо вставить по одному и тому же имени (или индексу) ячейки. А это означает, что нужно хранить данные о расположении полей в шаблоне. Но есть более простое универсальное решение. Данную задачу можно реализовать через NamedRange.

NamedRange — это имя ячейки или области на листе. При этом NamedRange уникальный в рамкой одной книги (документа).

Еще одна необходимая функция для решения данной задачи — вставка строк. При этом вставка должна быть с учетом сохранения форматирования строки (шрифт, объединенные ячейки и т.п.).

Исходя из вышеперечисленных задач, был разработан модуль на Python, который реализует следующие функции:

  • Открытие и создание документов
  • Сохранение документов разных форматах (поддерживаемых Libre/Open Office)
  • Вставка/удаление листов
  • Вставка строк с копированием форматирования
  • Вставка/получения значения имен (NamedRange)
  • Вставка/получения значения ячеек по имени (индексу)

Пример использования:

import pyloo  # open document doc = pyloo.Document() file_name = os.getcwd() + "/example.ods" doc.open_document(file_name)  # Get document fields fields = doc.fields()  # Get field "HEADER" field = fields.field("HEADER") print ("Document header is: " + str(field.is_null()))  # Set values field = fields.field("TABLE_NAME") field.set_value("Test table name") print ("New table name is: " + field.value())  # Insert 5 rows field1 = fields.field("FIELD_1") num_rows = 5 step = 2 if num_rows > 0:     field1.insert_rows(num_rows=num_rows-1, step=step, columns_to_copy=200) for i in range(1, num_rows + 1):     field1.set_value("F1." + str(i), 0, i * step - (step - 1))  # Set value="value1" at column=1, row=1 (B1) sheet = doc.sheets().sheet(0) sheet.set_cell_value_by_index(1, 0, "value1") print (sheet.cell_value_by_index(1, 0)) 

Уверен, что данная задача возникала не только у меня. Рад, если кому-то пригодится.

Пример документа с данными требованиями и пример использования библиотеки находятся в каталоге examples.

Скачать: PyLOO

ссылка на оригинал статьи http://habrahabr.ru/post/273131/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *