or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# pyexcel-ods

1

2

A Python wrapper library for reading, manipulating, and writing data in OpenDocument Spreadsheet (ODS) format. Built on top of the odfpy library, pyexcel-ods provides simple, intuitive functions for working with ODS files without complex formatting concerns. Integrates seamlessly with the broader pyexcel ecosystem for comprehensive data processing workflows.

3

4

## Package Information

5

6

- **Package Name**: pyexcel-ods

7

- **Language**: Python

8

- **Installation**: `pip install pyexcel-ods`

9

10

## Core Imports

11

12

```python

13

from pyexcel_ods import get_data, save_data

14

```

15

16

Alternative import for backward compatibility:

17

18

```python

19

from pyexcel_ods import read_data, write_data

20

```

21

22

Check if object is a stream:

23

24

```python

25

from pyexcel_ods import isstream

26

```

27

28

## Basic Usage

29

30

```python

31

from pyexcel_ods import get_data, save_data

32

from collections import OrderedDict

33

34

# Reading an ODS file

35

data = get_data("input.ods")

36

print(data) # {'Sheet1': [[1, 2, 3], [4, 5, 6]], 'Sheet2': [['a', 'b', 'c']]}

37

38

# Writing to an ODS file

39

output_data = OrderedDict()

40

output_data.update({"Sheet 1": [[1, 2, 3], [4, 5, 6]]})

41

output_data.update({"Sheet 2": [["row 1", "row 2", "row 3"]]})

42

save_data("output.ods", output_data)

43

44

# Working with memory streams

45

from io import BytesIO

46

47

# Write to memory

48

io_stream = BytesIO()

49

save_data(io_stream, output_data)

50

51

# Read from memory

52

io_stream.seek(0) # Reset stream position

53

data_from_memory = get_data(io_stream)

54

```

55

56

## Capabilities

57

58

### Data Reading

59

60

Read data from ODS files into Python data structures.

61

62

```python { .api }

63

def get_data(afile, file_type=None, **keywords):

64

"""

65

Standalone module function for reading module supported file type.

66

67

Args:

68

afile: File path (str) or file-like object to read from

69

file_type (str, optional): File type specification. Defaults to 'ods'

70

when afile is a stream

71

**keywords: Additional keyword arguments:

72

- start_row (int): Starting row index for pagination

73

- row_limit (int): Maximum number of rows to read

74

- start_column (int): Starting column index for pagination

75

- column_limit (int): Maximum number of columns to read

76

- auto_detect_int (bool): Auto-detect integers from floats (default: True)

77

78

Returns:

79

dict: Dictionary with sheet names as keys and data as lists of lists

80

81

Example:

82

data = get_data("file.ods")

83

# Returns: {"Sheet1": [[1, 2], [3, 4]], "Sheet2": [["a", "b"]]}

84

85

# With pagination

86

partial = get_data("file.ods", start_row=1, row_limit=5)

87

"""

88

```

89

90

### Data Writing

91

92

Write Python data structures to ODS files.

93

94

```python { .api }

95

def save_data(afile, data, file_type=None, **keywords):

96

"""

97

Standalone module function for writing module supported file type.

98

99

Args:

100

afile: File path (str) or file-like object to write to

101

data (dict): Dictionary with sheet names as keys and data as lists of lists

102

file_type (str, optional): File type specification. Defaults to 'ods'

103

when afile is a stream

104

**keywords: Additional keyword arguments passed to writer

105

106

Returns:

107

None

108

109

Example:

110

from collections import OrderedDict

111

data = OrderedDict()

112

data["Sheet1"] = [[1, 2, 3], [4, 5, 6]]

113

data["Sheet2"] = [["a", "b", "c"]]

114

save_data("output.ods", data)

115

"""

116

```

117

118

### Compatibility Functions

119

120

Alternative function names for backward compatibility with older pyexcel-ods versions.

121

122

```python { .api }

123

def read_data(afile, file_type=None, **keywords):

124

"""

125

Alias for get_data(). Identical functionality.

126

127

Args:

128

afile: File path or file-like object

129

file_type (str, optional): File type specification

130

**keywords: Same as get_data()

131

132

Returns:

133

dict: Same as get_data()

134

"""

135

136

def write_data(afile, data, file_type=None, **keywords):

137

"""

138

Alias for save_data(). Identical functionality.

139

140

Args:

141

afile: File path or file-like object

142

data (dict): Data to write

143

file_type (str, optional): File type specification

144

**keywords: Same as save_data()

145

146

Returns:

147

None

148

"""

149

```

150

151

### Stream Utilities

152

153

Utility functions for working with file-like objects.

154

155

```python { .api }

156

def isstream(afile):

157

"""

158

Check if the given object is a stream-like object.

159

160

Args:

161

afile: Object to check

162

163

Returns:

164

bool: True if object is stream-like, False otherwise

165

"""

166

```

167

168

## Data Types and Formats

169

170

### Supported Data Types

171

172

**Reading Support:**

173

- **Strings**: Text content, including multi-line strings with embedded newlines

174

- **Numbers**: Integers and floating-point numbers with automatic type detection

175

- **Booleans**: True/False values

176

- **Dates**: Date objects (converted to Python datetime.date)

177

- **Times**: Time objects (converted to Python datetime.time or timedelta)

178

- **Currency**: Formatted as "value currency" strings (e.g., "1 GBP", "-10000 USD")

179

- **Percentages**: Numeric percentage values

180

- **Empty cells**: Represented as empty strings or appropriate null values

181

182

**Writing Support:**

183

- **Basic Python types**: str, int, float, bool

184

- **Multi-line strings**: Strings containing newline characters

185

- **Automatic type conversion**: Python types are automatically converted to appropriate ODS cell types

186

187

### Data Structure Format

188

189

Data is organized as nested dictionaries and lists:

190

191

```python

192

{

193

"Sheet Name 1": [

194

["cell_a1", "cell_b1", "cell_c1"], # Row 1

195

["cell_a2", "cell_b2", "cell_c2"], # Row 2

196

["cell_a3", "cell_b3", "cell_c3"] # Row 3

197

],

198

"Sheet Name 2": [

199

[1, 2, 3, 4],

200

[5, 6, 7, 8]

201

]

202

}

203

```

204

205

### Pagination Options

206

207

For large files, you can read partial data using pagination parameters:

208

209

- **`start_row`**: Starting row index (0-based)

210

- **`row_limit`**: Maximum number of rows to read

211

- **`start_column`**: Starting column index (0-based)

212

- **`column_limit`**: Maximum number of columns to read

213

214

```python

215

# Read rows 2-4, columns 1-3

216

partial_data = get_data("large_file.ods",

217

start_row=2, row_limit=3,

218

start_column=1, column_limit=3)

219

```

220

221

## File and Stream Handling

222

223

### File Path Usage

224

225

```python

226

# Read from file path

227

data = get_data("/path/to/file.ods")

228

229

# Write to file path

230

save_data("/path/to/output.ods", data)

231

```

232

233

### Memory Stream Usage

234

235

```python

236

from io import BytesIO

237

238

# Writing to memory stream

239

memory_stream = BytesIO()

240

save_data(memory_stream, data)

241

242

# Reading from memory stream

243

memory_stream.seek(0) # Reset position to beginning

244

data = get_data(memory_stream, file_type="ods")

245

246

# Or get bytes for HTTP response, file upload, etc.

247

ods_bytes = memory_stream.getvalue()

248

```

249

250

### Integration with Web Frameworks

251

252

```python

253

# Flask example - file upload

254

from flask import Flask, request

255

app = Flask(__name__)

256

257

@app.route('/upload', methods=['POST'])

258

def upload_file():

259

file = request.files['ods_file']

260

data = get_data(file, file_type="ods")

261

# Process data...

262

return "File processed"

263

264

# Django example - file download

265

from django.http import HttpResponse

266

267

def download_ods(request):

268

data = {"Sheet1": [[1, 2, 3], [4, 5, 6]]}

269

270

response = HttpResponse(content_type='application/vnd.oasis.opendocument.spreadsheet')

271

response['Content-Disposition'] = 'attachment; filename="data.ods"'

272

273

save_data(response, data)

274

return response

275

```

276

277

## Integration with pyexcel Ecosystem

278

279

pyexcel-ods automatically integrates with the broader pyexcel library when both are installed:

280

281

```python

282

import pyexcel as pe

283

284

# pyexcel automatically uses pyexcel-ods for .ods files

285

book = pe.get_book(file_name="data.ods")

286

sheet = pe.get_sheet(file_name="data.ods")

287

288

# Save pyexcel objects as ODS

289

sheet.save_as("output.ods")

290

```

291

292

## Error Handling

293

294

Common error scenarios and handling:

295

296

```python

297

# File not found

298

try:

299

data = get_data("nonexistent.ods")

300

except FileNotFoundError:

301

print("File not found")

302

303

# Invalid ODS file

304

try:

305

data = get_data("corrupted.ods")

306

except Exception as e:

307

print(f"Error reading ODS file: {e}")

308

309

# Write permissions

310

try:

311

save_data("/readonly/path/file.ods", data)

312

except PermissionError:

313

print("No write permission")

314

```

315

316

## Limitations

317

318

- **Formatting not supported**: Fonts, colors, charts, and visual formatting are not preserved

319

- **Data focus**: Designed for data extraction and generation, not document formatting

320

- **Read-only for complex features**: Advanced ODS features like formulas, macros, and embedded objects are not supported

321

- **Memory considerations**: Large files are read entirely into memory; use pagination for very large datasets

322

323

## Constants

324

325

```python { .api }

326

__FILE_TYPE__ = "ods" # File type identifier used internally

327

```