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.
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
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 ofescape
andquoteattr
I’ve copied them into the source ofodio
, 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 atable-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
toparse_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. Thecreate_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.