aspose-cells-foss 25.12.1__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.
Files changed (53) hide show
  1. aspose/__init__.py +14 -0
  2. aspose/cells/__init__.py +31 -0
  3. aspose/cells/cell.py +350 -0
  4. aspose/cells/constants.py +44 -0
  5. aspose/cells/converters/__init__.py +13 -0
  6. aspose/cells/converters/csv_converter.py +55 -0
  7. aspose/cells/converters/json_converter.py +46 -0
  8. aspose/cells/converters/markdown_converter.py +453 -0
  9. aspose/cells/drawing/__init__.py +17 -0
  10. aspose/cells/drawing/anchor.py +172 -0
  11. aspose/cells/drawing/collection.py +233 -0
  12. aspose/cells/drawing/image.py +338 -0
  13. aspose/cells/formats.py +80 -0
  14. aspose/cells/formula/__init__.py +10 -0
  15. aspose/cells/formula/evaluator.py +360 -0
  16. aspose/cells/formula/functions.py +433 -0
  17. aspose/cells/formula/tokenizer.py +340 -0
  18. aspose/cells/io/__init__.py +27 -0
  19. aspose/cells/io/csv/__init__.py +8 -0
  20. aspose/cells/io/csv/reader.py +88 -0
  21. aspose/cells/io/csv/writer.py +98 -0
  22. aspose/cells/io/factory.py +138 -0
  23. aspose/cells/io/interfaces.py +48 -0
  24. aspose/cells/io/json/__init__.py +8 -0
  25. aspose/cells/io/json/reader.py +126 -0
  26. aspose/cells/io/json/writer.py +119 -0
  27. aspose/cells/io/md/__init__.py +8 -0
  28. aspose/cells/io/md/reader.py +161 -0
  29. aspose/cells/io/md/writer.py +334 -0
  30. aspose/cells/io/models.py +64 -0
  31. aspose/cells/io/xlsx/__init__.py +9 -0
  32. aspose/cells/io/xlsx/constants.py +312 -0
  33. aspose/cells/io/xlsx/image_writer.py +311 -0
  34. aspose/cells/io/xlsx/reader.py +284 -0
  35. aspose/cells/io/xlsx/writer.py +931 -0
  36. aspose/cells/plugins/__init__.py +6 -0
  37. aspose/cells/plugins/docling_backend/__init__.py +7 -0
  38. aspose/cells/plugins/docling_backend/backend.py +535 -0
  39. aspose/cells/plugins/markitdown_plugin/__init__.py +15 -0
  40. aspose/cells/plugins/markitdown_plugin/plugin.py +128 -0
  41. aspose/cells/range.py +210 -0
  42. aspose/cells/style.py +287 -0
  43. aspose/cells/utils/__init__.py +54 -0
  44. aspose/cells/utils/coordinates.py +68 -0
  45. aspose/cells/utils/exceptions.py +43 -0
  46. aspose/cells/utils/validation.py +102 -0
  47. aspose/cells/workbook.py +352 -0
  48. aspose/cells/worksheet.py +670 -0
  49. aspose_cells_foss-25.12.1.dist-info/METADATA +189 -0
  50. aspose_cells_foss-25.12.1.dist-info/RECORD +53 -0
  51. aspose_cells_foss-25.12.1.dist-info/WHEEL +5 -0
  52. aspose_cells_foss-25.12.1.dist-info/entry_points.txt +2 -0
  53. aspose_cells_foss-25.12.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,433 @@
1
+ """
2
+ Excel Function Library - Built-in functions for formula evaluation.
3
+ """
4
+
5
+ import math
6
+ import datetime
7
+ from typing import Union, Any, List, Callable
8
+ from decimal import Decimal
9
+
10
+
11
+ # Type aliases
12
+ Number = Union[int, float, Decimal]
13
+ Value = Union[Number, str, bool, datetime.datetime, None]
14
+
15
+
16
+ class ExcelError(Exception):
17
+ """Base class for Excel errors."""
18
+ pass
19
+
20
+
21
+ class DivisionByZeroError(ExcelError):
22
+ """#DIV/0! error."""
23
+ def __str__(self):
24
+ return "#DIV/0!"
25
+
26
+
27
+ class ValueErrorExcel(ExcelError):
28
+ """#VALUE! error."""
29
+ def __str__(self):
30
+ return "#VALUE!"
31
+
32
+
33
+ class NumError(ExcelError):
34
+ """#NUM! error."""
35
+ def __str__(self):
36
+ return "#NUM!"
37
+
38
+
39
+ class NameError(ExcelError):
40
+ """#NAME? error."""
41
+ def __str__(self):
42
+ return "#NAME?"
43
+
44
+
45
+ def to_number(value: Value) -> Number:
46
+ """Convert value to number, raising #VALUE! if not possible."""
47
+ if isinstance(value, (int, float, Decimal)):
48
+ return value
49
+ elif isinstance(value, bool):
50
+ return 1 if value else 0
51
+ elif isinstance(value, str):
52
+ try:
53
+ return float(value) if '.' in value else int(value)
54
+ except ValueError:
55
+ raise ValueErrorExcel()
56
+ else:
57
+ raise ValueErrorExcel()
58
+
59
+
60
+ def to_text(value: Value) -> str:
61
+ """Convert value to text."""
62
+ if value is None:
63
+ return ""
64
+ elif isinstance(value, bool):
65
+ return "TRUE" if value else "FALSE"
66
+ else:
67
+ return str(value)
68
+
69
+
70
+ def to_boolean(value: Value) -> bool:
71
+ """Convert value to boolean."""
72
+ if isinstance(value, bool):
73
+ return value
74
+ elif isinstance(value, (int, float, Decimal)):
75
+ return value != 0
76
+ elif isinstance(value, str):
77
+ upper = value.upper()
78
+ if upper == "TRUE":
79
+ return True
80
+ elif upper == "FALSE":
81
+ return False
82
+ else:
83
+ raise ValueErrorExcel()
84
+ else:
85
+ raise ValueErrorExcel()
86
+
87
+
88
+ # Mathematical Functions
89
+ def func_abs(value: Value) -> Number:
90
+ """ABS function - absolute value."""
91
+ return abs(to_number(value))
92
+
93
+
94
+ def func_sum(*args: Value) -> Number:
95
+ """SUM function - sum of values."""
96
+ total = 0
97
+ for arg in args:
98
+ if isinstance(arg, (list, tuple)):
99
+ total += func_sum(*arg)
100
+ else:
101
+ try:
102
+ total += to_number(arg)
103
+ except (ValueErrorExcel, TypeError):
104
+ continue # Skip non-numeric values
105
+ return total
106
+
107
+
108
+ def func_average(*args: Value) -> Number:
109
+ """AVERAGE function - average of values."""
110
+ values = []
111
+ for arg in args:
112
+ if isinstance(arg, (list, tuple)):
113
+ values.extend([v for v in arg if isinstance(v, (int, float, Decimal))])
114
+ else:
115
+ try:
116
+ values.append(to_number(arg))
117
+ except (ValueErrorExcel, TypeError):
118
+ continue
119
+
120
+ if not values:
121
+ raise DivisionByZeroError()
122
+
123
+ return sum(values) / len(values)
124
+
125
+
126
+ def func_count(*args: Value) -> int:
127
+ """COUNT function - count of numeric values."""
128
+ count = 0
129
+ for arg in args:
130
+ if isinstance(arg, (list, tuple)):
131
+ count += func_count(*arg)
132
+ else:
133
+ try:
134
+ to_number(arg)
135
+ count += 1
136
+ except (ValueErrorExcel, TypeError):
137
+ continue
138
+ return count
139
+
140
+
141
+ def func_counta(*args: Value) -> int:
142
+ """COUNTA function - count of non-empty values."""
143
+ count = 0
144
+ for arg in args:
145
+ if isinstance(arg, (list, tuple)):
146
+ count += func_counta(*arg)
147
+ else:
148
+ if arg is not None and arg != "":
149
+ count += 1
150
+ return count
151
+
152
+
153
+ def func_max(*args: Value) -> Number:
154
+ """MAX function - maximum value."""
155
+ values = []
156
+ for arg in args:
157
+ if isinstance(arg, (list, tuple)):
158
+ values.extend([v for v in arg if isinstance(v, (int, float, Decimal))])
159
+ else:
160
+ try:
161
+ values.append(to_number(arg))
162
+ except (ValueErrorExcel, TypeError):
163
+ continue
164
+
165
+ if not values:
166
+ return 0
167
+
168
+ return max(values)
169
+
170
+
171
+ def func_min(*args: Value) -> Number:
172
+ """MIN function - minimum value."""
173
+ values = []
174
+ for arg in args:
175
+ if isinstance(arg, (list, tuple)):
176
+ values.extend([v for v in arg if isinstance(v, (int, float, Decimal))])
177
+ else:
178
+ try:
179
+ values.append(to_number(arg))
180
+ except (ValueErrorExcel, TypeError):
181
+ continue
182
+
183
+ if not values:
184
+ return 0
185
+
186
+ return min(values)
187
+
188
+
189
+ def func_round(number: Value, digits: Value = 0) -> Number:
190
+ """ROUND function - round to specified digits."""
191
+ num = to_number(number)
192
+ dig = int(to_number(digits))
193
+ return round(num, dig)
194
+
195
+
196
+ def func_power(number: Value, power: Value) -> Number:
197
+ """POWER function - raise to power."""
198
+ num = to_number(number)
199
+ pow_val = to_number(power)
200
+ return num ** pow_val
201
+
202
+
203
+ def func_sqrt(number: Value) -> Number:
204
+ """SQRT function - square root."""
205
+ num = to_number(number)
206
+ if num < 0:
207
+ raise NumError()
208
+ return math.sqrt(num)
209
+
210
+
211
+ def func_exp(number: Value) -> Number:
212
+ """EXP function - e raised to power."""
213
+ num = to_number(number)
214
+ return math.exp(num)
215
+
216
+
217
+ def func_ln(number: Value) -> Number:
218
+ """LN function - natural logarithm."""
219
+ num = to_number(number)
220
+ if num <= 0:
221
+ raise NumError()
222
+ return math.log(num)
223
+
224
+
225
+ def func_log10(number: Value) -> Number:
226
+ """LOG10 function - base-10 logarithm."""
227
+ num = to_number(number)
228
+ if num <= 0:
229
+ raise NumError()
230
+ return math.log10(num)
231
+
232
+
233
+ # Trigonometric Functions
234
+ def func_sin(number: Value) -> Number:
235
+ """SIN function."""
236
+ return math.sin(to_number(number))
237
+
238
+
239
+ def func_cos(number: Value) -> Number:
240
+ """COS function."""
241
+ return math.cos(to_number(number))
242
+
243
+
244
+ def func_tan(number: Value) -> Number:
245
+ """TAN function."""
246
+ return math.tan(to_number(number))
247
+
248
+
249
+ def func_pi() -> Number:
250
+ """PI function."""
251
+ return math.pi
252
+
253
+
254
+ # Logical Functions
255
+ def func_if(condition: Value, true_value: Value, false_value: Value = False) -> Value:
256
+ """IF function."""
257
+ try:
258
+ if to_boolean(condition):
259
+ return true_value
260
+ else:
261
+ return false_value
262
+ except ValueErrorExcel:
263
+ return false_value
264
+
265
+
266
+ def func_and(*args: Value) -> bool:
267
+ """AND function."""
268
+ for arg in args:
269
+ if not to_boolean(arg):
270
+ return False
271
+ return True
272
+
273
+
274
+ def func_or(*args: Value) -> bool:
275
+ """OR function."""
276
+ for arg in args:
277
+ if to_boolean(arg):
278
+ return True
279
+ return False
280
+
281
+
282
+ def func_not(value: Value) -> bool:
283
+ """NOT function."""
284
+ return not to_boolean(value)
285
+
286
+
287
+ def func_true() -> bool:
288
+ """TRUE function."""
289
+ return True
290
+
291
+
292
+ def func_false() -> bool:
293
+ """FALSE function."""
294
+ return False
295
+
296
+
297
+ # Text Functions
298
+ def func_concatenate(*args: Value) -> str:
299
+ """CONCATENATE function."""
300
+ return "".join(to_text(arg) for arg in args)
301
+
302
+
303
+ def func_len(text: Value) -> int:
304
+ """LEN function - length of text."""
305
+ return len(to_text(text))
306
+
307
+
308
+ def func_left(text: Value, num_chars: Value = 1) -> str:
309
+ """LEFT function - leftmost characters."""
310
+ text_str = to_text(text)
311
+ num = int(to_number(num_chars))
312
+ return text_str[:num]
313
+
314
+
315
+ def func_right(text: Value, num_chars: Value = 1) -> str:
316
+ """RIGHT function - rightmost characters."""
317
+ text_str = to_text(text)
318
+ num = int(to_number(num_chars))
319
+ return text_str[-num:] if num > 0 else ""
320
+
321
+
322
+ def func_mid(text: Value, start_pos: Value, num_chars: Value) -> str:
323
+ """MID function - substring."""
324
+ text_str = to_text(text)
325
+ start = int(to_number(start_pos)) - 1 # Excel is 1-based
326
+ num = int(to_number(num_chars))
327
+ return text_str[start:start+num]
328
+
329
+
330
+ def func_upper(text: Value) -> str:
331
+ """UPPER function - convert to uppercase."""
332
+ return to_text(text).upper()
333
+
334
+
335
+ def func_lower(text: Value) -> str:
336
+ """LOWER function - convert to lowercase."""
337
+ return to_text(text).lower()
338
+
339
+
340
+ def func_trim(text: Value) -> str:
341
+ """TRIM function - remove extra spaces."""
342
+ return " ".join(to_text(text).split())
343
+
344
+
345
+ # Date Functions
346
+ def func_today() -> datetime.date:
347
+ """TODAY function - current date."""
348
+ return datetime.date.today()
349
+
350
+
351
+ def func_now() -> datetime.datetime:
352
+ """NOW function - current date and time."""
353
+ return datetime.datetime.now()
354
+
355
+
356
+ def func_year(date_value: Value) -> int:
357
+ """YEAR function - year from date."""
358
+ if isinstance(date_value, datetime.datetime):
359
+ return date_value.year
360
+ elif isinstance(date_value, datetime.date):
361
+ return date_value.year
362
+ else:
363
+ raise ValueErrorExcel()
364
+
365
+
366
+ def func_month(date_value: Value) -> int:
367
+ """MONTH function - month from date."""
368
+ if isinstance(date_value, datetime.datetime):
369
+ return date_value.month
370
+ elif isinstance(date_value, datetime.date):
371
+ return date_value.month
372
+ else:
373
+ raise ValueErrorExcel()
374
+
375
+
376
+ def func_day(date_value: Value) -> int:
377
+ """DAY function - day from date."""
378
+ if isinstance(date_value, datetime.datetime):
379
+ return date_value.day
380
+ elif isinstance(date_value, datetime.date):
381
+ return date_value.day
382
+ else:
383
+ raise ValueErrorExcel()
384
+
385
+
386
+ # Registry of all built-in functions
387
+ BUILTIN_FUNCTIONS: dict[str, Callable] = {
388
+ # Math functions
389
+ 'ABS': func_abs,
390
+ 'SUM': func_sum,
391
+ 'AVERAGE': func_average,
392
+ 'COUNT': func_count,
393
+ 'COUNTA': func_counta,
394
+ 'MAX': func_max,
395
+ 'MIN': func_min,
396
+ 'ROUND': func_round,
397
+ 'POWER': func_power,
398
+ 'SQRT': func_sqrt,
399
+ 'EXP': func_exp,
400
+ 'LN': func_ln,
401
+ 'LOG10': func_log10,
402
+
403
+ # Trigonometric
404
+ 'SIN': func_sin,
405
+ 'COS': func_cos,
406
+ 'TAN': func_tan,
407
+ 'PI': func_pi,
408
+
409
+ # Logical
410
+ 'IF': func_if,
411
+ 'AND': func_and,
412
+ 'OR': func_or,
413
+ 'NOT': func_not,
414
+ 'TRUE': func_true,
415
+ 'FALSE': func_false,
416
+
417
+ # Text
418
+ 'CONCATENATE': func_concatenate,
419
+ 'LEN': func_len,
420
+ 'LEFT': func_left,
421
+ 'RIGHT': func_right,
422
+ 'MID': func_mid,
423
+ 'UPPER': func_upper,
424
+ 'LOWER': func_lower,
425
+ 'TRIM': func_trim,
426
+
427
+ # Date
428
+ 'TODAY': func_today,
429
+ 'NOW': func_now,
430
+ 'YEAR': func_year,
431
+ 'MONTH': func_month,
432
+ 'DAY': func_day,
433
+ }