A library for the import / export of ODF documents.


Keywords
odf, ods
License
MIT
Install
pip install odio==0.0.22

Documentation

Odio

A pure-Python library for the import / export of ODF documents. Licensed under the MIT Licence. Odio runs on Python 3.6+ and supports ODF 1.1 and 1.2.

Build Status

Installation

It’s a good idea to set up a virtualenv:

python3 -m venv venv
source venv/bin/activate

then install Odio with pip:

pip install odio

Quickstart

Create a spreadsheet:

>>> import odio
>>> import datetime
>>>
>>>
>>> # Create the spreadsheet.
>>> # Version is ODF version. Can be '1.1' or '1.2'. The default is '1.2'.
>>> # Default for 'compressed' is True.
>>> with open('test.ods', 'wb') as f, odio.create_spreadsheet(f, version='1.2', compressed=True) as sheet:
...
...	# Add a table (tab) to the spreadsheet
... 	sheet.append_table(
...         'Plan',
...         [
...             [
...                 "veni, vidi, vici", 0.3, 5, odio.Formula('=B1 + C1'),
...                 datetime.datetime(2015, 6, 30, 16, 38)]])

import the spreadsheet:

>>> import odio
>>>
>>>
>>> # Parse the document we just created.
>>> # Version is ODF version. Can be '1.1' or '1.2'. The default is '1.2'.
>>> with open('test.ods', 'rb') as f:
...     sheet = odio.parse_spreadsheet(f)
>>>
>>> table = sheet.tables[0]
>>> print(table.name)
Plan
>>> for row in table.rows:
...     print(row)
['veni, vidi, vici', 0.3, 5.0, odio.Formula('=B1 + C1'), datetime.datetime(2015, 6, 30, 16, 38)]

Create a text document:

>>> from odio import create_text, P, H, Span
>>>
>>>
>>> # Create the text document. The ODF version string can be '1.2' or '1.1'
>>> with open('test.odt', 'wb') as f, create_text(f, '1.2') as txt:
...
...     txt.append(
...         P("The Meditations", text_style_name='Title'),
...         H("Book One", text_style_name='Heading 1'),
...         P(
...             "From my grandfather ",
...             Span("Verus", text_style_name='Strong Emphasis'),
...             " I learned good morals and the government of my temper."),
...         P(
...             "From the reputation and remembrance of my father, "
...             "modesty and a ", Span("manly", text_style_name='Emphasis'),
...             " character."))

parse the text document:

>>> import odio
>>>
>>>
>>> # Parse the text document we just created. Can be ODF 1.1 or 1.2 format.
>>> txt = odio.parse_text(open('test.odt', "rb"))
>>>
>>> # Find a subnode
>>> subnode = txt.nodes[2]
>>> print(subnode.name)
text:p
>>> print(subnode.attributes['text_style_name'])
Text Body
>>> print(subnode)
odio.P(' From my grandfather ', odio.Span('Verus', text_style_name='Strong Emphasis'), ' I learned good morals and the government of my temper. ')

Regression Tests

To run the regression tests, install tox:

pip install tox

then run tox from the odio directory:

tox

Doing A Release Of Odio

Run tox make sure all tests pass, then update the release notes and then do:

git tag -a x.y.z -m "Version x.y.z"
rm -r build
rm -r dist
python setup.py sdist bdist_wheel --python-tag py3
for f in dist/*; do gpg --detach-sign -a $f; done
twine upload dist/*

Release Notes

Version 0.0.22, 2021-02-08

  • Substitute <text:line-break/> for line breaks.

Version 0.0.21, 2021-02-05

  • Finding text should never result in a None.

Version 0.0.20, 2021-02-04

  • Text should appear in the content of a <text:p> element within a cell.

Version 0.0.19, 2021-02-04

  • Where line breaks appear in a text element’s content, they are now replaced by a <text:line-break/> element. This means that line breaks appear in the spreadsheet, whereas before they didn’t.

Version 0.0.18, 2019-11-29

  • Performance improvement: rather than use the xml.sax.saxutils versions of escape and quoteattr I’ve copied them into the source of odio, but removing the code for entities that aren’t needed.

Version 0.0.17, 2018-08-19

  • When parsing a spreadsheet cell of text type, if the value isn’t contained in the attribute, recursively use the next nodes in the element contents.

Version 0.0.16, 2018-06-01

  • Support the boolean type.

Version 0.0.15, 2017-03-29

  • Fix bug where XML attribute values aren’t escaped.

Version 0.0.14, 2017-03-28

  • Use a streaming approach to file processing rather than an in-memory approach. This uses much less memory.

Version 0.0.13, 2017-03-09

  • Bug where a file was closed when it was passed into a create_spreadsheet for ODF version 1.2.

Version 0.0.12, 2017-03-09

  • The file-like object passed into the parse_* and create_* functions are no longer closed when the returned object is closed.

Version 0.0.11, 2017-03-07

  • Support the table:number-columns-repeated attribute.

Version 0.0.10, 2017-03-07

  • Spreadsheet: Python None corresponds to a table-cell with no attributes.

  • Automate continuous integration with TravisCI.

Version 0.0.9, 2017-03-03

  • Passes tests with Python 3.5.

  • Can now export uncompressed spreadsheets.

Version 0.0.8, 2015-08-02

  • Change read_spreadsheet to parse_spreadsheet.

  • Add support for formulas.

Version 0.0.7, 2015-07-17

  • Can now read ODS spreadsheets. See Quickstart section for details.

  • The append_row() method now accepts a single sequence type, rather than an arbitrary number of positional parameters.

  • API changed so that only the top level odio package needs to be imported. The create_spreadsheet() function is new, and accepts an ODF version string ('1.1', '1.2').

Version 0.0.5, 2015-06-13

  • Fixed links on readme file.

Version 0.0.4, 2015-06-13

  • Renamed OdsOut to Spreadsheet to make things more intuitive.

Version 0.0.3, 2015-06-13

  • Added support for ODF 1.2.

Version 0.0.1, 2015-05-25

  • Make wheel setting 'universal'.

Version 0.0.0, 2015-05-25

  • Initial release, nothing to see yet.