Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/openpyxl/formatting/rule.py: 47%

143 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1# Copyright (c) 2010-2022 openpyxl 

2 

3from openpyxl.descriptors.serialisable import Serialisable 

4from openpyxl.descriptors import ( 

5 Typed, 

6 String, 

7 Sequence, 

8 Bool, 

9 NoneSet, 

10 Set, 

11 Integer, 

12 Float, 

13) 

14from openpyxl.descriptors.excel import ExtensionList 

15from openpyxl.styles.colors import Color, ColorDescriptor 

16from openpyxl.styles.differential import DifferentialStyle 

17 

18from openpyxl.utils.cell import COORD_RE 

19 

20 

21class ValueDescriptor(Float): 

22 """ 

23 Expected type depends upon type attribue of parent :-( 

24 

25 Most values should be numeric BUT they can also be cell references 

26 """ 

27 

28 def __set__(self, instance, value): 

29 ref = None 

30 if value is not None and isinstance(value, str): 

31 ref = COORD_RE.match(value) 

32 if instance.type == "formula" or ref: 

33 self.expected_type = str 

34 else: 

35 self.expected_type = float 

36 super(ValueDescriptor, self).__set__(instance, value) 

37 

38 

39class FormatObject(Serialisable): 

40 

41 tagname = "cfvo" 

42 

43 type = Set(values=(['num', 'percent', 'max', 'min', 'formula', 'percentile'])) 

44 val = ValueDescriptor(allow_none=True) 

45 gte = Bool(allow_none=True) 

46 extLst = Typed(expected_type=ExtensionList, allow_none=True) 

47 

48 __elements__ = () 

49 

50 def __init__(self, 

51 type, 

52 val=None, 

53 gte=None, 

54 extLst=None, 

55 ): 

56 self.type = type 

57 self.val = val 

58 self.gte = gte 

59 

60 

61class RuleType(Serialisable): 

62 

63 cfvo = Sequence(expected_type=FormatObject) 

64 

65 

66class IconSet(RuleType): 

67 

68 tagname = "iconSet" 

69 

70 iconSet = NoneSet(values=(['3Arrows', '3ArrowsGray', '3Flags', 

71 '3TrafficLights1', '3TrafficLights2', '3Signs', '3Symbols', '3Symbols2', 

72 '4Arrows', '4ArrowsGray', '4RedToBlack', '4Rating', '4TrafficLights', 

73 '5Arrows', '5ArrowsGray', '5Rating', '5Quarters'])) 

74 showValue = Bool(allow_none=True) 

75 percent = Bool(allow_none=True) 

76 reverse = Bool(allow_none=True) 

77 

78 __elements__ = ("cfvo",) 

79 

80 def __init__(self, 

81 iconSet=None, 

82 showValue=None, 

83 percent=None, 

84 reverse=None, 

85 cfvo=None, 

86 ): 

87 self.iconSet = iconSet 

88 self.showValue = showValue 

89 self.percent = percent 

90 self.reverse = reverse 

91 self.cfvo = cfvo 

92 

93 

94class DataBar(RuleType): 

95 

96 tagname = "dataBar" 

97 

98 minLength = Integer(allow_none=True) 

99 maxLength = Integer(allow_none=True) 

100 showValue = Bool(allow_none=True) 

101 color = ColorDescriptor() 

102 

103 __elements__ = ('cfvo', 'color') 

104 

105 def __init__(self, 

106 minLength=None, 

107 maxLength=None, 

108 showValue=None, 

109 cfvo=None, 

110 color=None, 

111 ): 

112 self.minLength = minLength 

113 self.maxLength = maxLength 

114 self.showValue = showValue 

115 self.cfvo = cfvo 

116 self.color = color 

117 

118 

119class ColorScale(RuleType): 

120 

121 tagname = "colorScale" 

122 

123 color = Sequence(expected_type=Color) 

124 

125 __elements__ = ('cfvo', 'color') 

126 

127 def __init__(self, 

128 cfvo=None, 

129 color=None, 

130 ): 

131 self.cfvo = cfvo 

132 self.color = color 

133 

134 

135class Rule(Serialisable): 

136 

137 tagname = "cfRule" 

138 

139 type = Set(values=(['expression', 'cellIs', 'colorScale', 'dataBar', 

140 'iconSet', 'top10', 'uniqueValues', 'duplicateValues', 'containsText', 

141 'notContainsText', 'beginsWith', 'endsWith', 'containsBlanks', 

142 'notContainsBlanks', 'containsErrors', 'notContainsErrors', 'timePeriod', 

143 'aboveAverage'])) 

144 dxfId = Integer(allow_none=True) 

145 priority = Integer() 

146 stopIfTrue = Bool(allow_none=True) 

147 aboveAverage = Bool(allow_none=True) 

148 percent = Bool(allow_none=True) 

149 bottom = Bool(allow_none=True) 

150 operator = NoneSet(values=(['lessThan', 'lessThanOrEqual', 'equal', 

151 'notEqual', 'greaterThanOrEqual', 'greaterThan', 'between', 'notBetween', 

152 'containsText', 'notContains', 'beginsWith', 'endsWith'])) 

153 text = String(allow_none=True) 

154 timePeriod = NoneSet(values=(['today', 'yesterday', 'tomorrow', 'last7Days', 

155 'thisMonth', 'lastMonth', 'nextMonth', 'thisWeek', 'lastWeek', 

156 'nextWeek'])) 

157 rank = Integer(allow_none=True) 

158 stdDev = Integer(allow_none=True) 

159 equalAverage = Bool(allow_none=True) 

160 formula = Sequence(expected_type=str) 

161 colorScale = Typed(expected_type=ColorScale, allow_none=True) 

162 dataBar = Typed(expected_type=DataBar, allow_none=True) 

163 iconSet = Typed(expected_type=IconSet, allow_none=True) 

164 extLst = Typed(expected_type=ExtensionList, allow_none=True) 

165 dxf = Typed(expected_type=DifferentialStyle, allow_none=True) 

166 

167 __elements__ = ('colorScale', 'dataBar', 'iconSet', 'formula') 

168 __attrs__ = ('type', 'rank', 'priority', 'equalAverage', 'operator', 

169 'aboveAverage', 'dxfId', 'stdDev', 'stopIfTrue', 'timePeriod', 'text', 

170 'percent', 'bottom') 

171 

172 

173 def __init__(self, 

174 type, 

175 dxfId=None, 

176 priority=0, 

177 stopIfTrue=None, 

178 aboveAverage=None, 

179 percent=None, 

180 bottom=None, 

181 operator=None, 

182 text=None, 

183 timePeriod=None, 

184 rank=None, 

185 stdDev=None, 

186 equalAverage=None, 

187 formula=(), 

188 colorScale=None, 

189 dataBar=None, 

190 iconSet=None, 

191 extLst=None, 

192 dxf=None, 

193 ): 

194 self.type = type 

195 self.dxfId = dxfId 

196 self.priority = priority 

197 self.stopIfTrue = stopIfTrue 

198 self.aboveAverage = aboveAverage 

199 self.percent = percent 

200 self.bottom = bottom 

201 self.operator = operator 

202 self.text = text 

203 self.timePeriod = timePeriod 

204 self.rank = rank 

205 self.stdDev = stdDev 

206 self.equalAverage = equalAverage 

207 self.formula = formula 

208 self.colorScale = colorScale 

209 self.dataBar = dataBar 

210 self.iconSet = iconSet 

211 self.dxf = dxf 

212 

213 

214def ColorScaleRule(start_type=None, 

215 start_value=None, 

216 start_color=None, 

217 mid_type=None, 

218 mid_value=None, 

219 mid_color=None, 

220 end_type=None, 

221 end_value=None, 

222 end_color=None): 

223 

224 """Backwards compatibility""" 

225 formats = [] 

226 if start_type is not None: 

227 formats.append(FormatObject(type=start_type, val=start_value)) 

228 if mid_type is not None: 

229 formats.append(FormatObject(type=mid_type, val=mid_value)) 

230 if end_type is not None: 

231 formats.append(FormatObject(type=end_type, val=end_value)) 

232 colors = [] 

233 for v in (start_color, mid_color, end_color): 

234 if v is not None: 

235 if not isinstance(v, Color): 

236 v = Color(v) 

237 colors.append(v) 

238 cs = ColorScale(cfvo=formats, color=colors) 

239 rule = Rule(type="colorScale", colorScale=cs) 

240 return rule 

241 

242 

243def FormulaRule(formula=None, stopIfTrue=None, font=None, border=None, 

244 fill=None): 

245 """ 

246 Conditional formatting with custom differential style 

247 """ 

248 rule = Rule(type="expression", formula=formula, stopIfTrue=stopIfTrue) 

249 rule.dxf = DifferentialStyle(font=font, border=border, fill=fill) 

250 return rule 

251 

252 

253def CellIsRule(operator=None, formula=None, stopIfTrue=None, font=None, border=None, fill=None): 

254 """ 

255 Conditional formatting rule based on cell contents. 

256 """ 

257 # Excel doesn't use >, >=, etc, but allow for ease of python development 

258 expand = {">": "greaterThan", ">=": "greaterThanOrEqual", "<": "lessThan", "<=": "lessThanOrEqual", 

259 "=": "equal", "==": "equal", "!=": "notEqual"} 

260 

261 operator = expand.get(operator, operator) 

262 

263 rule = Rule(type='cellIs', operator=operator, formula=formula, stopIfTrue=stopIfTrue) 

264 rule.dxf = DifferentialStyle(font=font, border=border, fill=fill) 

265 

266 return rule 

267 

268 

269def IconSetRule(icon_style=None, type=None, values=None, showValue=None, percent=None, reverse=None): 

270 """ 

271 Convenience function for creating icon set rules 

272 """ 

273 cfvo = [] 

274 for val in values: 

275 cfvo.append(FormatObject(type, val)) 

276 icon_set = IconSet(iconSet=icon_style, cfvo=cfvo, showValue=showValue, 

277 percent=percent, reverse=reverse) 

278 rule = Rule(type='iconSet', iconSet=icon_set) 

279 

280 return rule 

281 

282 

283def DataBarRule(start_type=None, start_value=None, end_type=None, 

284 end_value=None, color=None, showValue=None, minLength=None, maxLength=None): 

285 start = FormatObject(start_type, start_value) 

286 end = FormatObject(end_type, end_value) 

287 data_bar = DataBar(cfvo=[start, end], color=color, showValue=showValue, 

288 minLength=minLength, maxLength=maxLength) 

289 rule = Rule(type='dataBar', dataBar=data_bar) 

290 

291 return rule