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.
Files changed (93) hide show
  1. aspose_cells/__init__.py +88 -0
  2. aspose_cells/auto_filter.py +527 -0
  3. aspose_cells/cell.py +483 -0
  4. aspose_cells/cell_value_handler.py +319 -0
  5. aspose_cells/cells.py +779 -0
  6. aspose_cells/cfb_handler.py +445 -0
  7. aspose_cells/cfb_writer.py +659 -0
  8. aspose_cells/cfb_writer_minimal.py +337 -0
  9. aspose_cells/comment_xml.py +475 -0
  10. aspose_cells/conditional_format.py +1185 -0
  11. aspose_cells/csv_handler.py +690 -0
  12. aspose_cells/data_validation.py +911 -0
  13. aspose_cells/document_properties.py +356 -0
  14. aspose_cells/encryption_crypto.py +247 -0
  15. aspose_cells/encryption_params.py +138 -0
  16. aspose_cells/hyperlink.py +372 -0
  17. aspose_cells/json_handler.py +185 -0
  18. aspose_cells/markdown_handler.py +583 -0
  19. aspose_cells/shared_strings.py +101 -0
  20. aspose_cells/style.py +841 -0
  21. aspose_cells/workbook.py +499 -0
  22. aspose_cells/workbook_hash_password.py +68 -0
  23. aspose_cells/workbook_properties.py +712 -0
  24. aspose_cells/worksheet.py +570 -0
  25. aspose_cells/worksheet_properties.py +1239 -0
  26. aspose_cells/xlsx_encryptor.py +403 -0
  27. aspose_cells/xml_autofilter_loader.py +195 -0
  28. aspose_cells/xml_autofilter_saver.py +173 -0
  29. aspose_cells/xml_conditional_format_loader.py +215 -0
  30. aspose_cells/xml_conditional_format_saver.py +351 -0
  31. aspose_cells/xml_datavalidation_loader.py +239 -0
  32. aspose_cells/xml_datavalidation_saver.py +245 -0
  33. aspose_cells/xml_hyperlink_handler.py +323 -0
  34. aspose_cells/xml_loader.py +986 -0
  35. aspose_cells/xml_properties_loader.py +512 -0
  36. aspose_cells/xml_properties_saver.py +607 -0
  37. aspose_cells/xml_saver.py +1306 -0
  38. aspose_cells_foss-26.2.2.dist-info/METADATA +190 -0
  39. aspose_cells_foss-26.2.2.dist-info/RECORD +41 -0
  40. {aspose_cells_foss-25.12.1.dist-info → aspose_cells_foss-26.2.2.dist-info}/WHEEL +1 -1
  41. aspose_cells_foss-26.2.2.dist-info/top_level.txt +1 -0
  42. aspose/__init__.py +0 -14
  43. aspose/cells/__init__.py +0 -31
  44. aspose/cells/cell.py +0 -350
  45. aspose/cells/constants.py +0 -44
  46. aspose/cells/converters/__init__.py +0 -13
  47. aspose/cells/converters/csv_converter.py +0 -55
  48. aspose/cells/converters/json_converter.py +0 -46
  49. aspose/cells/converters/markdown_converter.py +0 -453
  50. aspose/cells/drawing/__init__.py +0 -17
  51. aspose/cells/drawing/anchor.py +0 -172
  52. aspose/cells/drawing/collection.py +0 -233
  53. aspose/cells/drawing/image.py +0 -338
  54. aspose/cells/formats.py +0 -80
  55. aspose/cells/formula/__init__.py +0 -10
  56. aspose/cells/formula/evaluator.py +0 -360
  57. aspose/cells/formula/functions.py +0 -433
  58. aspose/cells/formula/tokenizer.py +0 -340
  59. aspose/cells/io/__init__.py +0 -27
  60. aspose/cells/io/csv/__init__.py +0 -8
  61. aspose/cells/io/csv/reader.py +0 -88
  62. aspose/cells/io/csv/writer.py +0 -98
  63. aspose/cells/io/factory.py +0 -138
  64. aspose/cells/io/interfaces.py +0 -48
  65. aspose/cells/io/json/__init__.py +0 -8
  66. aspose/cells/io/json/reader.py +0 -126
  67. aspose/cells/io/json/writer.py +0 -119
  68. aspose/cells/io/md/__init__.py +0 -8
  69. aspose/cells/io/md/reader.py +0 -161
  70. aspose/cells/io/md/writer.py +0 -334
  71. aspose/cells/io/models.py +0 -64
  72. aspose/cells/io/xlsx/__init__.py +0 -9
  73. aspose/cells/io/xlsx/constants.py +0 -312
  74. aspose/cells/io/xlsx/image_writer.py +0 -311
  75. aspose/cells/io/xlsx/reader.py +0 -284
  76. aspose/cells/io/xlsx/writer.py +0 -931
  77. aspose/cells/plugins/__init__.py +0 -6
  78. aspose/cells/plugins/docling_backend/__init__.py +0 -7
  79. aspose/cells/plugins/docling_backend/backend.py +0 -535
  80. aspose/cells/plugins/markitdown_plugin/__init__.py +0 -15
  81. aspose/cells/plugins/markitdown_plugin/plugin.py +0 -128
  82. aspose/cells/range.py +0 -210
  83. aspose/cells/style.py +0 -287
  84. aspose/cells/utils/__init__.py +0 -54
  85. aspose/cells/utils/coordinates.py +0 -68
  86. aspose/cells/utils/exceptions.py +0 -43
  87. aspose/cells/utils/validation.py +0 -102
  88. aspose/cells/workbook.py +0 -352
  89. aspose/cells/worksheet.py +0 -670
  90. aspose_cells_foss-25.12.1.dist-info/METADATA +0 -189
  91. aspose_cells_foss-25.12.1.dist-info/RECORD +0 -53
  92. aspose_cells_foss-25.12.1.dist-info/entry_points.txt +0 -2
  93. aspose_cells_foss-25.12.1.dist-info/top_level.txt +0 -1
aspose_cells/cells.py ADDED
@@ -0,0 +1,779 @@
1
+ """
2
+ Aspose.Cells for Python - Cells Module
3
+
4
+ This module provides the Cells class which represents a collection of cells in a worksheet.
5
+ The Cells class provides methods for accessing, modifying, and iterating over cells.
6
+
7
+ Compatible with Aspose.Cells for .NET API structure.
8
+ """
9
+
10
+ from .cell import Cell
11
+
12
+
13
+ class Cells:
14
+ """
15
+ Represents a collection of cells in a worksheet.
16
+
17
+ The Cells class provides methods and properties for working with collections of cells,
18
+ including cell access by reference or coordinates, iteration, and coordinate conversion.
19
+
20
+ Examples:
21
+ >>> from aspose_cells import Workbook
22
+ >>> wb = Workbook()
23
+ >>> ws = wb.worksheets[0]
24
+ >>> cells = ws.cells
25
+ >>> cells['A1'].value = "Hello"
26
+ >>> cell = cells.cell(row=1, column=1)
27
+ """
28
+
29
+ def __init__(self, worksheet=None):
30
+ """
31
+ Initializes a new instance of the Cells class.
32
+
33
+ Examples:
34
+ >>> cells = Cells()
35
+ """
36
+ self._cells = {}
37
+ self._worksheet = worksheet
38
+
39
+ def _require_worksheet(self):
40
+ if self._worksheet is None:
41
+ raise ValueError("Cells is not attached to a Worksheet")
42
+
43
+ # Cell access methods
44
+
45
+ def __getitem__(self, key):
46
+ """
47
+ Gets a cell by its reference (e.g., 'A1').
48
+
49
+ Args:
50
+ key (str): Cell reference in A1 notation (e.g., 'A1', 'B3').
51
+
52
+ Returns:
53
+ Cell: The Cell object at the specified reference. Creates a new Cell if it doesn't exist.
54
+
55
+ Examples:
56
+ >>> cell = cells['A1']
57
+ >>> cell.value = "Hello"
58
+ """
59
+ if key not in self._cells:
60
+ self._cells[key] = Cell()
61
+ return self._cells[key]
62
+
63
+ def __setitem__(self, key, value):
64
+ """
65
+ Sets a cell value by its reference (e.g., 'A1').
66
+
67
+ Args:
68
+ key (str): Cell reference in A1 notation (e.g., 'A1', 'B3').
69
+ value: The value to set in the cell. Can be a Cell object or any value type.
70
+
71
+ Examples:
72
+ >>> cells['A1'] = "Hello"
73
+ >>> cells['B1'] = 42
74
+ >>> cells['C1'] = Cell("Custom cell")
75
+ """
76
+ if key not in self._cells:
77
+ self._cells[key] = Cell()
78
+ if isinstance(value, Cell):
79
+ self._cells[key] = value
80
+ else:
81
+ self._cells[key].value = value
82
+
83
+ def cell(self, row=None, column=None):
84
+ """
85
+ Accesses a cell by row and column (1-based).
86
+
87
+ Args:
88
+ row (int): 1-based row number.
89
+ column (int or str): 1-based column number or column letter (e.g., 1 or 'A').
90
+
91
+ Returns:
92
+ Cell: The Cell object at the specified row and column.
93
+
94
+ Raises:
95
+ ValueError: If row or column is not specified.
96
+
97
+ Examples:
98
+ >>> cell = cells.cell(row=1, column=1) # Same as cells['A1']
99
+ >>> cell = cells.cell(row=3, column='B') # Same as cells['B3']
100
+ >>> cell = cells.cell(row=5, column=10) # Cell J5
101
+ """
102
+ if row is None or column is None:
103
+ raise ValueError("Both row and column must be specified")
104
+
105
+ # Convert column letter to number if needed
106
+ if isinstance(column, str):
107
+ column = self.column_index_from_string(column)
108
+
109
+ ref = f"{self.column_letter_from_index(column)}{row}"
110
+ return self[ref]
111
+
112
+ # Coordinate conversion methods (static methods)
113
+
114
+ @staticmethod
115
+ def column_index_from_string(column):
116
+ """
117
+ Converts a column letter to a 1-based index.
118
+
119
+ Args:
120
+ column (str): Column letter(s) (e.g., 'A', 'Z', 'AA').
121
+
122
+ Returns:
123
+ int: 1-based column index (e.g., 'A' -> 1, 'Z' -> 26, 'AA' -> 27).
124
+
125
+ Raises:
126
+ ValueError: If column string is empty or contains invalid characters.
127
+
128
+ Examples:
129
+ >>> Cells.column_index_from_string('A')
130
+ 1
131
+ >>> Cells.column_index_from_string('Z')
132
+ 26
133
+ >>> Cells.column_index_from_string('AA')
134
+ 27
135
+ >>> Cells.column_index_from_string('AB')
136
+ 28
137
+ """
138
+ if not column:
139
+ raise ValueError("Column string cannot be empty")
140
+
141
+ column = column.upper()
142
+ result = 0
143
+ for char in column:
144
+ if not char.isalpha():
145
+ raise ValueError(f"Invalid column character: {char}")
146
+ result = result * 26 + (ord(char) - ord('A') + 1)
147
+ return result
148
+
149
+ @staticmethod
150
+ def column_letter_from_index(column_index):
151
+ """
152
+ Converts a 1-based column index to a letter.
153
+
154
+ Args:
155
+ column_index (int): 1-based column index.
156
+
157
+ Returns:
158
+ str: Column letter(s) (e.g., 1 -> 'A', 26 -> 'Z', 27 -> 'AA').
159
+
160
+ Raises:
161
+ ValueError: If column_index is less than 1.
162
+
163
+ Examples:
164
+ >>> Cells.column_letter_from_index(1)
165
+ 'A'
166
+ >>> Cells.column_letter_from_index(26)
167
+ 'Z'
168
+ >>> Cells.column_letter_from_index(27)
169
+ 'AA'
170
+ >>> Cells.column_letter_from_index(28)
171
+ 'AB'
172
+ """
173
+ if column_index < 1:
174
+ raise ValueError("Column index must be >= 1")
175
+
176
+ result = ""
177
+ while column_index > 0:
178
+ column_index -= 1
179
+ result = chr(ord('A') + (column_index % 26)) + result
180
+ column_index = column_index // 26
181
+ return result
182
+
183
+ @staticmethod
184
+ def coordinate_from_string(coord):
185
+ """
186
+ Converts an A1 coordinate string to (row, column) tuple (1-based).
187
+
188
+ Args:
189
+ coord (str): Cell reference in A1 notation (e.g., 'A1', 'B3', 'Z100').
190
+
191
+ Returns:
192
+ tuple: (row, column) tuple with 1-based indices.
193
+
194
+ Raises:
195
+ ValueError: If coordinate is empty or has invalid format.
196
+
197
+ Examples:
198
+ >>> Cells.coordinate_from_string('A1')
199
+ (1, 1)
200
+ >>> Cells.coordinate_from_string('B3')
201
+ (3, 2)
202
+ >>> Cells.coordinate_from_string('AA10')
203
+ (10, 27)
204
+ """
205
+ if not coord:
206
+ raise ValueError("Coordinate cannot be empty")
207
+
208
+ # Split into column letters and row number
209
+ col_str = ""
210
+ row_str = ""
211
+ for char in coord:
212
+ if char.isalpha():
213
+ col_str += char
214
+ elif char.isdigit():
215
+ row_str += char
216
+ else:
217
+ raise ValueError(f"Invalid character in coordinate: {char}")
218
+
219
+ if not col_str or not row_str:
220
+ raise ValueError(f"Invalid coordinate format: {coord}")
221
+
222
+ column = Cells.column_index_from_string(col_str)
223
+ row = int(row_str)
224
+ return (row, column)
225
+
226
+ @staticmethod
227
+ def coordinate_to_string(row, column):
228
+ """
229
+ Converts row and column (1-based) to an A1 coordinate string.
230
+
231
+ Args:
232
+ row (int): 1-based row number.
233
+ column (int): 1-based column number.
234
+
235
+ Returns:
236
+ str: Cell reference in A1 notation.
237
+
238
+ Raises:
239
+ ValueError: If row or column is less than 1.
240
+
241
+ Examples:
242
+ >>> Cells.coordinate_to_string(1, 1)
243
+ 'A1'
244
+ >>> Cells.coordinate_to_string(3, 2)
245
+ 'B3'
246
+ >>> Cells.coordinate_to_string(10, 27)
247
+ 'AA10'
248
+ """
249
+ if row < 1 or column < 1:
250
+ raise ValueError("Row and column must be >= 1")
251
+
252
+ col_letter = Cells.column_letter_from_index(column)
253
+ return f"{col_letter}{row}"
254
+
255
+ # Iteration methods
256
+
257
+ def iter_rows(self, min_row=None, max_row=None, min_col=None, max_col=None, values_only=False):
258
+ """
259
+ Iterates over rows in the worksheet.
260
+
261
+ Args:
262
+ min_row (int, optional): Minimum row number (1-based). Defaults to 1.
263
+ max_row (int, optional): Maximum row number (1-based). Defaults to max row with data.
264
+ min_col (int, optional): Minimum column number (1-based). Defaults to 1.
265
+ max_col (int, optional): Maximum column number (1-based). Defaults to max column with data.
266
+ values_only (bool): If True, yields cell values instead of Cell objects. Defaults to False.
267
+
268
+ Yields:
269
+ tuple: If values_only=False, yields tuples containing Cell objects for each row.
270
+ If values_only=True, yields tuples containing cell values for each row.
271
+
272
+ Examples:
273
+ >>> for row in cells.iter_rows(min_row=1, max_row=5):
274
+ ... print(row[0].value)
275
+
276
+ >>> for row in cells.iter_rows(min_row=1, max_row=3, min_col=1, max_col=3, values_only=True):
277
+ ... print(row)
278
+ """
279
+ # Determine bounds
280
+ if not self._cells:
281
+ return
282
+
283
+ # Get all row and column numbers from existing cells
284
+ rows = set()
285
+ cols = set()
286
+ for ref in self._cells:
287
+ row, col = self.coordinate_from_string(ref)
288
+ rows.add(row)
289
+ cols.add(col)
290
+
291
+ min_row = min_row if min_row is not None else min(rows) if rows else 1
292
+ max_row = max_row if max_row is not None else max(rows) if rows else 1
293
+ min_col = min_col if min_col is not None else min(cols) if cols else 1
294
+ max_col = max_col if max_col is not None else max(cols) if cols else 1
295
+
296
+ for row in range(min_row, max_row + 1):
297
+ row_cells = []
298
+ for col in range(min_col, max_col + 1):
299
+ ref = self.coordinate_to_string(row, col)
300
+ cell = self[ref]
301
+ if values_only:
302
+ row_cells.append(cell.value)
303
+ else:
304
+ row_cells.append(cell)
305
+ yield tuple(row_cells)
306
+
307
+ def iter_cols(self, min_row=None, max_row=None, min_col=None, max_col=None, values_only=False):
308
+ """
309
+ Iterates over columns in the worksheet.
310
+
311
+ Args:
312
+ min_row (int, optional): Minimum row number (1-based). Defaults to 1.
313
+ max_row (int, optional): Maximum row number (1-based). Defaults to max row with data.
314
+ min_col (int, optional): Minimum column number (1-based). Defaults to 1.
315
+ max_col (int, optional): Maximum column number (1-based). Defaults to max column with data.
316
+ values_only (bool): If True, yields cell values instead of Cell objects. Defaults to False.
317
+
318
+ Yields:
319
+ tuple: If values_only=False, yields tuples containing Cell objects for each column.
320
+ If values_only=True, yields tuples containing cell values for each column.
321
+
322
+ Examples:
323
+ >>> for col in cells.iter_cols(min_col=1, max_col=3):
324
+ ... print(col[0].value)
325
+
326
+ >>> for col in cells.iter_cols(min_row=1, max_row=5, min_col=1, max_col=2, values_only=True):
327
+ ... print(col)
328
+ """
329
+ # Determine bounds
330
+ if not self._cells:
331
+ return
332
+
333
+ # Get all row and column numbers from existing cells
334
+ rows = set()
335
+ cols = set()
336
+ for ref in self._cells:
337
+ row, col = self.coordinate_from_string(ref)
338
+ rows.add(row)
339
+ cols.add(col)
340
+
341
+ min_row = min_row if min_row is not None else min(rows) if rows else 1
342
+ max_row = max_row if max_row is not None else max(rows) if rows else 1
343
+ min_col = min_col if min_col is not None else min(cols) if cols else 1
344
+ max_col = max_col if max_col is not None else max(cols) if cols else 1
345
+
346
+ for col in range(min_col, max_col + 1):
347
+ col_cells = []
348
+ for row in range(min_row, max_row + 1):
349
+ ref = self.coordinate_to_string(row, col)
350
+ cell = self[ref]
351
+ if values_only:
352
+ col_cells.append(cell.value)
353
+ else:
354
+ col_cells.append(cell)
355
+ yield tuple(col_cells)
356
+
357
+ # Cell collection methods
358
+
359
+ def count(self):
360
+ """
361
+ Gets the number of cells in the collection.
362
+
363
+ Returns:
364
+ int: The number of cells that have been accessed or modified.
365
+
366
+ Examples:
367
+ >>> num_cells = cells.count()
368
+ >>> print(f"Total cells: {num_cells}")
369
+ """
370
+ return len(self._cells)
371
+
372
+ def clear(self):
373
+ """
374
+ Clears all cells in the collection.
375
+
376
+ Examples:
377
+ >>> cells.clear()
378
+ """
379
+ self._cells.clear()
380
+
381
+ def get_cell_by_name(self, cell_name):
382
+ """
383
+ Gets a cell by its name (reference).
384
+
385
+ Args:
386
+ cell_name (str): Cell reference in A1 notation (e.g., 'A1', 'B3').
387
+
388
+ Returns:
389
+ Cell: The Cell object at the specified reference.
390
+
391
+ Examples:
392
+ >>> cell = cells.get_cell_by_name('A1')
393
+ >>> cell.value = "Hello"
394
+ """
395
+ return self[cell_name]
396
+
397
+ def set_cell_by_name(self, cell_name, value):
398
+ """
399
+ Sets a cell value by its name (reference).
400
+
401
+ Args:
402
+ cell_name (str): Cell reference in A1 notation (e.g., 'A1', 'B3').
403
+ value: The value to set in the cell.
404
+
405
+ Examples:
406
+ >>> cells.set_cell_by_name('A1', "Hello")
407
+ >>> cells.set_cell_by_name('B1', 42)
408
+ """
409
+ self[cell_name] = value
410
+
411
+ def get_cell(self, row, column):
412
+ """
413
+ Gets a cell by row and column (1-based).
414
+
415
+ Args:
416
+ row (int): 1-based row number.
417
+ column (int): 1-based column number.
418
+
419
+ Returns:
420
+ Cell: The Cell object at the specified row and column.
421
+
422
+ Examples:
423
+ >>> cell = cells.get_cell(1, 1) # Same as cells['A1']
424
+ >>> cell = cells.get_cell(3, 2) # Same as cells['B3']
425
+ """
426
+ return self.cell(row=row, column=column)
427
+
428
+ def set_cell(self, row, column, value):
429
+ """
430
+ Sets a cell value by row and column (1-based).
431
+
432
+ Args:
433
+ row (int): 1-based row number.
434
+ column (int): 1-based column number.
435
+ value: The value to set in the cell.
436
+
437
+ Examples:
438
+ >>> cells.set_cell(1, 1, "Hello") # Same as cells['A1'] = "Hello"
439
+ >>> cells.set_cell(3, 2, 42) # Same as cells['B3'] = 42
440
+ """
441
+ ref = self.coordinate_to_string(row, column)
442
+ self[ref] = value
443
+
444
+ # Row/Column dimensions (Aspose.Cells compatible)
445
+
446
+ def set_row_height(self, row, height):
447
+ """
448
+ Sets the height of the specified row in points.
449
+
450
+ Args:
451
+ row (int): 1-based row index.
452
+ height (float): Row height in points (must be > 0).
453
+ """
454
+ self._require_worksheet()
455
+ if row is None or row < 1:
456
+ raise ValueError("row must be >= 1")
457
+ if height is None or height <= 0:
458
+ raise ValueError("height must be > 0")
459
+ self._worksheet._row_heights[int(row)] = float(height)
460
+
461
+ def get_row_height(self, row):
462
+ """
463
+ Gets the height of the specified row in points.
464
+
465
+ Args:
466
+ row (int): 1-based row index.
467
+
468
+ Returns:
469
+ float: Row height in points.
470
+ """
471
+ self._require_worksheet()
472
+ if row is None or row < 1:
473
+ raise ValueError("row must be >= 1")
474
+ row = int(row)
475
+ if row in self._worksheet._row_heights:
476
+ return self._worksheet._row_heights[row]
477
+ return float(self._worksheet.properties.format.default_row_height)
478
+
479
+ def hide_row(self, row):
480
+ """
481
+ Hides the specified row.
482
+
483
+ Args:
484
+ row (int): 1-based row index.
485
+ """
486
+ self._require_worksheet()
487
+ if row is None or row < 1:
488
+ raise ValueError("row must be >= 1")
489
+ self._worksheet._hidden_rows.add(int(row))
490
+
491
+ def unhide_row(self, row):
492
+ """
493
+ Unhides the specified row.
494
+
495
+ Args:
496
+ row (int): 1-based row index.
497
+ """
498
+ self._require_worksheet()
499
+ if row is None or row < 1:
500
+ raise ValueError("row must be >= 1")
501
+ self._worksheet._hidden_rows.discard(int(row))
502
+
503
+ def is_row_hidden(self, row):
504
+ """
505
+ Checks if the specified row is hidden.
506
+
507
+ Args:
508
+ row (int): 1-based row index.
509
+
510
+ Returns:
511
+ bool: True if hidden, False otherwise.
512
+ """
513
+ self._require_worksheet()
514
+ if row is None or row < 1:
515
+ raise ValueError("row must be >= 1")
516
+ return int(row) in self._worksheet._hidden_rows
517
+
518
+ def set_column_width(self, column, width):
519
+ """
520
+ Sets the width of the specified column in character units.
521
+
522
+ Args:
523
+ column (int or str): 1-based column index or column letter.
524
+ width (float): Column width in characters (must be > 0).
525
+ """
526
+ self._require_worksheet()
527
+ if column is None:
528
+ raise ValueError("column must be specified")
529
+ if isinstance(column, str):
530
+ column = self.column_index_from_string(column)
531
+ if column < 1:
532
+ raise ValueError("column must be >= 1")
533
+ if width is None or width <= 0:
534
+ raise ValueError("width must be > 0")
535
+ self._worksheet._column_widths[int(column)] = float(width)
536
+
537
+ def get_column_width(self, column):
538
+ """
539
+ Gets the width of the specified column in character units.
540
+
541
+ Args:
542
+ column (int or str): 1-based column index or column letter.
543
+
544
+ Returns:
545
+ float: Column width in characters.
546
+ """
547
+ self._require_worksheet()
548
+ if column is None:
549
+ raise ValueError("column must be specified")
550
+ if isinstance(column, str):
551
+ column = self.column_index_from_string(column)
552
+ if column < 1:
553
+ raise ValueError("column must be >= 1")
554
+ column = int(column)
555
+ if column in self._worksheet._column_widths:
556
+ return self._worksheet._column_widths[column]
557
+ fmt = self._worksheet.properties.format
558
+ if fmt.default_col_width is not None:
559
+ return float(fmt.default_col_width)
560
+ return float(fmt.base_col_width)
561
+
562
+ def hide_column(self, column):
563
+ """
564
+ Hides the specified column.
565
+
566
+ Args:
567
+ column (int or str): 1-based column index or column letter.
568
+ """
569
+ self._require_worksheet()
570
+ if column is None:
571
+ raise ValueError("column must be specified")
572
+ if isinstance(column, str):
573
+ column = self.column_index_from_string(column)
574
+ if column < 1:
575
+ raise ValueError("column must be >= 1")
576
+ self._worksheet._hidden_columns.add(int(column))
577
+
578
+ def unhide_column(self, column):
579
+ """
580
+ Unhides the specified column.
581
+
582
+ Args:
583
+ column (int or str): 1-based column index or column letter.
584
+ """
585
+ self._require_worksheet()
586
+ if column is None:
587
+ raise ValueError("column must be specified")
588
+ if isinstance(column, str):
589
+ column = self.column_index_from_string(column)
590
+ if column < 1:
591
+ raise ValueError("column must be >= 1")
592
+ self._worksheet._hidden_columns.discard(int(column))
593
+
594
+ def is_column_hidden(self, column):
595
+ """
596
+ Checks if the specified column is hidden.
597
+
598
+ Args:
599
+ column (int or str): 1-based column index or column letter.
600
+
601
+ Returns:
602
+ bool: True if hidden, False otherwise.
603
+ """
604
+ self._require_worksheet()
605
+ if column is None:
606
+ raise ValueError("column must be specified")
607
+ if isinstance(column, str):
608
+ column = self.column_index_from_string(column)
609
+ if column < 1:
610
+ raise ValueError("column must be >= 1")
611
+ return int(column) in self._worksheet._hidden_columns
612
+
613
+ # Aspose.Cells .NET-style aliases
614
+
615
+ def SetRowHeight(self, row, height):
616
+ return self.set_row_height(row, height)
617
+
618
+ def GetRowHeight(self, row):
619
+ return self.get_row_height(row)
620
+
621
+ def SetColumnWidth(self, column, width):
622
+ return self.set_column_width(column, width)
623
+
624
+ def GetColumnWidth(self, column):
625
+ return self.get_column_width(column)
626
+
627
+ def SetRowHidden(self, row, is_hidden):
628
+ if is_hidden:
629
+ return self.hide_row(row)
630
+ return self.unhide_row(row)
631
+
632
+ def IsRowHidden(self, row):
633
+ return self.is_row_hidden(row)
634
+
635
+ def SetColumnHidden(self, column, is_hidden):
636
+ if is_hidden:
637
+ return self.hide_column(column)
638
+ return self.unhide_column(column)
639
+
640
+ def IsColumnHidden(self, column):
641
+ return self.is_column_hidden(column)
642
+
643
+ # Range methods
644
+
645
+ def get_range(self, start_row, start_column, end_row, end_column):
646
+ """
647
+ Gets a range of cells as a list of lists.
648
+
649
+ Args:
650
+ start_row (int): 1-based start row number.
651
+ start_column (int): 1-based start column number.
652
+ end_row (int): 1-based end row number.
653
+ end_column (int): 1-based end column number.
654
+
655
+ Returns:
656
+ list: List of lists containing Cell objects for the specified range.
657
+
658
+ Examples:
659
+ >>> range_cells = cells.get_range(1, 1, 3, 3) # A1:C3 range
660
+ >>> for row in range_cells:
661
+ ... for cell in row:
662
+ ... print(cell.value)
663
+ """
664
+ result = []
665
+ for row in range(start_row, end_row + 1):
666
+ row_cells = []
667
+ for col in range(start_column, end_column + 1):
668
+ ref = self.coordinate_to_string(row, col)
669
+ row_cells.append(self[ref])
670
+ result.append(row_cells)
671
+ return result
672
+
673
+ def set_range(self, start_row, start_column, end_row, end_column, values):
674
+ """
675
+ Sets values for a range of cells.
676
+
677
+ Args:
678
+ start_row (int): 1-based start row number.
679
+ start_column (int): 1-based start column number.
680
+ end_row (int): 1-based end row number.
681
+ end_column (int): 1-based end column number.
682
+ values: List of lists containing values to set. Must match the range dimensions.
683
+
684
+ Examples:
685
+ >>> values = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
686
+ >>> cells.set_range(1, 1, 3, 3, values) # Sets A1:C3
687
+ """
688
+ for i, row in enumerate(range(start_row, end_row + 1)):
689
+ for j, col in enumerate(range(start_column, end_column + 1)):
690
+ if i < len(values) and j < len(values[i]):
691
+ ref = self.coordinate_to_string(row, col)
692
+ self[ref] = values[i][j]
693
+
694
+ # Utility methods
695
+
696
+ def has_cell(self, cell_name):
697
+ """
698
+ Checks if a cell exists in the collection.
699
+
700
+ Args:
701
+ cell_name (str): Cell reference in A1 notation (e.g., 'A1', 'B3').
702
+
703
+ Returns:
704
+ bool: True if the cell has been accessed or modified, False otherwise.
705
+
706
+ Examples:
707
+ >>> if cells.has_cell('A1'):
708
+ ... print("Cell A1 exists")
709
+ """
710
+ return cell_name in self._cells
711
+
712
+ def delete_cell(self, cell_name):
713
+ """
714
+ Deletes a cell from the collection.
715
+
716
+ Args:
717
+ cell_name (str): Cell reference in A1 notation (e.g., 'A1', 'B3').
718
+
719
+ Examples:
720
+ >>> cells.delete_cell('A1')
721
+ """
722
+ if cell_name in self._cells:
723
+ del self._cells[cell_name]
724
+
725
+ def get_all_cells(self):
726
+ """
727
+ Gets all cells in the collection.
728
+
729
+ Returns:
730
+ dict: Dictionary mapping cell references to Cell objects.
731
+
732
+ Examples:
733
+ >>> all_cells = cells.get_all_cells()
734
+ >>> for ref, cell in all_cells.items():
735
+ ... print(f"{ref}: {cell.value}")
736
+ """
737
+ return self._cells.copy()
738
+
739
+ # String representation
740
+
741
+ def __len__(self):
742
+ """
743
+ Gets the number of cells in the collection.
744
+
745
+ Returns:
746
+ int: The number of cells in the collection.
747
+ """
748
+ return len(self._cells)
749
+
750
+ def __contains__(self, key):
751
+ """
752
+ Checks if a cell reference exists in the collection.
753
+
754
+ Args:
755
+ key (str): Cell reference in A1 notation.
756
+
757
+ Returns:
758
+ bool: True if the cell exists, False otherwise.
759
+ """
760
+ return key in self._cells
761
+
762
+ def __iter__(self):
763
+ """
764
+ Iterates over all cells in the collection.
765
+
766
+ Yields:
767
+ tuple: (cell_reference, Cell) tuples for each cell.
768
+ """
769
+ for ref, cell in self._cells.items():
770
+ yield (ref, cell)
771
+
772
+ def __repr__(self):
773
+ """
774
+ Returns a string representation of the Cells collection.
775
+
776
+ Returns:
777
+ str: String representation showing the number of cells.
778
+ """
779
+ return f"Cells(count={len(self._cells)})"