Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/openpyxl/worksheet/merge.py: 35%
67 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1# Copyright (c) 2010-2022 openpyxl
3import copy
5from openpyxl.descriptors.serialisable import Serialisable
6from openpyxl.descriptors import (
7 Integer,
8 Sequence,
9)
11from openpyxl.cell.cell import MergedCell
12from openpyxl.styles.borders import Border
14from .cell_range import CellRange
17class MergeCell(CellRange):
19 tagname = "mergeCell"
20 ref = CellRange.coord
22 __attrs__ = ("ref",)
25 def __init__(self,
26 ref=None,
27 ):
28 super(MergeCell, self).__init__(ref)
31 def __copy__(self):
32 return self.__class__(self.ref)
35class MergeCells(Serialisable):
37 tagname = "mergeCells"
39 count = Integer(allow_none=True)
40 mergeCell = Sequence(expected_type=MergeCell, )
42 __elements__ = ('mergeCell',)
43 __attrs__ = ('count',)
45 def __init__(self,
46 count=None,
47 mergeCell=(),
48 ):
49 self.mergeCell = mergeCell
52 @property
53 def count(self):
54 return len(self.mergeCell)
57class MergedCellRange(CellRange):
59 """
60 MergedCellRange stores the border information of a merged cell in the top
61 left cell of the merged cell.
62 The remaining cells in the merged cell are stored as MergedCell objects and
63 get their border information from the upper left cell.
64 """
66 def __init__(self, worksheet, coord):
67 self.ws = worksheet
68 super().__init__(range_string=coord)
69 self.start_cell = None
70 self._get_borders()
73 def _get_borders(self):
74 """
75 If the upper left cell of the merged cell does not yet exist, it is
76 created.
77 The upper left cell gets the border information of the bottom and right
78 border from the bottom right cell of the merged cell, if available.
79 """
81 # Top-left cell.
82 self.start_cell = self.ws._cells.get((self.min_row, self.min_col))
83 if self.start_cell is None:
84 self.start_cell = self.ws.cell(row=self.min_row, column=self.min_col)
86 # Bottom-right cell
87 end_cell = self.ws._cells.get((self.max_row, self.max_col))
88 if end_cell is not None:
89 self.start_cell.border += Border(right=end_cell.border.right,
90 bottom=end_cell.border.bottom)
93 def format(self):
94 """
95 Each cell of the merged cell is created as MergedCell if it does not
96 already exist.
98 The MergedCells at the edge of the merged cell gets its borders from
99 the upper left cell.
101 - The top MergedCells get the top border from the top left cell.
102 - The bottom MergedCells get the bottom border from the top left cell.
103 - The left MergedCells get the left border from the top left cell.
104 - The right MergedCells get the right border from the top left cell.
105 """
107 names = ['top', 'left', 'right', 'bottom']
109 for name in names:
110 side = getattr(self.start_cell.border, name)
111 if side and side.style is None:
112 continue # don't need to do anything if there is no border style
113 border = Border(**{name:side})
114 for coord in getattr(self, name):
115 cell = self.ws._cells.get(coord)
116 if cell is None:
117 row, col = coord
118 cell = MergedCell(self.ws, row=row, column=col)
119 self.ws._cells[(cell.row, cell.column)] = cell
120 cell.border += border
122 protected = self.start_cell.protection is not None
123 if protected:
124 protection = copy.copy(self.start_cell.protection)
125 for coord in self.cells:
126 cell = self.ws._cells.get(coord)
127 if cell is None:
128 row, col = coord
129 cell = MergedCell(self.ws, row=row, column=col)
130 self.ws._cells[(cell.row, cell.column)] = cell
132 if protected:
133 cell.protection = protection
136 def __contains__(self, coord):
137 return coord in CellRange(self.coord)
140 def __copy__(self):
141 return self.__class__(self.ws, self.coord)