aspose-cells-foss 25.12.1__py3-none-any.whl → 26.2.2__py3-none-any.whl
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.
- aspose_cells/__init__.py +88 -0
- aspose_cells/auto_filter.py +527 -0
- aspose_cells/cell.py +483 -0
- aspose_cells/cell_value_handler.py +319 -0
- aspose_cells/cells.py +779 -0
- aspose_cells/cfb_handler.py +445 -0
- aspose_cells/cfb_writer.py +659 -0
- aspose_cells/cfb_writer_minimal.py +337 -0
- aspose_cells/comment_xml.py +475 -0
- aspose_cells/conditional_format.py +1185 -0
- aspose_cells/csv_handler.py +690 -0
- aspose_cells/data_validation.py +911 -0
- aspose_cells/document_properties.py +356 -0
- aspose_cells/encryption_crypto.py +247 -0
- aspose_cells/encryption_params.py +138 -0
- aspose_cells/hyperlink.py +372 -0
- aspose_cells/json_handler.py +185 -0
- aspose_cells/markdown_handler.py +583 -0
- aspose_cells/shared_strings.py +101 -0
- aspose_cells/style.py +841 -0
- aspose_cells/workbook.py +499 -0
- aspose_cells/workbook_hash_password.py +68 -0
- aspose_cells/workbook_properties.py +712 -0
- aspose_cells/worksheet.py +570 -0
- aspose_cells/worksheet_properties.py +1239 -0
- aspose_cells/xlsx_encryptor.py +403 -0
- aspose_cells/xml_autofilter_loader.py +195 -0
- aspose_cells/xml_autofilter_saver.py +173 -0
- aspose_cells/xml_conditional_format_loader.py +215 -0
- aspose_cells/xml_conditional_format_saver.py +351 -0
- aspose_cells/xml_datavalidation_loader.py +239 -0
- aspose_cells/xml_datavalidation_saver.py +245 -0
- aspose_cells/xml_hyperlink_handler.py +323 -0
- aspose_cells/xml_loader.py +986 -0
- aspose_cells/xml_properties_loader.py +512 -0
- aspose_cells/xml_properties_saver.py +607 -0
- aspose_cells/xml_saver.py +1306 -0
- aspose_cells_foss-26.2.2.dist-info/METADATA +190 -0
- aspose_cells_foss-26.2.2.dist-info/RECORD +41 -0
- {aspose_cells_foss-25.12.1.dist-info → aspose_cells_foss-26.2.2.dist-info}/WHEEL +1 -1
- aspose_cells_foss-26.2.2.dist-info/top_level.txt +1 -0
- aspose/__init__.py +0 -14
- aspose/cells/__init__.py +0 -31
- aspose/cells/cell.py +0 -350
- aspose/cells/constants.py +0 -44
- aspose/cells/converters/__init__.py +0 -13
- aspose/cells/converters/csv_converter.py +0 -55
- aspose/cells/converters/json_converter.py +0 -46
- aspose/cells/converters/markdown_converter.py +0 -453
- aspose/cells/drawing/__init__.py +0 -17
- aspose/cells/drawing/anchor.py +0 -172
- aspose/cells/drawing/collection.py +0 -233
- aspose/cells/drawing/image.py +0 -338
- aspose/cells/formats.py +0 -80
- aspose/cells/formula/__init__.py +0 -10
- aspose/cells/formula/evaluator.py +0 -360
- aspose/cells/formula/functions.py +0 -433
- aspose/cells/formula/tokenizer.py +0 -340
- aspose/cells/io/__init__.py +0 -27
- aspose/cells/io/csv/__init__.py +0 -8
- aspose/cells/io/csv/reader.py +0 -88
- aspose/cells/io/csv/writer.py +0 -98
- aspose/cells/io/factory.py +0 -138
- aspose/cells/io/interfaces.py +0 -48
- aspose/cells/io/json/__init__.py +0 -8
- aspose/cells/io/json/reader.py +0 -126
- aspose/cells/io/json/writer.py +0 -119
- aspose/cells/io/md/__init__.py +0 -8
- aspose/cells/io/md/reader.py +0 -161
- aspose/cells/io/md/writer.py +0 -334
- aspose/cells/io/models.py +0 -64
- aspose/cells/io/xlsx/__init__.py +0 -9
- aspose/cells/io/xlsx/constants.py +0 -312
- aspose/cells/io/xlsx/image_writer.py +0 -311
- aspose/cells/io/xlsx/reader.py +0 -284
- aspose/cells/io/xlsx/writer.py +0 -931
- aspose/cells/plugins/__init__.py +0 -6
- aspose/cells/plugins/docling_backend/__init__.py +0 -7
- aspose/cells/plugins/docling_backend/backend.py +0 -535
- aspose/cells/plugins/markitdown_plugin/__init__.py +0 -15
- aspose/cells/plugins/markitdown_plugin/plugin.py +0 -128
- aspose/cells/range.py +0 -210
- aspose/cells/style.py +0 -287
- aspose/cells/utils/__init__.py +0 -54
- aspose/cells/utils/coordinates.py +0 -68
- aspose/cells/utils/exceptions.py +0 -43
- aspose/cells/utils/validation.py +0 -102
- aspose/cells/workbook.py +0 -352
- aspose/cells/worksheet.py +0 -670
- aspose_cells_foss-25.12.1.dist-info/METADATA +0 -189
- aspose_cells_foss-25.12.1.dist-info/RECORD +0 -53
- aspose_cells_foss-25.12.1.dist-info/entry_points.txt +0 -2
- aspose_cells_foss-25.12.1.dist-info/top_level.txt +0 -1
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Aspose.Cells for Python - Cell Value Handler Module
|
|
3
|
+
|
|
4
|
+
This module provides comprehensive cell value import/export functionality according to ECMA-376 specification.
|
|
5
|
+
It handles all cell value data types: shared strings, inline strings, numeric, boolean, error, and formula.
|
|
6
|
+
|
|
7
|
+
ECMA-376 Reference:
|
|
8
|
+
- Part 1, Section 18.3.1.4 - cell (Cell)
|
|
9
|
+
- Part 1, Section 18.3.1.16 - f (Formula)
|
|
10
|
+
- Part 1, Section 18.3.1.96 - v (Cell Value)
|
|
11
|
+
- Part 1, Section 18.3.1.53 - is (Rich Text Inline)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from datetime import datetime, date, time
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CellValueHandler:
|
|
18
|
+
"""
|
|
19
|
+
Handles cell value import and export operations according to ECMA-376 specification.
|
|
20
|
+
|
|
21
|
+
This class provides methods to:
|
|
22
|
+
- Import cell values from XML elements
|
|
23
|
+
- Export cell values to XML elements
|
|
24
|
+
- Determine cell type attributes
|
|
25
|
+
- Format values for XML output
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
# ECMA-376 Cell Type Constants
|
|
29
|
+
TYPE_SHARED_STRING = 's' # Shared string index
|
|
30
|
+
TYPE_INLINE_STRING = 'str' # Inline string
|
|
31
|
+
TYPE_NUMBER = 'n' # Number (default)
|
|
32
|
+
TYPE_BOOLEAN = 'b' # Boolean
|
|
33
|
+
TYPE_ERROR = 'e' # Error
|
|
34
|
+
|
|
35
|
+
# ECMA-376 Error Values
|
|
36
|
+
ERROR_NULL = '#NULL!'
|
|
37
|
+
ERROR_DIV_0 = '#DIV/0!'
|
|
38
|
+
ERROR_VALUE = '#VALUE!'
|
|
39
|
+
ERROR_REF = '#REF!'
|
|
40
|
+
ERROR_NAME = '#NAME?'
|
|
41
|
+
ERROR_NUM = '#NUM!'
|
|
42
|
+
ERROR_NA = '#N/A'
|
|
43
|
+
|
|
44
|
+
# Valid error values according to ECMA-376
|
|
45
|
+
VALID_ERRORS = {
|
|
46
|
+
ERROR_NULL, ERROR_DIV_0, ERROR_VALUE, ERROR_REF,
|
|
47
|
+
ERROR_NAME, ERROR_NUM, ERROR_NA
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def get_cell_type(value):
|
|
52
|
+
"""
|
|
53
|
+
Determines the ECMA-376 cell type attribute for a given value.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
value: The cell value (can be None, int, float, str, bool, datetime, date, time)
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
str: The ECMA-376 cell type attribute ('s', 'str', 'n', 'b', 'e', or None for default)
|
|
60
|
+
|
|
61
|
+
Examples:
|
|
62
|
+
>>> CellValueHandler.get_cell_type("Hello")
|
|
63
|
+
's'
|
|
64
|
+
>>> CellValueHandler.get_cell_type(42)
|
|
65
|
+
None # Defaults to 'n' (number)
|
|
66
|
+
>>> CellValueHandler.get_cell_type(True)
|
|
67
|
+
'b'
|
|
68
|
+
>>> CellValueHandler.get_cell_type("#N/A")
|
|
69
|
+
'e'
|
|
70
|
+
"""
|
|
71
|
+
if value is None:
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
# Check for error values first (strings that match error patterns)
|
|
75
|
+
if isinstance(value, str) and value in CellValueHandler.VALID_ERRORS:
|
|
76
|
+
return CellValueHandler.TYPE_ERROR
|
|
77
|
+
|
|
78
|
+
# Boolean values
|
|
79
|
+
if isinstance(value, bool):
|
|
80
|
+
return CellValueHandler.TYPE_BOOLEAN
|
|
81
|
+
|
|
82
|
+
# Numeric values (default type, can be omitted)
|
|
83
|
+
if isinstance(value, (int, float)):
|
|
84
|
+
return None # Default to 'n'
|
|
85
|
+
|
|
86
|
+
# Date/time values (stored as numbers in Excel)
|
|
87
|
+
if isinstance(value, (datetime, date, time)):
|
|
88
|
+
return None # Stored as numbers
|
|
89
|
+
|
|
90
|
+
# String values
|
|
91
|
+
if isinstance(value, str):
|
|
92
|
+
# Check if string represents a boolean
|
|
93
|
+
if value.upper() in ('TRUE', 'FALSE'):
|
|
94
|
+
return CellValueHandler.TYPE_BOOLEAN
|
|
95
|
+
# Check if string represents an error
|
|
96
|
+
if value.upper() in (e.upper() for e in CellValueHandler.VALID_ERRORS):
|
|
97
|
+
return CellValueHandler.TYPE_ERROR
|
|
98
|
+
# Regular string - use shared string type
|
|
99
|
+
return CellValueHandler.TYPE_SHARED_STRING
|
|
100
|
+
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def format_value_for_xml(value, cell_type=None):
|
|
105
|
+
"""
|
|
106
|
+
Formats a cell value for XML output according to ECMA-376 specification.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
value: The cell value to format
|
|
110
|
+
cell_type (str, optional): The cell type attribute. If None, will be determined automatically.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
tuple: (formatted_value_str, cell_type) - The formatted value string and cell type
|
|
114
|
+
|
|
115
|
+
Examples:
|
|
116
|
+
>>> CellValueHandler.format_value_for_xml("Hello")
|
|
117
|
+
('0', 's') # Index into shared strings table
|
|
118
|
+
>>> CellValueHandler.format_value_for_xml(42.5)
|
|
119
|
+
('42.5', None)
|
|
120
|
+
>>> CellValueHandler.format_value_for_xml(True)
|
|
121
|
+
('1', 'b')
|
|
122
|
+
>>> CellValueHandler.format_value_for_xml("#N/A")
|
|
123
|
+
('#N/A', 'e')
|
|
124
|
+
"""
|
|
125
|
+
if value is None:
|
|
126
|
+
return (None, None)
|
|
127
|
+
|
|
128
|
+
# Determine cell type if not provided
|
|
129
|
+
if cell_type is None:
|
|
130
|
+
cell_type = CellValueHandler.get_cell_type(value)
|
|
131
|
+
|
|
132
|
+
# Format based on type
|
|
133
|
+
if cell_type == CellValueHandler.TYPE_BOOLEAN:
|
|
134
|
+
# Boolean: 1 for True, 0 for False
|
|
135
|
+
return ('1' if value else '0', cell_type)
|
|
136
|
+
|
|
137
|
+
elif cell_type == CellValueHandler.TYPE_ERROR:
|
|
138
|
+
# Error: use the error string as-is
|
|
139
|
+
return (value, cell_type)
|
|
140
|
+
|
|
141
|
+
elif cell_type == CellValueHandler.TYPE_SHARED_STRING:
|
|
142
|
+
# Shared string: return the string itself (index will be assigned later)
|
|
143
|
+
return (value, cell_type)
|
|
144
|
+
|
|
145
|
+
elif cell_type == CellValueHandler.TYPE_INLINE_STRING:
|
|
146
|
+
# Inline string: return the string as-is
|
|
147
|
+
return (value, cell_type)
|
|
148
|
+
|
|
149
|
+
else:
|
|
150
|
+
# Number (default type)
|
|
151
|
+
if isinstance(value, (datetime, date, time)):
|
|
152
|
+
# Convert date/time to Excel serial date number
|
|
153
|
+
serial_date = CellValueHandler._datetime_to_excel_serial(value)
|
|
154
|
+
return (str(serial_date), None)
|
|
155
|
+
else:
|
|
156
|
+
# Regular number
|
|
157
|
+
return (str(value), None)
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def parse_value_from_xml(value_str, cell_type, shared_strings=None):
|
|
161
|
+
"""
|
|
162
|
+
Parses a cell value from XML according to ECMA-376 specification.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
value_str (str): The value string from XML <v> element
|
|
166
|
+
cell_type (str): The cell type attribute ('s', 'str', 'n', 'b', 'e', or None)
|
|
167
|
+
shared_strings (list, optional): List of shared strings for type 's'
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
The parsed value (int, float, str, bool, or None)
|
|
171
|
+
|
|
172
|
+
Examples:
|
|
173
|
+
>>> CellValueHandler.parse_value_from_xml("42", None)
|
|
174
|
+
42
|
|
175
|
+
>>> CellValueHandler.parse_value_from_xml("0", "b")
|
|
176
|
+
False
|
|
177
|
+
>>> CellValueHandler.parse_value_from_xml("5", "s", ["Hello", "World"])
|
|
178
|
+
'World'
|
|
179
|
+
>>> CellValueHandler.parse_value_from_xml("#N/A", "e")
|
|
180
|
+
'#N/A'
|
|
181
|
+
"""
|
|
182
|
+
if value_str is None or value_str == '':
|
|
183
|
+
return None
|
|
184
|
+
|
|
185
|
+
# Default to number type if not specified
|
|
186
|
+
if cell_type is None:
|
|
187
|
+
cell_type = CellValueHandler.TYPE_NUMBER
|
|
188
|
+
|
|
189
|
+
# Parse based on type
|
|
190
|
+
if cell_type == CellValueHandler.TYPE_SHARED_STRING:
|
|
191
|
+
# Shared string: value_str is an index into shared strings table
|
|
192
|
+
if shared_strings is not None:
|
|
193
|
+
try:
|
|
194
|
+
index = int(value_str)
|
|
195
|
+
if 0 <= index < len(shared_strings):
|
|
196
|
+
return shared_strings[index]
|
|
197
|
+
except (ValueError, IndexError):
|
|
198
|
+
pass
|
|
199
|
+
return value_str
|
|
200
|
+
|
|
201
|
+
elif cell_type == CellValueHandler.TYPE_INLINE_STRING:
|
|
202
|
+
# Inline string: value_str is the actual string
|
|
203
|
+
return value_str
|
|
204
|
+
|
|
205
|
+
elif cell_type == CellValueHandler.TYPE_BOOLEAN:
|
|
206
|
+
# Boolean: 1 for True, 0 for False
|
|
207
|
+
return bool(int(value_str))
|
|
208
|
+
|
|
209
|
+
elif cell_type == CellValueHandler.TYPE_ERROR:
|
|
210
|
+
# Error: value_str is the error string
|
|
211
|
+
return value_str
|
|
212
|
+
|
|
213
|
+
else:
|
|
214
|
+
# Number (default type)
|
|
215
|
+
try:
|
|
216
|
+
if '.' in value_str or 'e' in value_str.lower():
|
|
217
|
+
return float(value_str)
|
|
218
|
+
else:
|
|
219
|
+
return int(value_str)
|
|
220
|
+
except ValueError:
|
|
221
|
+
return value_str
|
|
222
|
+
|
|
223
|
+
@staticmethod
|
|
224
|
+
def _datetime_to_excel_serial(dt):
|
|
225
|
+
"""
|
|
226
|
+
Converts a datetime/date/time object to Excel serial date number.
|
|
227
|
+
|
|
228
|
+
Excel stores dates as serial numbers where:
|
|
229
|
+
- 1 = January 1, 1900 (incorrectly treats 1900 as a leap year)
|
|
230
|
+
- 2 = January 2, 1900
|
|
231
|
+
- Fractional part represents time of day
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
dt: datetime, date, or time object
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
float: Excel serial date number
|
|
238
|
+
"""
|
|
239
|
+
# Excel base date (January 1, 1900)
|
|
240
|
+
excel_epoch = datetime(1899, 12, 30) # Adjusted for Excel's 1900 leap year bug
|
|
241
|
+
|
|
242
|
+
if isinstance(dt, time):
|
|
243
|
+
# Time only: convert to datetime with base date
|
|
244
|
+
dt = datetime.combine(datetime.today().date(), dt)
|
|
245
|
+
|
|
246
|
+
if isinstance(dt, date) and not isinstance(dt, datetime):
|
|
247
|
+
# Date only: convert to datetime at midnight
|
|
248
|
+
dt = datetime.combine(dt, time.min)
|
|
249
|
+
|
|
250
|
+
# Calculate difference in days
|
|
251
|
+
delta = dt - excel_epoch
|
|
252
|
+
serial_date = delta.days + delta.seconds / 86400.0
|
|
253
|
+
|
|
254
|
+
return serial_date
|
|
255
|
+
|
|
256
|
+
@staticmethod
|
|
257
|
+
def excel_serial_to_datetime(serial_date):
|
|
258
|
+
"""
|
|
259
|
+
Converts an Excel serial date number to a datetime object.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
serial_date (float): Excel serial date number
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
datetime: The corresponding datetime object
|
|
266
|
+
"""
|
|
267
|
+
# Excel base date (January 1, 1900)
|
|
268
|
+
excel_epoch = datetime(1899, 12, 30) # Adjusted for Excel's 1900 leap year bug
|
|
269
|
+
|
|
270
|
+
# Calculate datetime from serial
|
|
271
|
+
days = int(serial_date)
|
|
272
|
+
fraction = serial_date - days
|
|
273
|
+
seconds = int(fraction * 86400)
|
|
274
|
+
|
|
275
|
+
dt = excel_epoch + timedelta(days=days, seconds=seconds)
|
|
276
|
+
return dt
|
|
277
|
+
|
|
278
|
+
@staticmethod
|
|
279
|
+
def is_error_value(value):
|
|
280
|
+
"""
|
|
281
|
+
Checks if a value is a valid ECMA-376 error value.
|
|
282
|
+
|
|
283
|
+
Args:
|
|
284
|
+
value: The value to check
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
bool: True if the value is a valid error value, False otherwise
|
|
288
|
+
"""
|
|
289
|
+
return isinstance(value, str) and value in CellValueHandler.VALID_ERRORS
|
|
290
|
+
|
|
291
|
+
@staticmethod
|
|
292
|
+
def get_error_type(value):
|
|
293
|
+
"""
|
|
294
|
+
Returns the error type name for a given error value.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
value: The error value string
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
str: The error type name or None if not a valid error
|
|
301
|
+
"""
|
|
302
|
+
if not CellValueHandler.is_error_value(value):
|
|
303
|
+
return None
|
|
304
|
+
|
|
305
|
+
error_map = {
|
|
306
|
+
CellValueHandler.ERROR_NULL: 'NULL',
|
|
307
|
+
CellValueHandler.ERROR_DIV_0: 'DIV_0',
|
|
308
|
+
CellValueHandler.ERROR_VALUE: 'VALUE',
|
|
309
|
+
CellValueHandler.ERROR_REF: 'REF',
|
|
310
|
+
CellValueHandler.ERROR_NAME: 'NAME',
|
|
311
|
+
CellValueHandler.ERROR_NUM: 'NUM',
|
|
312
|
+
CellValueHandler.ERROR_NA: 'NA'
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return error_map.get(value)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
# Import timedelta for datetime conversion
|
|
319
|
+
from datetime import timedelta
|