Найти - Пользователи
Полная версия: ODFpy
Начало » Python для новичков » ODFpy
1
Kultom
Добрый день. Моя программа после расчётов должна выполнить отчёт и сохранить его в формате .odt
Помогите пожалуйста разобраться с библиотекой pyODF.

Разобрался как создавать текст, но в отчёт хотелось бы ещё вставить формулы Math.
пробую так:

from odf import opendocument
from odf import math



def main():
document = opendocument.OpenDocumentText()
formula = math.Math(c = 'sqrt{9}')
document.createElement(formula)
document.save('odftrenning.odt')


if __name__ == '__main__':
main()
но в ответ интерпретатор ругается:
Traceback (most recent call last):
File “E:\python_programms\odftrening.py”, line 19, in <module>
main()
File “E:\python_programms\odftrening.py”, line 14, in main
document.createElement(formula)
File “C:\Python27\lib\site-packages\odf\opendocument.py”, line 493, in createElement
return element(check_grammar=False)
AttributeError: Element instance has no __call__ method

Подскажите кто-нибудь. Может кто пользовался этой библиотекой, подскажите в какую сторону копать
Kultom
Решил проблему в обход.
Алгоритм такой:
1. Разархивирую ранее набранный файл odt (болванка)
2. Внутри лежат xml файлы. В них нахожу нужное слово, заменяю его на требуемое значение.
3. Снова запаковываю и вуаля: получаю красивый отчёт в виде текстового документа с формулами.

Хоть и многодельно, зато работает на ура.
p.s. библиотека pyODF оказалась ненужной
__akm__
Написал пару функций для генерации элемента math. Может пригодится кому-нибудь
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from xml.dom.minidom import parseString
from xml.dom import Node
import odf
import odf.opendocument
import odf.text
from odf.element import Element
from namespaces import MATHNS
math_templ = u'\
<math xmlns="http://www.w3.org/1998/Math/MathML">\
<semantics>\
<annotation encoding="StarMath 5.0">%s</annotation>\
</semantics></math>'
def gen_odf_math_(parent):
    elem = Element(qname = (MATHNS,parent.tagName))
    if parent.attributes:
        for attr, value in parent.attributes.items():
            elem.setAttribute((MATHNS,attr), value, check_grammar=False)
    for child in parent.childNodes:
        if child.nodeType == Node.TEXT_NODE:
            text = child.nodeValue
            elem.addText(text, check_grammar=False)
        else:
            elem.addElement(gen_odf_math_(child), check_grammar=False)
    return elem
def gen_odf_math(starmath_string):
    u'''
    Generating odf.math.Math element
    '''
    mathml = math_templ % (starmath_string)
    math_ = parseString(mathml.encode('utf-8'))
    math_ = math_.documentElement
    odf_math = gen_odf_math_(math_)
    return odf_math
def main():
    doc = odf.opendocument.OpenDocumentText()
    p = odf.text.P(text=u'text')
    df = odf.draw.Frame( zindex=0, anchortype='as-char')
    p.addElement(df)
    doc.text.addElement(p)
    formula = 'c = sqrt(a^2+b_2) + %ialpha over %ibeta'
    math = gen_odf_math(formula)
    do = odf.draw.Object()
    do.addElement(math)
    df.addElement(do)
    outputfile = u'result'
    doc.save(outputfile, True)
if __name__ == '__main__':
    main()
doza_and
Kultom
В них нахожу нужное слово
Только надо сделать так чтобы оно не встретилось случайно в другом месте. Делали такие штуки в несколько более развернутом виде. Проблема в том, что часто нужно вставить таблицы или рисунки. В одни документ вставить другой. Применить совершенно нестандартную схему нумерации. и т.п. Мы использовали внутри документа разметку из mako templates. А таблички и прочие сложные объекты вставляли функцией (мако допускает шаблонные функции).
Из минусов.
1. Надежность подхода невелика. Часто шаблоны рвутся и ломаются форматированием (особенно характерно для docx). Поэтому все шаблонизаторы odt/docx, которые мы нашли в интернете используют для подставляемых значений не просто текст а поля. Это не очень удобно при редактировании. (мы применяли специальные процедуры восстановления - склейки шаблонов)
2. xml шаблон велик. Большие документы не прожевываются или прожевываются медленно если документ большой.
3. Неудобно работать со стилями. Например так и не научились вставлять один документ в другой для формата docx (Кстати и сам word этого похоже не может нормально сделать).
4. Проблемки с автонумеруемыми полями. Не знаю как в odt а в docx так и не научились нормально вставлять картинки в виде “связать и вставить” с добавлением номеров рисунков.

Поэтому от такого подхода отказались.
Используем цепочки latex->pdf, latex->docx latex->odt,rst->latex->docx
Инструмента всего три Latex, Sphinx, pandoc. Т.е первичные данные - LaTeX (отчеты) или rst (программная документация) все остальное вторично.
__akm__
Разобрался в итоге. Теперь более красивый вариант.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import odf
from odf.opendocument import OpenDocumentText
from odf.element import Element
from odf.text import P
from odf.math import Math
from namespaces import MATHNS
def main():
    doc = OpenDocumentText()
    p = P(text=u'text')
    df = odf.draw.Frame( zindex=0, anchortype='as-char')
    p.addElement(df)
    doc.text.addElement(p)
    formula =u'c=sqrt(a^2+b^2)'
    math = Math()
    annot = Element(qname = (MATHNS,u'annotation'))
    annot.addText(formula, check_grammar=False)
    annot.setAttribute((MATHNS,'encoding'), 'StarMath 5.0', check_grammar=False)
    math.addElement(annot)
    do = odf.draw.Object()
    do.addElement(math)
    df.addElement(do)
    outputfile = u'result'
    doc.save(outputfile, True)
if __name__ == '__main__':
    main()
doza_and
__akm__
Теперь более красивый вариант.
А use case какой у этой конструкции?
__akm__
Мне нужно сгенерировать трассировку инженерного расчёта с описанием хода решения. Там должны быть формулы. ODFpy позволяет сгенерировать данный отчёт. Вначале использовал docutils с конвертацией rst в html. Потом захотелось иметь возможность ручной корректировки отчёта и остановился на формате odt.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB