2025-04-14 14:37:03 +02:00
|
|
|
# @odfjs/odfjs
|
2024-06-14 16:57:20 +02:00
|
|
|
|
2025-04-14 14:37:03 +02:00
|
|
|
Small lib to parse/understand .odf files (.odt, .ods) in the browser and node.js
|
2024-06-14 16:57:20 +02:00
|
|
|
|
|
|
|
|
|
2025-04-07 11:00:18 +02:00
|
|
|
## Rough roadmap
|
|
|
|
|
|
2025-04-09 10:37:05 +02:00
|
|
|
- [x] add odt templating
|
2025-04-17 17:39:08 +02:00
|
|
|
- [x] remove support for xlsx
|
2025-04-07 11:00:18 +02:00
|
|
|
- [ ] add a .ods minifyer
|
|
|
|
|
- [ ] add a generic .ods visualizer
|
|
|
|
|
- [ ] move to a dedicated odf docs org
|
|
|
|
|
- [ ] add a quick .odt visualiser (maybe converting to markdown first?)
|
|
|
|
|
|
|
|
|
|
|
2024-06-16 14:31:57 +02:00
|
|
|
## Usage
|
|
|
|
|
|
|
|
|
|
### Install
|
|
|
|
|
|
|
|
|
|
```sh
|
2025-04-17 17:39:50 +02:00
|
|
|
npm i https://github.com/odfjs/odfjs.git#v0.15.0
|
2024-06-16 14:31:57 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2025-04-17 17:39:08 +02:00
|
|
|
### Basic - reading an ods file
|
2024-06-16 14:31:57 +02:00
|
|
|
|
|
|
|
|
```js
|
2025-04-14 14:56:45 +02:00
|
|
|
import {tableRawContentToObjects, tableWithoutEmptyRows, getODSTableRawContent} from '@odfjs/odfjs'
|
2024-06-16 14:31:57 +02:00
|
|
|
|
|
|
|
|
/**
|
2025-04-07 11:00:18 +02:00
|
|
|
* @param {ArrayBuffer} odsFile - content of an .ods file
|
2024-06-16 14:31:57 +02:00
|
|
|
* @return {Promise<any[]>}
|
|
|
|
|
*/
|
2025-04-07 11:00:18 +02:00
|
|
|
async function getFileData(odsFile){
|
|
|
|
|
return getODSTableRawContent(odsFile)
|
2024-06-18 11:06:41 +02:00
|
|
|
.then(tableWithoutEmptyRows)
|
|
|
|
|
.then(tableRawContentToObjects)
|
2024-06-16 14:31:57 +02:00
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The return value is an array of objects where
|
|
|
|
|
the **keys** are the column names in the first row and
|
2025-04-17 17:39:08 +02:00
|
|
|
the **values** are automatically converted from the .ods files (which type numbers, strings, booleans and dates)
|
2024-06-16 14:31:57 +02:00
|
|
|
to the appropriate JavaScript value
|
|
|
|
|
|
|
|
|
|
|
2025-04-07 11:00:18 +02:00
|
|
|
### Basic - creating an ods file
|
2024-10-23 19:13:29 +02:00
|
|
|
|
|
|
|
|
```js
|
2025-04-17 17:39:08 +02:00
|
|
|
import {createOdsFile} from '@odfjs/odfjs'
|
2024-10-23 19:13:29 +02:00
|
|
|
|
|
|
|
|
const content = new Map([
|
|
|
|
|
[
|
|
|
|
|
'La feuille',
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
{value: '37', type: 'float'},
|
|
|
|
|
{value: '26', type: 'string'}
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
"L'autre feuille",
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
{value: '1', type: 'string'},
|
|
|
|
|
{value: '2', type: 'string'},
|
|
|
|
|
{value: '3', type: 'string'},
|
|
|
|
|
{value: '5', type: 'string'},
|
|
|
|
|
{value: '8', type: 'string'}
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
]
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
const ods = await createOdsFile(content)
|
|
|
|
|
// ods is an ArrayBuffer representing an ods file with the content described by the Map
|
|
|
|
|
```
|
|
|
|
|
|
2024-10-23 21:06:01 +02:00
|
|
|
(and there is a tool to test file creation:
|
|
|
|
|
`node tools/create-an-ods-file.js > yo.ods`)
|
2024-10-23 19:13:29 +02:00
|
|
|
|
2024-06-16 14:31:57 +02:00
|
|
|
|
2025-04-07 11:00:18 +02:00
|
|
|
### Filling an .odt template
|
|
|
|
|
|
|
|
|
|
odf.js proposes a template syntax
|
|
|
|
|
|
|
|
|
|
In an .odt file, write the following:
|
|
|
|
|
|
|
|
|
|
```txt
|
|
|
|
|
Hey {nom}!
|
|
|
|
|
|
|
|
|
|
Your birthdate is {dateNaissance}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
And then run the code:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
import {join} from 'node:path';
|
|
|
|
|
|
|
|
|
|
import {getOdtTemplate} from '../scripts/odf/odtTemplate-forNode.js'
|
|
|
|
|
import {fillOdtTemplate} from '../scripts/node.js'
|
|
|
|
|
|
|
|
|
|
// replace with your template path
|
|
|
|
|
const templatePath = join(import.meta.dirname, './tests/data/template-anniversaire.odt')
|
|
|
|
|
const data = {
|
|
|
|
|
nom: 'David Bruant',
|
|
|
|
|
dateNaissance: '8 mars 1987'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const odtTemplate = await getOdtTemplate(templatePath)
|
|
|
|
|
const odtResult = await fillOdtTemplate(odtTemplate, data)
|
|
|
|
|
|
|
|
|
|
process.stdout.write(new Uint8Array(odtResult))
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
There are also loops in the form:
|
|
|
|
|
|
|
|
|
|
```txt
|
|
|
|
|
- {#each listeCourses as élément}
|
|
|
|
|
- {élément}
|
|
|
|
|
- {/each}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
They can be used to generate lists or tables in .odt files from data and a template using this syntax
|
|
|
|
|
|
2024-06-16 14:31:57 +02:00
|
|
|
|
|
|
|
|
### Demo
|
|
|
|
|
|
2025-04-17 17:39:08 +02:00
|
|
|
https://odfjs.github.io/odfjs/
|
2024-06-14 16:57:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
## Local dev
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
npm install
|
|
|
|
|
npm run dev
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2025-04-07 11:00:18 +02:00
|
|
|
|
|
|
|
|
|
2024-06-14 16:57:20 +02:00
|
|
|
## Expectations and licence
|
|
|
|
|
|
2024-06-16 14:31:57 +02:00
|
|
|
I hope to be credited for the work on this repo
|
2024-06-14 16:57:20 +02:00
|
|
|
|
|
|
|
|
Everything written by me and contributors to this repo is licenced under **CC0 1.0 (Public Domain)**
|
|
|
|
|
|