97 lines
3.2 KiB
Python
97 lines
3.2 KiB
Python
# sumaexcel/merge.py
|
|
from typing import List, Tuple, Dict
|
|
from openpyxl.worksheet.worksheet import Worksheet
|
|
from openpyxl.worksheet.merge import MergedCellRange
|
|
|
|
class MergeManager:
|
|
"""Handle merge cell operations"""
|
|
|
|
def __init__(self, worksheet: Worksheet):
|
|
self.worksheet = worksheet
|
|
self._merged_ranges: List[MergedCellRange] = []
|
|
self._load_merged_ranges()
|
|
|
|
def _load_merged_ranges(self) -> None:
|
|
"""Load existing merged ranges from worksheet"""
|
|
self._merged_ranges = list(self.worksheet.merged_cells.ranges)
|
|
|
|
def merge_cells(
|
|
self,
|
|
start_row: int,
|
|
start_col: int,
|
|
end_row: int,
|
|
end_col: int
|
|
) -> None:
|
|
"""Merge cells in specified range"""
|
|
self.worksheet.merge_cells(
|
|
start_row=start_row,
|
|
start_column=start_col,
|
|
end_row=end_row,
|
|
end_column=end_col
|
|
)
|
|
self._load_merged_ranges()
|
|
|
|
def unmerge_cells(
|
|
self,
|
|
start_row: int,
|
|
start_col: int,
|
|
end_row: int,
|
|
end_col: int
|
|
) -> None:
|
|
"""Unmerge cells in specified range"""
|
|
self.worksheet.unmerge_cells(
|
|
start_row=start_row,
|
|
start_column=start_col,
|
|
end_row=end_row,
|
|
end_column=end_col
|
|
)
|
|
self._load_merged_ranges()
|
|
|
|
def copy_merged_cells(
|
|
self,
|
|
source_range: Tuple[int, int, int, int],
|
|
target_start_row: int,
|
|
target_start_col: int
|
|
) -> None:
|
|
"""Copy merged cells from source range to target position"""
|
|
src_row1, src_col1, src_row2, src_col2 = source_range
|
|
row_offset = target_start_row - src_row1
|
|
col_offset = target_start_col - src_col1
|
|
|
|
for merged_range in self._merged_ranges:
|
|
if (src_row1 <= merged_range.min_row <= src_row2 and
|
|
src_col1 <= merged_range.min_col <= src_col2):
|
|
new_row1 = merged_range.min_row + row_offset
|
|
new_col1 = merged_range.min_col + col_offset
|
|
new_row2 = merged_range.max_row + row_offset
|
|
new_col2 = merged_range.max_col + col_offset
|
|
|
|
self.merge_cells(new_row1, new_col1, new_row2, new_col2)
|
|
|
|
def shift_merged_cells(
|
|
self,
|
|
start_row: int,
|
|
rows: int = 0,
|
|
cols: int = 0
|
|
) -> None:
|
|
"""Shift merged cells by specified number of rows and columns"""
|
|
new_ranges = []
|
|
for merged_range in self._merged_ranges:
|
|
if merged_range.min_row >= start_row:
|
|
new_row1 = merged_range.min_row + rows
|
|
new_col1 = merged_range.min_col + cols
|
|
new_row2 = merged_range.max_row + rows
|
|
new_col2 = merged_range.max_col + cols
|
|
|
|
self.worksheet.unmerge_cells(
|
|
start_row=merged_range.min_row,
|
|
start_column=merged_range.min_col,
|
|
end_row=merged_range.max_row,
|
|
end_column=merged_range.max_col
|
|
)
|
|
|
|
new_ranges.append((new_row1, new_col1, new_row2, new_col2))
|
|
|
|
for new_range in new_ranges:
|
|
self.merge_cells(*new_range)
|