Skip to main content

Odio

A pure-Python library for the import / export of ODF (.ods and .odt) documents. Licensed under the MIT No Attribution Licence. Odio supports ODF 1.1, 1.2 and 1.3.

Installation

  • Set up a virtual environment: python3 -m venv venv
  • Activate the virtual environment: source venv/bin/activate
  • Install Odio with pip: pip install odio

Examples

Create And Save A Spreadsheet

>>> from odio.v1_3 import create_spreadsheet, Cell, Formula, Table
>>> import datetime
>>> 
>>>
>>> # Create the spreadsheet.
>>> sheet = create_spreadsheet()
>>>
>>>	# Append a table (tab) to the spreadsheet
>>> table = sheet.append_table('Plan', values=[
...         [
...             "veni, vidi, vici", 0.3, 5, Formula('=B1 + C1'),
...             datetime.datetime(2015, 6, 30, 16, 38),
...         ],
...     ]
... )
>>>
>>> with open('test.ods', 'wb') as f:
...     sheet.save(f)

Parse a spreadsheet

>>> from odio import parse_document
>>>
>>>
>>> # Parse the document we just created.
>>> with open('test.ods', 'rb') as f:
...     sheet = parse_document(f)
>>>
>>> table = sheet.tables[0]
>>> print(table.name)
Plan
>>> for row in table.rows:
...     for cell in row.cells:
...         print(cell.value)
veni, vidi, vici
0.3
5.0
=B1 + C1
2015-06-30 16:38:00

Create And Save A Text Document

>>> from odio.v1_3 import create_text, P, H, Span
>>> 
>>>
>>> txt = create_text()
>>>	
>>> txt.children.append(H("The Meditations"))
>>> txt.children.append(H("Book One"))
>>> txt.children.append(
...     P(
...         "From my grandfather Verus: the lessons of noble character ",
...         "and even temper."
...     )
... )
>>> txt.children.append(
...     P(
...         "From my father's reputation and my memory of "
...         "him: modesty and manliness."
...     )
... )
>>>
>>> with open('test.odt', 'wb') as f:
...     txt.save(f)

Parse a text document

>>> from odio import parse_document
>>>
>>>
>>> # Parse the text document we just created.
>>> with open('test.odt', "rb") as f:
...     txt = parse_document(f)
>>> 
>>> # Find a child
>>> child = txt.children[2] 
>>> print(child.tag_name)
text:p
>>>
>>> print(child)
<text:p>From my grandfather Verus: the lessons of noble character and even temper.</text:p>

Hyperlinks

In a text document:

>>> from odio.v1_3 import A, P, create_text
>>>
>>> txt = create_text()
>>> p = P(
...     "The 12 books of ",
...     A("The Meditations", href="https://en.wikipedia.org/wiki/Meditations"),
...     " is written in Greek"
... )
>>> txt.children.append(p)
>>>
>>> print(txt.children[0].children[1].href)
https://en.wikipedia.org/wiki/Meditations

and within a cell of a spreadsheet:

>>> sheet = create_spreadsheet()
>>> row = [
...     Cell(
...         P(
...             "The 12 books of ",
...             A("The Meditations", href="https://en.wikipedia.org/wiki/Meditations"),
...             " is written in Greek"
...         )
...     ),
... ]
>>> table = sheet.append_table('Book IX', values=[row])
>>>
>>> cell = table.rows[0].children[0]
>>> print(cell)
<table:table-cell><text:p>The 12 books of <text:a xlink:href="https://en.wikipedia.org/wiki/Meditations" xlink:type="simple">The Meditations</text:a> is written in Greek</text:p></table:table-cell>
>>> print(cell.children[0].children[1].href)
https://en.wikipedia.org/wiki/Meditations

Style

>>> from odio.v1_3 import create_text, P, H1, H2, Span
>>> 
>>>
>>> txt = create_text()
>>>	
>>> txt.children.append(H1("The Meditations", style_name='Title'))
>>> txt.children.append(H2("Book One", style_name='Heading 1'))
>>> txt.children.append(
...     P(
...         "From my grandfather ",
...         Span("Verus", style_name='Strong Emphasis'),
...         " I learned good morals and the government of my temper."
...     )
... )
>>> txt.children.append(
...     P(
...         "From the reputation and remembrance of my father, "
...         "modesty and a ", Span("manly", style_name='Emphasis'),
...         " character."
...     )
... )
>>>
>>> with open('test.odt', 'wb') as f:
...     txt.save(f)

References

Validator

https://odfvalidator.org/

Regression Tests

  • Install tox: pip install tox
  • Run tox: 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 dist
  • python -m build
  • twine upload dist/*

Release Notes

Version 0.0.27, 2025-08-06

  • Should be at least one row in a table.

Version 0.0.26, 2025-07-31

  • Update README with Codeberg homepage.
  • Tidy up top-level __init__.

Version 0.0.25, 2025-07-28 18:18

  • Modify sheet.append_table to accept rows.

Version 0.0.24, 2025-07-28 18:00

  • Add support for ODF 1.3
  • Handle table cell dates that don't have a time.

Version 0.0.23, 2024-05-22

  • When writing out to a spreadsheet, interpret a decimal.Decimal as a number.

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.

Metadata

Release files for odio 0.0.27

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for odio 0.0.27
File Size Uploaded
odio-0.0.27.tar.gz 122.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for odio 0.0.27
File Interpreter ABI Platform
odio-0.0.27-py3-none-any.whl Python 3 none any Details

Total release size: 150.2 kB

Release files / odio-0.0.27.tar.gz

Download URL odio-0.0.27.tar.gz
Size 122.7 kB
Tags Source
SHA-256 checksum
How to use checksums
dab42e4a6d5a24ac7d10b18789d68ee3377a993ef643efaedff0d7892acb106e
BLAKE2b-256 checksum
How to use checksums
e286b29769bad0c6f6f7b0478235c55dd0fa344cb459651f5056c02ea925c4f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.5

Release files / odio-0.0.27-py3-none-any.whl

Download URL odio-0.0.27-py3-none-any.whl
Size 27.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f1a753e8bb1cb3bf46fbfca1aa2f99c78113b2933c804bc5254d4fbc917d79ef
BLAKE2b-256 checksum
How to use checksums
2e3e0a3792006981b50755506380ad78e2d8b6ed51bce6179bad87aca2710e24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.5

Release history Release notifications | RSS feed

This release

0.0.27 This release

2 release files

0.0.26

2 release files

0.0.25

2 release files

0.0.24

2 release files

0.0.23

2 release files

0.0.18

2 release files

0.0.17

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page