Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/openpyxl/worksheet/dimensions.py: 55%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

166 statements  

1# Copyright (c) 2010-2024 openpyxl 

2 

3from copy import copy 

4 

5from openpyxl.compat import safe_string 

6from openpyxl.utils import ( 

7 get_column_letter, 

8 get_column_interval, 

9 column_index_from_string, 

10 range_boundaries, 

11) 

12from openpyxl.utils.units import DEFAULT_COLUMN_WIDTH 

13from openpyxl.descriptors import ( 

14 Integer, 

15 Float, 

16 Bool, 

17 Strict, 

18 String, 

19 Alias, 

20) 

21from openpyxl.descriptors.serialisable import Serialisable 

22from openpyxl.styles.styleable import StyleableObject 

23from openpyxl.utils.bound_dictionary import BoundDictionary 

24from openpyxl.xml.functions import Element 

25 

26 

27class Dimension(Strict, StyleableObject): 

28 """Information about the display properties of a row or column.""" 

29 __fields__ = ('hidden', 

30 'outlineLevel', 

31 'collapsed',) 

32 

33 index = Integer() 

34 hidden = Bool() 

35 outlineLevel = Integer(allow_none=True) 

36 outline_level = Alias('outlineLevel') 

37 collapsed = Bool() 

38 style = Alias('style_id') 

39 

40 

41 def __init__(self, index, hidden, outlineLevel, 

42 collapsed, worksheet, visible=True, style=None): 

43 super().__init__(sheet=worksheet, style_array=style) 

44 self.index = index 

45 self.hidden = hidden 

46 self.outlineLevel = outlineLevel 

47 self.collapsed = collapsed 

48 

49 

50 def __iter__(self): 

51 for key in self.__fields__: 

52 value = getattr(self, key, None) 

53 if value: 

54 yield key, safe_string(value) 

55 

56 

57 def __copy__(self): 

58 cp = self.__new__(self.__class__) 

59 attrib = self.__dict__ 

60 attrib['worksheet'] = self.parent 

61 cp.__init__(**attrib) 

62 cp._style = copy(self._style) 

63 return cp 

64 

65 

66 def __repr__(self): 

67 return f"<{self.__class__.__name__} Instance, Attributes={dict(self)}>" 

68 

69 

70class RowDimension(Dimension): 

71 """Information about the display properties of a row.""" 

72 

73 __fields__ = Dimension.__fields__ + ('ht', 'customFormat', 'customHeight', 's', 

74 'thickBot', 'thickTop') 

75 r = Alias('index') 

76 s = Alias('style_id') 

77 ht = Float(allow_none=True) 

78 height = Alias('ht') 

79 thickBot = Bool() 

80 thickTop = Bool() 

81 

82 def __init__(self, 

83 worksheet, 

84 index=0, 

85 ht=None, 

86 customHeight=None, # do not write 

87 s=None, 

88 customFormat=None, # do not write 

89 hidden=False, 

90 outlineLevel=0, 

91 outline_level=None, 

92 collapsed=False, 

93 visible=None, 

94 height=None, 

95 r=None, 

96 spans=None, 

97 thickBot=None, 

98 thickTop=None, 

99 **kw 

100 ): 

101 if r is not None: 

102 index = r 

103 if height is not None: 

104 ht = height 

105 self.ht = ht 

106 if visible is not None: 

107 hidden = not visible 

108 if outline_level is not None: 

109 outlineLevel = outline_level 

110 self.thickBot = thickBot 

111 self.thickTop = thickTop 

112 super().__init__(index, hidden, outlineLevel, 

113 collapsed, worksheet, style=s) 

114 

115 @property 

116 def customFormat(self): 

117 """Always true if there is a style for the row""" 

118 return self.has_style 

119 

120 @property 

121 def customHeight(self): 

122 """Always true if there is a height for the row""" 

123 return self.ht is not None 

124 

125 

126class ColumnDimension(Dimension): 

127 """Information about the display properties of a column.""" 

128 

129 width = Float() 

130 bestFit = Bool() 

131 auto_size = Alias('bestFit') 

132 index = String() 

133 min = Integer(allow_none=True) 

134 max = Integer(allow_none=True) 

135 collapsed = Bool() 

136 

137 __fields__ = Dimension.__fields__ + ('width', 'bestFit', 'customWidth', 'style', 

138 'min', 'max') 

139 

140 def __init__(self, 

141 worksheet, 

142 index='A', 

143 width=DEFAULT_COLUMN_WIDTH, 

144 bestFit=False, 

145 hidden=False, 

146 outlineLevel=0, 

147 outline_level=None, 

148 collapsed=False, 

149 style=None, 

150 min=None, 

151 max=None, 

152 customWidth=False, # do not write 

153 visible=None, 

154 auto_size=None,): 

155 self.width = width 

156 self.min = min 

157 self.max = max 

158 if visible is not None: 

159 hidden = not visible 

160 if auto_size is not None: 

161 bestFit = auto_size 

162 self.bestFit = bestFit 

163 if outline_level is not None: 

164 outlineLevel = outline_level 

165 self.collapsed = collapsed 

166 super().__init__(index, hidden, outlineLevel, 

167 collapsed, worksheet, style=style) 

168 

169 

170 @property 

171 def customWidth(self): 

172 """Always true if there is a width for the column""" 

173 return bool(self.width) 

174 

175 

176 def reindex(self): 

177 """ 

178 Set boundaries for column definition 

179 """ 

180 if not all([self.min, self.max]): 

181 self.min = self.max = column_index_from_string(self.index) 

182 

183 @property 

184 def range(self): 

185 """Return the range of cells actually covered""" 

186 return f"{get_column_letter(self.min)}:{get_column_letter(self.max)}" 

187 

188 

189 def to_tree(self): 

190 attrs = dict(self) 

191 if attrs.keys() != {'min', 'max'}: 

192 return Element("col", **attrs) 

193 

194 

195class DimensionHolder(BoundDictionary): 

196 """ 

197 Allow columns to be grouped 

198 """ 

199 

200 def __init__(self, worksheet, reference="index", default_factory=None): 

201 self.worksheet = worksheet 

202 self.max_outline = None 

203 self.default_factory = default_factory 

204 super().__init__(reference, default_factory) 

205 

206 

207 def group(self, start, end=None, outline_level=1, hidden=False): 

208 """allow grouping a range of consecutive rows or columns together 

209 

210 :param start: first row or column to be grouped (mandatory) 

211 :param end: last row or column to be grouped (optional, default to start) 

212 :param outline_level: outline level 

213 :param hidden: should the group be hidden on workbook open or not 

214 """ 

215 if end is None: 

216 end = start 

217 

218 if isinstance(self.default_factory(), ColumnDimension): 

219 new_dim = self[start] 

220 new_dim.outline_level = outline_level 

221 new_dim.hidden = hidden 

222 work_sequence = get_column_interval(start, end)[1:] 

223 for column_letter in work_sequence: 

224 if column_letter in self: 

225 del self[column_letter] 

226 new_dim.min, new_dim.max = map(column_index_from_string, (start, end)) 

227 elif isinstance(self.default_factory(), RowDimension): 

228 for el in range(start, end + 1): 

229 new_dim = self.worksheet.row_dimensions[el] 

230 new_dim.outline_level = outline_level 

231 new_dim.hidden = hidden 

232 

233 

234 def to_tree(self): 

235 

236 def sorter(value): 

237 value.reindex() 

238 return value.min 

239 

240 el = Element('cols') 

241 outlines = set() 

242 

243 for col in sorted(self.values(), key=sorter): 

244 obj = col.to_tree() 

245 if obj is not None: 

246 outlines.add(col.outlineLevel) 

247 el.append(obj) 

248 

249 if outlines: 

250 self.max_outline = max(outlines) 

251 

252 if len(el): 

253 return el # must have at least one child 

254 

255 

256class SheetFormatProperties(Serialisable): 

257 

258 tagname = "sheetFormatPr" 

259 

260 baseColWidth = Integer(allow_none=True) 

261 defaultColWidth = Float(allow_none=True) 

262 defaultRowHeight = Float() 

263 customHeight = Bool(allow_none=True) 

264 zeroHeight = Bool(allow_none=True) 

265 thickTop = Bool(allow_none=True) 

266 thickBottom = Bool(allow_none=True) 

267 outlineLevelRow = Integer(allow_none=True) 

268 outlineLevelCol = Integer(allow_none=True) 

269 

270 def __init__(self, 

271 baseColWidth=8, #according to spec 

272 defaultColWidth=None, 

273 defaultRowHeight=15, 

274 customHeight=None, 

275 zeroHeight=None, 

276 thickTop=None, 

277 thickBottom=None, 

278 outlineLevelRow=None, 

279 outlineLevelCol=None, 

280 ): 

281 self.baseColWidth = baseColWidth 

282 self.defaultColWidth = defaultColWidth 

283 self.defaultRowHeight = defaultRowHeight 

284 self.customHeight = customHeight 

285 self.zeroHeight = zeroHeight 

286 self.thickTop = thickTop 

287 self.thickBottom = thickBottom 

288 self.outlineLevelRow = outlineLevelRow 

289 self.outlineLevelCol = outlineLevelCol 

290 

291 

292class SheetDimension(Serialisable): 

293 

294 tagname = "dimension" 

295 

296 ref = String() 

297 

298 def __init__(self, 

299 ref=None, 

300 ): 

301 self.ref = ref 

302 

303 

304 @property 

305 def boundaries(self): 

306 return range_boundaries(self.ref)