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
aspose/cells/range.py ADDED
@@ -0,0 +1,210 @@
1
+ """
2
+ Range implementation for operating on multiple cells as a group.
3
+ """
4
+
5
+ from typing import List, Iterator, Tuple, Union, TYPE_CHECKING
6
+ from .formats import CellValue
7
+ from .utils import parse_range, InvalidCoordinateError
8
+ from .style import Style, Font, Fill
9
+
10
+ if TYPE_CHECKING:
11
+ from .worksheet import Worksheet
12
+ from .cell import Cell
13
+
14
+
15
+ class Range:
16
+ """Excel range representing a rectangular area of cells."""
17
+
18
+ def __init__(self, worksheet: 'Worksheet', range_string: str):
19
+ self._worksheet = worksheet
20
+ self._range_string = range_string.upper()
21
+
22
+ try:
23
+ (self._start_row, self._start_col), (self._end_row, self._end_col) = parse_range(range_string)
24
+ except Exception as e:
25
+ raise InvalidCoordinateError(f"Invalid range format: {range_string}") from e
26
+
27
+ # Ensure start <= end
28
+ if self._start_row > self._end_row:
29
+ self._start_row, self._end_row = self._end_row, self._start_row
30
+ if self._start_col > self._end_col:
31
+ self._start_col, self._end_col = self._end_col, self._start_col
32
+
33
+ @property
34
+ def coordinate(self) -> str:
35
+ """Range coordinate string."""
36
+ return self._range_string
37
+
38
+ @property
39
+ def min_row(self) -> int:
40
+ """Minimum row in range."""
41
+ return self._start_row
42
+
43
+ @property
44
+ def max_row(self) -> int:
45
+ """Maximum row in range."""
46
+ return self._end_row
47
+
48
+ @property
49
+ def min_column(self) -> int:
50
+ """Minimum column in range."""
51
+ return self._start_col
52
+
53
+ @property
54
+ def max_column(self) -> int:
55
+ """Maximum column in range."""
56
+ return self._end_col
57
+
58
+ @property
59
+ def row_count(self) -> int:
60
+ """Number of rows in range."""
61
+ return self._end_row - self._start_row + 1
62
+
63
+ @property
64
+ def column_count(self) -> int:
65
+ """Number of columns in range."""
66
+ return self._end_col - self._start_col + 1
67
+
68
+ @property
69
+ def size(self) -> Tuple[int, int]:
70
+ """Range size as (rows, columns)."""
71
+ return self.row_count, self.column_count
72
+
73
+ def cells(self) -> Iterator['Cell']:
74
+ """Iterate over all cells in range."""
75
+ for row in range(self._start_row, self._end_row + 1):
76
+ for col in range(self._start_col, self._end_col + 1):
77
+ yield self._worksheet.cell(row, col)
78
+
79
+ def rows_iter(self) -> Iterator[List['Cell']]:
80
+ """Iterate over rows of cells."""
81
+ for row in range(self._start_row, self._end_row + 1):
82
+ row_cells = []
83
+ for col in range(self._start_col, self._end_col + 1):
84
+ row_cells.append(self._worksheet.cell(row, col))
85
+ yield row_cells
86
+
87
+ def columns_iter(self) -> Iterator[List['Cell']]:
88
+ """Iterate over columns of cells."""
89
+ for col in range(self._start_col, self._end_col + 1):
90
+ col_cells = []
91
+ for row in range(self._start_row, self._end_row + 1):
92
+ col_cells.append(self._worksheet.cell(row, col))
93
+ yield col_cells
94
+
95
+ def rows(self) -> Iterator[List['Cell']]:
96
+ """Iterate over rows of cells (alias for rows_iter for test compatibility)."""
97
+ return self.rows_iter()
98
+
99
+ def columns(self) -> Iterator[List['Cell']]:
100
+ """Iterate over columns of cells (alias for columns_iter for test compatibility)."""
101
+ return self.columns_iter()
102
+
103
+ @property
104
+ def values(self) -> List[List[CellValue]]:
105
+ """Get all values as nested list."""
106
+ result = []
107
+ for row in range(self._start_row, self._end_row + 1):
108
+ row_values = []
109
+ for col in range(self._start_col, self._end_col + 1):
110
+ cell = self._worksheet.cell(row, col)
111
+ row_values.append(cell.value)
112
+ result.append(row_values)
113
+ return result
114
+
115
+ @values.setter
116
+ def values(self, data: Union[List[List[CellValue]], List[CellValue], CellValue]):
117
+ """Set values from nested list or single value."""
118
+ if not isinstance(data, list):
119
+ # Single value - apply to all cells
120
+ for cell in self.cells():
121
+ cell.value = data
122
+ return
123
+
124
+ if not data:
125
+ return
126
+
127
+ # Check if it's a list of lists (2D) or single list (1D)
128
+ if isinstance(data[0], list):
129
+ # 2D data
130
+ for row_idx, row_data in enumerate(data):
131
+ if row_idx >= self.row_count:
132
+ break
133
+ for col_idx, value in enumerate(row_data):
134
+ if col_idx >= self.column_count:
135
+ break
136
+ cell = self._worksheet.cell(
137
+ self._start_row + row_idx,
138
+ self._start_col + col_idx
139
+ )
140
+ cell.value = value
141
+ else:
142
+ # 1D data - fill row by row
143
+ flat_index = 0
144
+ for row in range(self._start_row, self._end_row + 1):
145
+ for col in range(self._start_col, self._end_col + 1):
146
+ if flat_index >= len(data):
147
+ return
148
+ cell = self._worksheet.cell(row, col)
149
+ cell.value = data[flat_index]
150
+ flat_index += 1
151
+
152
+ @property
153
+ def font(self) -> Font:
154
+ """Get font of first cell (for styling entire range)."""
155
+ first_cell = self._worksheet.cell(self._start_row, self._start_col)
156
+ return first_cell.font
157
+
158
+ @font.setter
159
+ def font(self, value: Font):
160
+ """Apply font to entire range."""
161
+ for cell in self.cells():
162
+ cell.style.font = value.copy()
163
+
164
+ @property
165
+ def fill(self) -> Fill:
166
+ """Get fill of first cell (for styling entire range)."""
167
+ first_cell = self._worksheet.cell(self._start_row, self._start_col)
168
+ return first_cell.fill
169
+
170
+ @fill.setter
171
+ def fill(self, value: Fill):
172
+ """Apply fill to entire range."""
173
+ for cell in self.cells():
174
+ cell.style.fill = value.copy()
175
+
176
+ def apply_style(self, style: Style):
177
+ """Apply complete style to entire range."""
178
+ for cell in self.cells():
179
+ cell.style = style.copy()
180
+
181
+ def clear(self):
182
+ """Clear all values and formatting in range."""
183
+ for cell in self.cells():
184
+ cell.clear()
185
+
186
+ def merge(self):
187
+ """Mark range for merging (implementation depends on writer)."""
188
+ if hasattr(self._worksheet, '_merged_ranges'):
189
+ self._worksheet._merged_ranges.add(self._range_string)
190
+
191
+ def unmerge(self):
192
+ """Unmerge previously merged range."""
193
+ if hasattr(self._worksheet, '_merged_ranges'):
194
+ self._worksheet._merged_ranges.discard(self._range_string)
195
+
196
+ def __str__(self) -> str:
197
+ """String representation."""
198
+ return f"Range({self._range_string})"
199
+
200
+ def __repr__(self) -> str:
201
+ """Debug representation."""
202
+ return f"Range('{self._range_string}', {self.row_count}x{self.column_count})"
203
+
204
+ def __iter__(self) -> Iterator['Cell']:
205
+ """Iterate over cells."""
206
+ return self.cells()
207
+
208
+ def __len__(self) -> int:
209
+ """Number of cells in range."""
210
+ return self.row_count * self.column_count
aspose/cells/style.py ADDED
@@ -0,0 +1,287 @@
1
+ """
2
+ Simplified styling system for Excel cells and ranges.
3
+ """
4
+
5
+ from typing import Optional, Union
6
+
7
+
8
+ class Font:
9
+ """Font styling properties."""
10
+
11
+ def __init__(self):
12
+ self.name: str = "Calibri"
13
+ self.size: Union[int, float] = 11
14
+ self.bold: bool = False
15
+ self.italic: bool = False
16
+ self.underline: bool = False
17
+ self.color: str = "black"
18
+
19
+ def copy(self) -> 'Font':
20
+ """Create a copy of this font."""
21
+ new_font = Font()
22
+ new_font.name = self.name
23
+ new_font.size = self.size
24
+ new_font.bold = self.bold
25
+ new_font.italic = self.italic
26
+ new_font.underline = self.underline
27
+ new_font.color = self.color
28
+ return new_font
29
+
30
+
31
+ class Fill:
32
+ """Fill/background styling properties."""
33
+
34
+ def __init__(self):
35
+ self.color: str = "white"
36
+ self.pattern: str = "none"
37
+ self.gradient: Optional[str] = None
38
+
39
+ def copy(self) -> 'Fill':
40
+ """Create a copy of this fill."""
41
+ new_fill = Fill()
42
+ new_fill.color = self.color
43
+ new_fill.pattern = self.pattern
44
+ new_fill.gradient = self.gradient
45
+ return new_fill
46
+
47
+
48
+ class BorderSide:
49
+ """Individual border side styling."""
50
+
51
+ def __init__(self):
52
+ self.style: str = "none" # none, thin, thick, medium, dashed, dotted, double
53
+ self.color: str = "black"
54
+
55
+ def copy(self) -> 'BorderSide':
56
+ """Create a copy of this border side."""
57
+ new_side = BorderSide()
58
+ new_side.style = self.style
59
+ new_side.color = self.color
60
+ return new_side
61
+
62
+
63
+ class Border:
64
+ """Comprehensive border styling properties."""
65
+
66
+ def __init__(self):
67
+ self._left: Optional[BorderSide] = None
68
+ self._right: Optional[BorderSide] = None
69
+ self._top: Optional[BorderSide] = None
70
+ self._bottom: Optional[BorderSide] = None
71
+ self._diagonal: Optional[BorderSide] = None
72
+ self._diagonal_up: bool = False
73
+ self._diagonal_down: bool = False
74
+
75
+ @property
76
+ def left(self) -> BorderSide:
77
+ """Get or create left border."""
78
+ if self._left is None:
79
+ self._left = BorderSide()
80
+ return self._left
81
+
82
+ @left.setter
83
+ def left(self, value: BorderSide):
84
+ """Set left border."""
85
+ self._left = value
86
+
87
+ @property
88
+ def right(self) -> BorderSide:
89
+ """Get or create right border."""
90
+ if self._right is None:
91
+ self._right = BorderSide()
92
+ return self._right
93
+
94
+ @right.setter
95
+ def right(self, value: BorderSide):
96
+ """Set right border."""
97
+ self._right = value
98
+
99
+ @property
100
+ def top(self) -> BorderSide:
101
+ """Get or create top border."""
102
+ if self._top is None:
103
+ self._top = BorderSide()
104
+ return self._top
105
+
106
+ @top.setter
107
+ def top(self, value: BorderSide):
108
+ """Set top border."""
109
+ self._top = value
110
+
111
+ @property
112
+ def bottom(self) -> BorderSide:
113
+ """Get or create bottom border."""
114
+ if self._bottom is None:
115
+ self._bottom = BorderSide()
116
+ return self._bottom
117
+
118
+ @bottom.setter
119
+ def bottom(self, value: BorderSide):
120
+ """Set bottom border."""
121
+ self._bottom = value
122
+
123
+ @property
124
+ def diagonal(self) -> BorderSide:
125
+ """Get or create diagonal border."""
126
+ if self._diagonal is None:
127
+ self._diagonal = BorderSide()
128
+ return self._diagonal
129
+
130
+ @diagonal.setter
131
+ def diagonal(self, value: BorderSide):
132
+ """Set diagonal border."""
133
+ self._diagonal = value
134
+
135
+ def set_all_borders(self, style: str = "thin", color: str = "black"):
136
+ """Set all borders to the same style and color."""
137
+ for side in ['left', 'right', 'top', 'bottom']:
138
+ border_side = getattr(self, side)
139
+ border_side.style = style
140
+ border_side.color = color
141
+
142
+ def set_outline(self, style: str = "thin", color: str = "black"):
143
+ """Set outline borders (all four sides)."""
144
+ self.set_all_borders(style, color)
145
+
146
+ def remove_all_borders(self):
147
+ """Remove all borders."""
148
+ self._left = None
149
+ self._right = None
150
+ self._top = None
151
+ self._bottom = None
152
+ self._diagonal = None
153
+
154
+ def copy(self) -> 'Border':
155
+ """Create a copy of this border."""
156
+ new_border = Border()
157
+ if self._left:
158
+ new_border._left = self._left.copy()
159
+ if self._right:
160
+ new_border._right = self._right.copy()
161
+ if self._top:
162
+ new_border._top = self._top.copy()
163
+ if self._bottom:
164
+ new_border._bottom = self._bottom.copy()
165
+ if self._diagonal:
166
+ new_border._diagonal = self._diagonal.copy()
167
+ new_border._diagonal_up = self._diagonal_up
168
+ new_border._diagonal_down = self._diagonal_down
169
+ return new_border
170
+
171
+
172
+ class Alignment:
173
+ """Text alignment properties."""
174
+
175
+ def __init__(self):
176
+ self.horizontal: str = "general"
177
+ self.vertical: str = "bottom"
178
+ self.wrap_text: bool = False
179
+ self.shrink_to_fit: bool = False
180
+ self.indent: int = 0
181
+ self.text_rotation: int = 0
182
+
183
+ def copy(self) -> 'Alignment':
184
+ """Create a copy of this alignment."""
185
+ new_alignment = Alignment()
186
+ new_alignment.horizontal = self.horizontal
187
+ new_alignment.vertical = self.vertical
188
+ new_alignment.wrap_text = self.wrap_text
189
+ new_alignment.shrink_to_fit = self.shrink_to_fit
190
+ new_alignment.indent = self.indent
191
+ new_alignment.text_rotation = self.text_rotation
192
+ return new_alignment
193
+
194
+
195
+ class Style:
196
+ """Complete cell style container."""
197
+
198
+ def __init__(self):
199
+ self._font: Optional[Font] = None
200
+ self._fill: Optional[Fill] = None
201
+ self._border: Optional[Border] = None
202
+ self._alignment: Optional[Alignment] = None
203
+ self._number_format: str = "General"
204
+ self._protection: bool = True
205
+
206
+ @property
207
+ def font(self) -> Font:
208
+ """Get or create font styling."""
209
+ if self._font is None:
210
+ self._font = Font()
211
+ return self._font
212
+
213
+ @font.setter
214
+ def font(self, value: Font):
215
+ """Set font styling."""
216
+ self._font = value
217
+
218
+ @property
219
+ def fill(self) -> Fill:
220
+ """Get or create fill styling."""
221
+ if self._fill is None:
222
+ self._fill = Fill()
223
+ return self._fill
224
+
225
+ @fill.setter
226
+ def fill(self, value: Fill):
227
+ """Set fill styling."""
228
+ self._fill = value
229
+
230
+ @property
231
+ def border(self) -> Border:
232
+ """Get or create border styling."""
233
+ if self._border is None:
234
+ self._border = Border()
235
+ return self._border
236
+
237
+ @border.setter
238
+ def border(self, value: Border):
239
+ """Set border styling."""
240
+ self._border = value
241
+
242
+ @property
243
+ def alignment(self) -> Alignment:
244
+ """Get or create alignment styling."""
245
+ if self._alignment is None:
246
+ self._alignment = Alignment()
247
+ return self._alignment
248
+
249
+ @alignment.setter
250
+ def alignment(self, value: Alignment):
251
+ """Set alignment styling."""
252
+ self._alignment = value
253
+
254
+ @property
255
+ def number_format(self) -> str:
256
+ """Get number format."""
257
+ return self._number_format
258
+
259
+ @number_format.setter
260
+ def number_format(self, value: str):
261
+ """Set number format."""
262
+ self._number_format = value
263
+
264
+ @property
265
+ def protection(self) -> bool:
266
+ """Get protection status."""
267
+ return self._protection
268
+
269
+ @protection.setter
270
+ def protection(self, value: bool):
271
+ """Set protection status."""
272
+ self._protection = value
273
+
274
+ def copy(self) -> 'Style':
275
+ """Create a deep copy of this style."""
276
+ new_style = Style()
277
+ if self._font:
278
+ new_style._font = self._font.copy()
279
+ if self._fill:
280
+ new_style._fill = self._fill.copy()
281
+ if self._border:
282
+ new_style._border = self._border.copy()
283
+ if self._alignment:
284
+ new_style._alignment = self._alignment.copy()
285
+ new_style._number_format = self._number_format
286
+ new_style._protection = self._protection
287
+ return new_style
@@ -0,0 +1,54 @@
1
+ """
2
+ Utility functions and classes for Excel operations.
3
+ """
4
+
5
+ from .coordinates import (
6
+ column_index_to_letter,
7
+ column_letter_to_index,
8
+ coordinate_to_tuple,
9
+ tuple_to_coordinate,
10
+ parse_range
11
+ )
12
+ from .validation import (
13
+ is_numeric_string,
14
+ is_formula,
15
+ is_date_value,
16
+ infer_data_type,
17
+ validate_sheet_name,
18
+ sanitize_sheet_name,
19
+ convert_value
20
+ )
21
+ from .exceptions import (
22
+ AsposeException,
23
+ FileFormatError,
24
+ InvalidCoordinateError,
25
+ WorksheetNotFoundError,
26
+ CellValueError,
27
+ ExportError
28
+ )
29
+
30
+ __all__ = [
31
+ # Coordinates
32
+ "column_index_to_letter",
33
+ "column_letter_to_index",
34
+ "coordinate_to_tuple",
35
+ "tuple_to_coordinate",
36
+ "parse_range",
37
+
38
+ # Validation
39
+ "is_numeric_string",
40
+ "is_formula",
41
+ "is_date_value",
42
+ "infer_data_type",
43
+ "validate_sheet_name",
44
+ "sanitize_sheet_name",
45
+ "convert_value",
46
+
47
+ # Exceptions
48
+ "AsposeException",
49
+ "FileFormatError",
50
+ "InvalidCoordinateError",
51
+ "WorksheetNotFoundError",
52
+ "CellValueError",
53
+ "ExportError"
54
+ ]
@@ -0,0 +1,68 @@
1
+ """
2
+ Coordinate conversion utilities for Excel cell addressing.
3
+ """
4
+
5
+ import re
6
+ from typing import Tuple
7
+ from .exceptions import InvalidCoordinateError
8
+
9
+
10
+ def column_index_to_letter(index: int) -> str:
11
+ """Convert 1-based column index to Excel letter (1 -> A, 27 -> AA)."""
12
+ if index < 1:
13
+ raise InvalidCoordinateError(f"Column index must be >= 1, got {index}")
14
+
15
+ result = ""
16
+ while index > 0:
17
+ index -= 1
18
+ result = chr(65 + index % 26) + result
19
+ index //= 26
20
+ return result
21
+
22
+
23
+ def column_letter_to_index(letter: str) -> int:
24
+ """Convert Excel column letter to 1-based index (A -> 1, AA -> 27)."""
25
+ if not letter or not letter.isalpha():
26
+ raise InvalidCoordinateError(f"Invalid column letter: {letter}")
27
+
28
+ result = 0
29
+ for char in letter.upper():
30
+ result = result * 26 + (ord(char) - ord('A') + 1)
31
+ return result
32
+
33
+
34
+ def coordinate_to_tuple(coordinate: str) -> Tuple[int, int]:
35
+ """Convert Excel coordinate to (row, column) tuple (A1 -> (1, 1))."""
36
+ match = re.match(r'^([A-Z]+)(\d+)$', coordinate.upper())
37
+ if not match:
38
+ raise InvalidCoordinateError(f"Invalid coordinate format: {coordinate}")
39
+
40
+ col_letter, row_str = match.groups()
41
+ row = int(row_str)
42
+ col = column_letter_to_index(col_letter)
43
+
44
+ if row < 1:
45
+ raise InvalidCoordinateError(f"Row number must be >= 1, got {row}")
46
+
47
+ return row, col
48
+
49
+
50
+ def tuple_to_coordinate(row: int, column: int) -> str:
51
+ """Convert (row, column) tuple to Excel coordinate ((1, 1) -> A1)."""
52
+ if row < 1 or column < 1:
53
+ raise InvalidCoordinateError(f"Row and column must be >= 1, got ({row}, {column})")
54
+
55
+ col_letter = column_index_to_letter(column)
56
+ return f"{col_letter}{row}"
57
+
58
+
59
+ def parse_range(range_str: str) -> Tuple[Tuple[int, int], Tuple[int, int]]:
60
+ """Parse Excel range to ((start_row, start_col), (end_row, end_col))."""
61
+ if ':' not in range_str:
62
+ raise InvalidCoordinateError(f"Range must contain ':', got: {range_str}")
63
+
64
+ start_cell, end_cell = range_str.split(':', 1)
65
+ start_coord = coordinate_to_tuple(start_cell.strip())
66
+ end_coord = coordinate_to_tuple(end_cell.strip())
67
+
68
+ return start_coord, end_coord
@@ -0,0 +1,43 @@
1
+ """
2
+ Custom exception classes for Aspose.Cells operations.
3
+ """
4
+
5
+
6
+ class AsposeException(Exception):
7
+ """Base exception for all Aspose.Cells errors."""
8
+ pass
9
+
10
+
11
+ class FileFormatError(AsposeException):
12
+ """Raised when file format is not supported or invalid."""
13
+ pass
14
+
15
+
16
+ class InvalidCoordinateError(AsposeException):
17
+ """Raised when cell coordinate is invalid."""
18
+ pass
19
+
20
+
21
+ class WorksheetNotFoundError(AsposeException):
22
+ """Raised when worksheet cannot be found."""
23
+ pass
24
+
25
+
26
+ class CellValueError(AsposeException):
27
+ """Raised when cell value operation fails."""
28
+ pass
29
+
30
+
31
+ class ExportError(AsposeException):
32
+ """Raised when data export operation fails."""
33
+ pass
34
+
35
+
36
+ class ExcelValidationError(AsposeException):
37
+ """Raised when Excel data validation fails."""
38
+ pass
39
+
40
+
41
+ class CellRangeError(AsposeException):
42
+ """Raised when cell range operation fails."""
43
+ pass