numbers-parser 4.8.1__tar.gz → 4.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/PKG-INFO +23 -28
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/README.md +22 -27
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/pyproject.toml +1 -1
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/cell.py +80 -13
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/cell_storage.py +48 -12
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/constants.py +103 -6
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/containers.py +2 -2
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/document.py +193 -69
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/file.py +9 -4
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/model.py +104 -1
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/LICENSE.rst +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/__init__.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/_cat_numbers.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/_unpack_numbers.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/bullets.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/currencies.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/data/empty.numbers +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/exceptions.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/experimental.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/formula.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TNArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TNArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TNCommandArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TNCommandArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSAArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSAArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSACommandArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSCEArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSCH3DArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSCHArchives_Common_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSCHArchives_GEN_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSCHArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSCHArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSCHCommandArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSCHPreUFFArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSDArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSDArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSDCommandArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSKArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSKArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSPArchiveMessages_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSPDatabaseMessages_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSPMessages_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSSArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSSArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSTArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSTArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSTCommandArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSTStylePropertyArchiving_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSWPArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSWPArchives_sos_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/TSWPCommandArchives_pb2.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/__init__.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/fontmap.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/generated/functionmap.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/iwafile.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/mapping.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/numbers_cache.py +0 -0
- {numbers_parser-4.8.1 → numbers_parser-4.9.0}/src/numbers_parser/numbers_uuid.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: numbers-parser
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.9.0
|
|
4
4
|
Summary: Read and write Apple Numbers spreadsheets
|
|
5
5
|
Home-page: https://github.com/masaccio/numbers-parser
|
|
6
6
|
License: MIT
|
|
@@ -187,8 +187,8 @@ Whilst support for writing numbers files has been stable since version
|
|
|
187
187
|
and instead save data to a new file.
|
|
188
188
|
|
|
189
189
|
Cell values are written using
|
|
190
|
-
[Table.write()](https://masaccio.github.io/numbers-parser
|
|
191
|
-
|
|
190
|
+
[Table.write()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.write) and
|
|
191
|
+
`numbers-parser` will automatically create empty rows and columns
|
|
192
192
|
for any cell references that are out of range of the current table.
|
|
193
193
|
|
|
194
194
|
```python
|
|
@@ -201,12 +201,9 @@ table.write("B7", datetime(2020, 12, 25))
|
|
|
201
201
|
doc.save("new-sheet.numbers")
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
-
Additional tables and worksheets can be added to a `Document` before
|
|
205
|
-
|
|
206
|
-
[
|
|
207
|
-
and
|
|
208
|
-
[Sheet.add_table()](https://masaccio.github.io/numbers-parser/#numbers_parser.Sheet.add_table)
|
|
209
|
-
respectively:
|
|
204
|
+
Additional tables and worksheets can be added to a `Document` before saving using
|
|
205
|
+
[Document.add_sheet()](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_sheet) and
|
|
206
|
+
[Sheet.add_table()](https://masaccio.github.io/numbers-parser/api/sheet.html#numbers_parser.Sheet.add_table) respectively:
|
|
210
207
|
|
|
211
208
|
```python
|
|
212
209
|
doc = Document()
|
|
@@ -222,27 +219,28 @@ doc.save("sheet.numbers")
|
|
|
222
219
|
### Styles
|
|
223
220
|
|
|
224
221
|
`numbers_parser` currently only supports paragraph styles and cell
|
|
225
|
-
styles. The following
|
|
222
|
+
styles. The following styles are supported:
|
|
226
223
|
|
|
227
224
|
- font attributes: bold, italic, underline, strikethrough
|
|
228
225
|
- font selection and size
|
|
229
226
|
- text foreground color
|
|
230
227
|
- horizontal and vertical alignment
|
|
231
228
|
- cell background color
|
|
229
|
+
- cell background images
|
|
232
230
|
- cell indents (first line, left, right, and text inset)
|
|
233
231
|
|
|
234
232
|
Numbers conflates style attributes that can be stored in paragraph
|
|
235
233
|
styles (the style menu in the text panel) with the settings that are
|
|
236
234
|
available on the Style tab of the Text panel. Some attributes in Numbers
|
|
237
|
-
are not applied to new cells when a style is applied.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
object. When a document is saved, the attributes
|
|
241
|
-
paragraph style are applied to each cell that includes it.
|
|
235
|
+
are not applied to new cells when a style is applied.
|
|
236
|
+
|
|
237
|
+
To keep the API simple, `numbers-parser` packs all styling into a single
|
|
238
|
+
[Style](https://masaccio.github.io/numbers-parser/api/style.html) object. When a document is saved, the attributes
|
|
239
|
+
not stored in a paragraph style are applied to each cell that includes it.
|
|
242
240
|
|
|
243
241
|
Styles are read from cells using the
|
|
244
|
-
[Cell.style](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.Cell.style)
|
|
245
|
-
|
|
242
|
+
[Cell.style](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.Cell.style) property and you can
|
|
243
|
+
add new styles with
|
|
246
244
|
[Document.add_style](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_style).
|
|
247
245
|
|
|
248
246
|
```python
|
|
@@ -272,7 +270,7 @@ internally by the package. Changing a data format for cell has no impact
|
|
|
272
270
|
on any other cells.
|
|
273
271
|
|
|
274
272
|
Cell formats are changed using
|
|
275
|
-
[Table.set_cell_formatting](https://masaccio.github.io/numbers-parser
|
|
273
|
+
[Table.set_cell_formatting()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_formatting):
|
|
276
274
|
|
|
277
275
|
```python
|
|
278
276
|
table.set_cell_formatting(
|
|
@@ -293,9 +291,9 @@ Custom formats are shared across a Document and can be applied to
|
|
|
293
291
|
multiple cells in multiple tables. Editing a custom format changes the
|
|
294
292
|
appearance of data in all cells that share that format. You must first
|
|
295
293
|
add a custom format to the document using
|
|
296
|
-
[Document.add_custom_format](https://masaccio.github.io/numbers-parser
|
|
294
|
+
[Document.add_custom_format()](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_custom_format)
|
|
297
295
|
before assigning it to cells using
|
|
298
|
-
[Table.set_cell_formatting](https://masaccio.github.io/numbers-parser
|
|
296
|
+
[Table.set_cell_formatting()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_formatting):
|
|
299
297
|
|
|
300
298
|
```python
|
|
301
299
|
long_date = doc.add_custom_format(
|
|
@@ -322,13 +320,11 @@ table to allow for drawing borders across multiple cells. Setting the
|
|
|
322
320
|
border of merged cells is not possible unless the edge of the cells is
|
|
323
321
|
at the end of the merged region.
|
|
324
322
|
|
|
325
|
-
Borders are represented using the
|
|
326
|
-
|
|
327
|
-
class that can be initialized with line width, color and line style. The
|
|
323
|
+
Borders are represented using the [Border](https://masaccio.github.io/numbers-parser/api/border.html) class
|
|
324
|
+
that can be initialized with line width, color and line style. The
|
|
328
325
|
current state of a cell border is read using the
|
|
329
|
-
[Cell.border](https://masaccio.github.io/numbers-parser
|
|
330
|
-
|
|
331
|
-
[Table.set_cell_border](https://masaccio.github.io/numbers-parser/#numbers_parser.Table.set_cell_border)
|
|
326
|
+
[Cell.border](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.Cell.border) property
|
|
327
|
+
and [Table.set_cell_border()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_border)
|
|
332
328
|
sets the border for a cell edge or a range of cells.
|
|
333
329
|
|
|
334
330
|
## API
|
|
@@ -400,6 +396,5 @@ Current known limitations of `numbers-parser` are:
|
|
|
400
396
|
|
|
401
397
|
## License
|
|
402
398
|
|
|
403
|
-
All code in this repository is licensed under the [MIT
|
|
404
|
-
License](https://github.com/masaccio/numbers-parser/blob/master/LICENSE.rst)
|
|
399
|
+
All code in this repository is licensed under the [MIT License](https://github.com/masaccio/numbers-parser/blob/master/LICENSE.rst).
|
|
405
400
|
|
|
@@ -157,8 +157,8 @@ Whilst support for writing numbers files has been stable since version
|
|
|
157
157
|
and instead save data to a new file.
|
|
158
158
|
|
|
159
159
|
Cell values are written using
|
|
160
|
-
[Table.write()](https://masaccio.github.io/numbers-parser
|
|
161
|
-
|
|
160
|
+
[Table.write()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.write) and
|
|
161
|
+
`numbers-parser` will automatically create empty rows and columns
|
|
162
162
|
for any cell references that are out of range of the current table.
|
|
163
163
|
|
|
164
164
|
```python
|
|
@@ -171,12 +171,9 @@ table.write("B7", datetime(2020, 12, 25))
|
|
|
171
171
|
doc.save("new-sheet.numbers")
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
-
Additional tables and worksheets can be added to a `Document` before
|
|
175
|
-
|
|
176
|
-
[
|
|
177
|
-
and
|
|
178
|
-
[Sheet.add_table()](https://masaccio.github.io/numbers-parser/#numbers_parser.Sheet.add_table)
|
|
179
|
-
respectively:
|
|
174
|
+
Additional tables and worksheets can be added to a `Document` before saving using
|
|
175
|
+
[Document.add_sheet()](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_sheet) and
|
|
176
|
+
[Sheet.add_table()](https://masaccio.github.io/numbers-parser/api/sheet.html#numbers_parser.Sheet.add_table) respectively:
|
|
180
177
|
|
|
181
178
|
```python
|
|
182
179
|
doc = Document()
|
|
@@ -192,27 +189,28 @@ doc.save("sheet.numbers")
|
|
|
192
189
|
### Styles
|
|
193
190
|
|
|
194
191
|
`numbers_parser` currently only supports paragraph styles and cell
|
|
195
|
-
styles. The following
|
|
192
|
+
styles. The following styles are supported:
|
|
196
193
|
|
|
197
194
|
- font attributes: bold, italic, underline, strikethrough
|
|
198
195
|
- font selection and size
|
|
199
196
|
- text foreground color
|
|
200
197
|
- horizontal and vertical alignment
|
|
201
198
|
- cell background color
|
|
199
|
+
- cell background images
|
|
202
200
|
- cell indents (first line, left, right, and text inset)
|
|
203
201
|
|
|
204
202
|
Numbers conflates style attributes that can be stored in paragraph
|
|
205
203
|
styles (the style menu in the text panel) with the settings that are
|
|
206
204
|
available on the Style tab of the Text panel. Some attributes in Numbers
|
|
207
|
-
are not applied to new cells when a style is applied.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
object. When a document is saved, the attributes
|
|
211
|
-
paragraph style are applied to each cell that includes it.
|
|
205
|
+
are not applied to new cells when a style is applied.
|
|
206
|
+
|
|
207
|
+
To keep the API simple, `numbers-parser` packs all styling into a single
|
|
208
|
+
[Style](https://masaccio.github.io/numbers-parser/api/style.html) object. When a document is saved, the attributes
|
|
209
|
+
not stored in a paragraph style are applied to each cell that includes it.
|
|
212
210
|
|
|
213
211
|
Styles are read from cells using the
|
|
214
|
-
[Cell.style](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.Cell.style)
|
|
215
|
-
|
|
212
|
+
[Cell.style](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.Cell.style) property and you can
|
|
213
|
+
add new styles with
|
|
216
214
|
[Document.add_style](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_style).
|
|
217
215
|
|
|
218
216
|
```python
|
|
@@ -242,7 +240,7 @@ internally by the package. Changing a data format for cell has no impact
|
|
|
242
240
|
on any other cells.
|
|
243
241
|
|
|
244
242
|
Cell formats are changed using
|
|
245
|
-
[Table.set_cell_formatting](https://masaccio.github.io/numbers-parser
|
|
243
|
+
[Table.set_cell_formatting()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_formatting):
|
|
246
244
|
|
|
247
245
|
```python
|
|
248
246
|
table.set_cell_formatting(
|
|
@@ -263,9 +261,9 @@ Custom formats are shared across a Document and can be applied to
|
|
|
263
261
|
multiple cells in multiple tables. Editing a custom format changes the
|
|
264
262
|
appearance of data in all cells that share that format. You must first
|
|
265
263
|
add a custom format to the document using
|
|
266
|
-
[Document.add_custom_format](https://masaccio.github.io/numbers-parser
|
|
264
|
+
[Document.add_custom_format()](https://masaccio.github.io/numbers-parser/api/document.html#numbers_parser.Document.add_custom_format)
|
|
267
265
|
before assigning it to cells using
|
|
268
|
-
[Table.set_cell_formatting](https://masaccio.github.io/numbers-parser
|
|
266
|
+
[Table.set_cell_formatting()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_formatting):
|
|
269
267
|
|
|
270
268
|
```python
|
|
271
269
|
long_date = doc.add_custom_format(
|
|
@@ -292,13 +290,11 @@ table to allow for drawing borders across multiple cells. Setting the
|
|
|
292
290
|
border of merged cells is not possible unless the edge of the cells is
|
|
293
291
|
at the end of the merged region.
|
|
294
292
|
|
|
295
|
-
Borders are represented using the
|
|
296
|
-
|
|
297
|
-
class that can be initialized with line width, color and line style. The
|
|
293
|
+
Borders are represented using the [Border](https://masaccio.github.io/numbers-parser/api/border.html) class
|
|
294
|
+
that can be initialized with line width, color and line style. The
|
|
298
295
|
current state of a cell border is read using the
|
|
299
|
-
[Cell.border](https://masaccio.github.io/numbers-parser
|
|
300
|
-
|
|
301
|
-
[Table.set_cell_border](https://masaccio.github.io/numbers-parser/#numbers_parser.Table.set_cell_border)
|
|
296
|
+
[Cell.border](https://masaccio.github.io/numbers-parser/api/cells.html#numbers_parser.Cell.border) property
|
|
297
|
+
and [Table.set_cell_border()](https://masaccio.github.io/numbers-parser/api/table.html#numbers_parser.Table.set_cell_border)
|
|
302
298
|
sets the border for a cell edge or a range of cells.
|
|
303
299
|
|
|
304
300
|
## API
|
|
@@ -370,5 +366,4 @@ Current known limitations of `numbers-parser` are:
|
|
|
370
366
|
|
|
371
367
|
## License
|
|
372
368
|
|
|
373
|
-
All code in this repository is licensed under the [MIT
|
|
374
|
-
License](https://github.com/masaccio/numbers-parser/blob/master/LICENSE.rst)
|
|
369
|
+
All code in this repository is licensed under the [MIT License](https://github.com/masaccio/numbers-parser/blob/master/LICENSE.rst).
|
|
@@ -12,7 +12,7 @@ name = "numbers-parser"
|
|
|
12
12
|
packages = [{include = "numbers_parser", from = "src"}]
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
repository = "https://github.com/masaccio/numbers-parser"
|
|
15
|
-
version = "4.
|
|
15
|
+
version = "4.9.0"
|
|
16
16
|
|
|
17
17
|
[tool.poetry.scripts]
|
|
18
18
|
cat-numbers = "numbers_parser._cat_numbers:main"
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from collections import namedtuple
|
|
3
|
-
from dataclasses import dataclass
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
4
|
from datetime import datetime as builtin_datetime
|
|
5
5
|
from datetime import timedelta as builtin_timedelta
|
|
6
6
|
from enum import IntEnum
|
|
7
|
+
from os.path import basename
|
|
7
8
|
from typing import Any, List, Tuple, Union
|
|
8
9
|
from warnings import warn
|
|
9
10
|
|
|
@@ -27,6 +28,7 @@ from numbers_parser.constants import (
|
|
|
27
28
|
EMPTY_STORAGE_BUFFER,
|
|
28
29
|
MAX_BASE,
|
|
29
30
|
MAX_SIGNIFICANT_DIGITS,
|
|
31
|
+
ControlFormattingType,
|
|
30
32
|
CustomFormattingType,
|
|
31
33
|
FormattingType,
|
|
32
34
|
FormatType,
|
|
@@ -75,18 +77,43 @@ __all__ = [
|
|
|
75
77
|
|
|
76
78
|
|
|
77
79
|
class BackgroundImage:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
"""
|
|
81
|
+
A named document style that can be applied to cells.
|
|
82
|
+
|
|
83
|
+
.. code-block:: python
|
|
84
|
+
|
|
85
|
+
fh = open("cats.png", mode="rb")
|
|
86
|
+
image_data = fh.read()
|
|
87
|
+
cats_bg = doc.add_style(
|
|
88
|
+
name="Cats",
|
|
89
|
+
bg_image=BackgroundImage(image_data, "cats.png")
|
|
90
|
+
)
|
|
91
|
+
table.write(0, 0, "❤️ cats", style=cats_bg)
|
|
92
|
+
|
|
93
|
+
Currently only standard image files and not 'advanced' image fills are
|
|
94
|
+
supported. Tiling and scaling is not reported back and cannot be changed
|
|
95
|
+
when saving new cells.
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
data: bytes
|
|
100
|
+
Raw image data for a cell background image.
|
|
101
|
+
filename: str
|
|
102
|
+
Path to the image file.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
def __init__(self, data: bytes = None, filename: str = None):
|
|
106
|
+
self._data = data
|
|
107
|
+
self._filename = basename(filename)
|
|
81
108
|
|
|
82
109
|
@property
|
|
83
110
|
def data(self) -> bytes:
|
|
84
|
-
"""The background image as
|
|
111
|
+
"""bytes: The background image as bytes for a cell, or None if no image."""
|
|
85
112
|
return self._data
|
|
86
113
|
|
|
87
114
|
@property
|
|
88
115
|
def filename(self) -> str:
|
|
89
|
-
"""The image filename for a cell, or None if no image."""
|
|
116
|
+
"""str: The image filename for a cell, or None if no image."""
|
|
90
117
|
return self._filename
|
|
91
118
|
|
|
92
119
|
|
|
@@ -184,6 +211,8 @@ class Style:
|
|
|
184
211
|
------
|
|
185
212
|
TypeError:
|
|
186
213
|
If arguments do not match the specified type or for objects have invalid arguments
|
|
214
|
+
IndexError:
|
|
215
|
+
If an image filename already exists in document
|
|
187
216
|
"""
|
|
188
217
|
|
|
189
218
|
alignment: Alignment = DEFAULT_ALIGNMENT_CLASS # : horizontal and vertical alignment
|
|
@@ -230,6 +259,7 @@ class Style:
|
|
|
230
259
|
return [
|
|
231
260
|
"alignment",
|
|
232
261
|
"bg_color",
|
|
262
|
+
"bg_image",
|
|
233
263
|
"first_indent",
|
|
234
264
|
"left_indent",
|
|
235
265
|
"right_indent",
|
|
@@ -273,9 +303,9 @@ class Style:
|
|
|
273
303
|
if not isinstance(self.font_name, str):
|
|
274
304
|
raise TypeError("font name must be a string")
|
|
275
305
|
|
|
276
|
-
for
|
|
277
|
-
if not isinstance(getattr(self,
|
|
278
|
-
raise TypeError(f"{
|
|
306
|
+
for attr in ["bold", "italic", "underline", "strikethrough"]:
|
|
307
|
+
if not isinstance(getattr(self, attr), bool):
|
|
308
|
+
raise TypeError(f"{attr} argument must be boolean")
|
|
279
309
|
|
|
280
310
|
def __setattr__(self, name: str, value: Any) -> None:
|
|
281
311
|
"""Detect changes to cell styles and flag the style for
|
|
@@ -575,8 +605,14 @@ class Cell(Cacheable):
|
|
|
575
605
|
else:
|
|
576
606
|
raise ValueError("Can't determine cell type from type " + type(value).__name__)
|
|
577
607
|
|
|
578
|
-
def _set_formatting(
|
|
579
|
-
self
|
|
608
|
+
def _set_formatting(
|
|
609
|
+
self,
|
|
610
|
+
format_id: int,
|
|
611
|
+
format_type: FormattingType,
|
|
612
|
+
control_id: int = None,
|
|
613
|
+
is_currency: bool = False,
|
|
614
|
+
) -> None:
|
|
615
|
+
self._storage.set_formatting(format_id, format_type, control_id, is_currency)
|
|
580
616
|
|
|
581
617
|
def __init__(self, row: int, col: int, value):
|
|
582
618
|
self._value = value
|
|
@@ -705,7 +741,32 @@ class Cell(Cacheable):
|
|
|
705
741
|
|
|
706
742
|
@property
|
|
707
743
|
def formatted_value(self) -> str:
|
|
708
|
-
"""
|
|
744
|
+
"""
|
|
745
|
+
str: The formatted value of the cell as it appears in Numbers.
|
|
746
|
+
|
|
747
|
+
Interactive elements are converted into a suitable text format where
|
|
748
|
+
supported, or as their number values where there is no suitable
|
|
749
|
+
visual representation. Currently supported mappings are:
|
|
750
|
+
|
|
751
|
+
* Checkboxes are U+2610 (Ballow Box) or U+2611 (Ballot Box with Check)
|
|
752
|
+
* Ratings are their star value represented using (U+2605) (Black Star)
|
|
753
|
+
|
|
754
|
+
.. code-block:: python
|
|
755
|
+
|
|
756
|
+
>>> table = doc.sheets[0].tables[0]
|
|
757
|
+
>>> table.cell(0,0).value
|
|
758
|
+
False
|
|
759
|
+
>>> table.cell(0,0).formatted_value
|
|
760
|
+
'☐'
|
|
761
|
+
>>> table.cell(0,1).value
|
|
762
|
+
True
|
|
763
|
+
>>> table.cell(0,1).formatted_value
|
|
764
|
+
'☑'
|
|
765
|
+
>>> table.cell(1,1).value
|
|
766
|
+
3.0
|
|
767
|
+
>>> table.cell(1,1).formatted_value
|
|
768
|
+
'★★★'
|
|
769
|
+
"""
|
|
709
770
|
if self._storage is None:
|
|
710
771
|
return ""
|
|
711
772
|
else:
|
|
@@ -1079,16 +1140,22 @@ def xl_col_to_name(col, col_abs=False):
|
|
|
1079
1140
|
|
|
1080
1141
|
@dataclass()
|
|
1081
1142
|
class Formatting:
|
|
1082
|
-
|
|
1143
|
+
allow_none: bool = False
|
|
1083
1144
|
base_places: int = 0
|
|
1084
1145
|
base_use_minus_sign: bool = True
|
|
1085
1146
|
base: int = 10
|
|
1147
|
+
control_format: ControlFormattingType = ControlFormattingType.NUMBER
|
|
1086
1148
|
currency_code: str = "GBP"
|
|
1087
1149
|
date_time_format: str = DEFAULT_DATETIME_FORMAT
|
|
1088
1150
|
decimal_places: int = None
|
|
1089
1151
|
fraction_accuracy: FractionAccuracy = FractionAccuracy.THREE
|
|
1152
|
+
increment: float = 1.0
|
|
1153
|
+
maximum: float = 100.0
|
|
1154
|
+
minimum: float = 1.0
|
|
1155
|
+
popup_values: List[str] = field(default_factory=lambda: ["Item 1"])
|
|
1090
1156
|
negative_style: NegativeNumberStyle = NegativeNumberStyle.MINUS
|
|
1091
1157
|
show_thousands_separator: bool = False
|
|
1158
|
+
type: FormattingType = FormattingType.NUMBER
|
|
1092
1159
|
use_accounting_style: bool = False
|
|
1093
1160
|
_format_id = None
|
|
1094
1161
|
|
|
@@ -11,6 +11,8 @@ from pendulum import datetime, duration
|
|
|
11
11
|
|
|
12
12
|
from numbers_parser import __name__ as numbers_parser_name
|
|
13
13
|
from numbers_parser.constants import (
|
|
14
|
+
CHECKBOX_FALSE_VALUE,
|
|
15
|
+
CHECKBOX_TRUE_VALUE,
|
|
14
16
|
CURRENCY_CELL_TYPE,
|
|
15
17
|
CUSTOM_TEXT_PLACEHOLDER,
|
|
16
18
|
DATETIME_FIELD_MAP,
|
|
@@ -21,6 +23,7 @@ from numbers_parser.constants import (
|
|
|
21
23
|
SECONDS_IN_DAY,
|
|
22
24
|
SECONDS_IN_HOUR,
|
|
23
25
|
SECONDS_IN_WEEK,
|
|
26
|
+
STAR_RATING_VALUE,
|
|
24
27
|
CellPadding,
|
|
25
28
|
CellType,
|
|
26
29
|
CustomFormattingType,
|
|
@@ -60,7 +63,7 @@ class CellStorage(Cacheable):
|
|
|
60
63
|
# "cond_style_id",
|
|
61
64
|
# "cond_rule_style_id",
|
|
62
65
|
"formula_id",
|
|
63
|
-
|
|
66
|
+
"control_id",
|
|
64
67
|
"formula_error_id",
|
|
65
68
|
"suggest_id",
|
|
66
69
|
"num_format_id",
|
|
@@ -95,7 +98,7 @@ class CellStorage(Cacheable):
|
|
|
95
98
|
# self.cond_style_id = None
|
|
96
99
|
# self.cond_rule_style_id = None
|
|
97
100
|
self.formula_id = None
|
|
98
|
-
|
|
101
|
+
self.control_id = None
|
|
99
102
|
self.formula_error_id = None
|
|
100
103
|
self.suggest_id = None
|
|
101
104
|
self.num_format_id = None
|
|
@@ -148,9 +151,9 @@ class CellStorage(Cacheable):
|
|
|
148
151
|
if flags & 0x200:
|
|
149
152
|
self.formula_id = unpack("<i", buffer[offset : offset + 4])[0]
|
|
150
153
|
offset += 4
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
if flags & 0x400:
|
|
155
|
+
self.control_id = unpack("<i", buffer[offset : offset + 4])[0]
|
|
156
|
+
offset += 4
|
|
154
157
|
# if flags & 0x800:
|
|
155
158
|
# self.formula_error_id = unpack("<i", buffer[offset : offset + 4])[0]
|
|
156
159
|
# offset += 4
|
|
@@ -158,7 +161,7 @@ class CellStorage(Cacheable):
|
|
|
158
161
|
self.suggest_id = unpack("<i", buffer[offset : offset + 4])[0]
|
|
159
162
|
offset += 4
|
|
160
163
|
# Skip unused flags
|
|
161
|
-
offset += 4 * bin(flags &
|
|
164
|
+
offset += 4 * bin(flags & 0x900).count("1")
|
|
162
165
|
#
|
|
163
166
|
if flags & 0x2000:
|
|
164
167
|
self.num_format_id = unpack("<i", buffer[offset : offset + 4])[0]
|
|
@@ -300,13 +303,15 @@ class CellStorage(Cacheable):
|
|
|
300
303
|
format = self.model.table_format(self.table_id, self.text_format_id)
|
|
301
304
|
elif self.currency_format_id is not None:
|
|
302
305
|
format = self.model.table_format(self.table_id, self.currency_format_id)
|
|
306
|
+
elif self.bool_format_id is not None and self.type == CellType.BOOL:
|
|
307
|
+
format = self.model.table_format(self.table_id, self.bool_format_id)
|
|
303
308
|
elif self.num_format_id is not None:
|
|
304
309
|
format = self.model.table_format(self.table_id, self.num_format_id)
|
|
305
|
-
elif self.bool_format_id is not None:
|
|
306
|
-
format = self.model.table_format(self.table_id, self.bool_format_id)
|
|
307
310
|
else:
|
|
308
311
|
return str(self.value)
|
|
309
312
|
|
|
313
|
+
debug("custom_format: @[%d,%d]: format_type=%s, ", self.row, self.col, format.format_type)
|
|
314
|
+
|
|
310
315
|
if format.HasField("custom_uid"):
|
|
311
316
|
format_uuid = NumbersUUID(format.custom_uid).hex
|
|
312
317
|
format_map = self.model.custom_format_map()
|
|
@@ -336,6 +341,10 @@ class CellStorage(Cacheable):
|
|
|
336
341
|
return format_fraction(self.d128, format)
|
|
337
342
|
elif format.format_type == FormatType.SCIENTIFIC:
|
|
338
343
|
return format_scientific(self.d128, format)
|
|
344
|
+
elif format.format_type == FormatType.CHECKBOX:
|
|
345
|
+
return CHECKBOX_TRUE_VALUE if self.value else CHECKBOX_FALSE_VALUE
|
|
346
|
+
elif format.format_type == FormatType.RATING:
|
|
347
|
+
return STAR_RATING_VALUE * int(self.d128)
|
|
339
348
|
else:
|
|
340
349
|
formatted_value = str(self.value)
|
|
341
350
|
return formatted_value
|
|
@@ -362,6 +371,14 @@ class CellStorage(Cacheable):
|
|
|
362
371
|
|
|
363
372
|
def duration_format(self) -> str:
|
|
364
373
|
format = self.model.table_format(self.table_id, self.duration_format_id)
|
|
374
|
+
debug(
|
|
375
|
+
"duration_format: @[%d,%d]: table_id=%d, duration_format_id=%d, duration_style=%s",
|
|
376
|
+
self.row,
|
|
377
|
+
self.col,
|
|
378
|
+
self.table_id,
|
|
379
|
+
self.duration_format_id,
|
|
380
|
+
format.duration_style,
|
|
381
|
+
)
|
|
365
382
|
|
|
366
383
|
duration_style = format.duration_style
|
|
367
384
|
unit_largest = format.duration_unit_largest
|
|
@@ -431,15 +448,34 @@ class CellStorage(Cacheable):
|
|
|
431
448
|
|
|
432
449
|
return duration_str
|
|
433
450
|
|
|
434
|
-
def
|
|
435
|
-
self,
|
|
451
|
+
def set_formatting(
|
|
452
|
+
self,
|
|
453
|
+
format_id: int,
|
|
454
|
+
format_type: Union[FormattingType, CustomFormattingType],
|
|
455
|
+
control_id: int = None,
|
|
456
|
+
is_currency: bool = False,
|
|
436
457
|
) -> None:
|
|
458
|
+
self.is_currency = is_currency
|
|
437
459
|
if format_type == FormattingType.CURRENCY:
|
|
438
460
|
self.currency_format_id = format_id
|
|
439
|
-
|
|
461
|
+
elif format_type == FormattingType.TICKBOX:
|
|
462
|
+
self.bool_format_id = format_id
|
|
463
|
+
self.control_id = control_id
|
|
464
|
+
elif format_type == FormattingType.RATING:
|
|
465
|
+
self.num_format_id = format_id
|
|
466
|
+
self.control_id = control_id
|
|
467
|
+
elif format_type in [FormattingType.SLIDER, FormattingType.STEPPER]:
|
|
468
|
+
if is_currency:
|
|
469
|
+
self.currency_format_id = format_id
|
|
470
|
+
else:
|
|
471
|
+
self.num_format_id = format_id
|
|
472
|
+
self.control_id = control_id
|
|
473
|
+
elif format_type == FormattingType.POPUP:
|
|
474
|
+
self.text_format_id = format_id
|
|
475
|
+
self.control_id = control_id
|
|
440
476
|
elif format_type in [FormattingType.DATETIME, CustomFormattingType.DATETIME]:
|
|
441
477
|
self.date_format_id = format_id
|
|
442
|
-
elif format_type
|
|
478
|
+
elif format_type in [FormattingType.TEXT, CustomFormattingType.TEXT]:
|
|
443
479
|
self.text_format_id = format_id
|
|
444
480
|
else:
|
|
445
481
|
self.num_format_id = format_id
|