Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/xlsxwriter/metadata.py: 68%

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

109 statements  

1############################################################################### 

2# 

3# Metadata - A class for writing the Excel XLSX Metadata file. 

4# 

5# SPDX-License-Identifier: BSD-2-Clause 

6# 

7# Copyright (c) 2013-2025, John McNamara, jmcnamara@cpan.org 

8# 

9 

10from . import xmlwriter 

11 

12 

13class Metadata(xmlwriter.XMLwriter): 

14 """ 

15 A class for writing the Excel XLSX Metadata file. 

16 

17 

18 """ 

19 

20 ########################################################################### 

21 # 

22 # Public API. 

23 # 

24 ########################################################################### 

25 

26 def __init__(self): 

27 """ 

28 Constructor. 

29 

30 """ 

31 

32 super().__init__() 

33 self.has_dynamic_functions = False 

34 self.has_embedded_images = False 

35 self.num_embedded_images = 0 

36 

37 ########################################################################### 

38 # 

39 # Private API. 

40 # 

41 ########################################################################### 

42 

43 def _assemble_xml_file(self): 

44 # Assemble and write the XML file. 

45 

46 if self.num_embedded_images > 0: 

47 self.has_embedded_images = True 

48 

49 # Write the XML declaration. 

50 self._xml_declaration() 

51 

52 # Write the metadata element. 

53 self._write_metadata() 

54 

55 # Write the metadataTypes element. 

56 self._write_metadata_types() 

57 

58 # Write the futureMetadata elements. 

59 if self.has_dynamic_functions: 

60 self._write_cell_future_metadata() 

61 if self.has_embedded_images: 

62 self._write_value_future_metadata() 

63 

64 # Write the cellMetadata element. 

65 if self.has_dynamic_functions: 

66 self._write_cell_metadata() 

67 if self.has_embedded_images: 

68 self._write_value_metadata() 

69 

70 self._xml_end_tag("metadata") 

71 

72 # Close the file. 

73 self._xml_close() 

74 

75 ########################################################################### 

76 # 

77 # XML methods. 

78 # 

79 ########################################################################### 

80 

81 def _write_metadata(self): 

82 # Write the <metadata> element. 

83 xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main" 

84 schema = "http://schemas.microsoft.com/office/spreadsheetml" 

85 

86 attributes = [("xmlns", xmlns)] 

87 

88 if self.has_embedded_images: 

89 attributes.append(("xmlns:xlrd", schema + "/2017/richdata")) 

90 

91 if self.has_dynamic_functions: 

92 attributes.append(("xmlns:xda", schema + "/2017/dynamicarray")) 

93 

94 self._xml_start_tag("metadata", attributes) 

95 

96 def _write_metadata_types(self): 

97 # Write the <metadataTypes> element. 

98 count = 0 

99 

100 if self.has_dynamic_functions: 

101 count += 1 

102 if self.has_embedded_images: 

103 count += 1 

104 

105 attributes = [("count", count)] 

106 

107 self._xml_start_tag("metadataTypes", attributes) 

108 

109 # Write the metadataType element. 

110 if self.has_dynamic_functions: 

111 self._write_cell_metadata_type() 

112 if self.has_embedded_images: 

113 self._write_value_metadata_type() 

114 

115 self._xml_end_tag("metadataTypes") 

116 

117 def _write_cell_metadata_type(self): 

118 # Write the <metadataType> element. 

119 attributes = [ 

120 ("name", "XLDAPR"), 

121 ("minSupportedVersion", 120000), 

122 ("copy", 1), 

123 ("pasteAll", 1), 

124 ("pasteValues", 1), 

125 ("merge", 1), 

126 ("splitFirst", 1), 

127 ("rowColShift", 1), 

128 ("clearFormats", 1), 

129 ("clearComments", 1), 

130 ("assign", 1), 

131 ("coerce", 1), 

132 ("cellMeta", 1), 

133 ] 

134 

135 self._xml_empty_tag("metadataType", attributes) 

136 

137 def _write_value_metadata_type(self): 

138 # Write the <metadataType> element. 

139 attributes = [ 

140 ("name", "XLRICHVALUE"), 

141 ("minSupportedVersion", 120000), 

142 ("copy", 1), 

143 ("pasteAll", 1), 

144 ("pasteValues", 1), 

145 ("merge", 1), 

146 ("splitFirst", 1), 

147 ("rowColShift", 1), 

148 ("clearFormats", 1), 

149 ("clearComments", 1), 

150 ("assign", 1), 

151 ("coerce", 1), 

152 ] 

153 

154 self._xml_empty_tag("metadataType", attributes) 

155 

156 def _write_cell_future_metadata(self): 

157 # Write the <futureMetadata> element. 

158 attributes = [ 

159 ("name", "XLDAPR"), 

160 ("count", 1), 

161 ] 

162 

163 self._xml_start_tag("futureMetadata", attributes) 

164 self._xml_start_tag("bk") 

165 self._xml_start_tag("extLst") 

166 self._write_cell_ext() 

167 self._xml_end_tag("extLst") 

168 self._xml_end_tag("bk") 

169 self._xml_end_tag("futureMetadata") 

170 

171 def _write_value_future_metadata(self): 

172 # Write the <futureMetadata> element. 

173 attributes = [ 

174 ("name", "XLRICHVALUE"), 

175 ("count", self.num_embedded_images), 

176 ] 

177 

178 self._xml_start_tag("futureMetadata", attributes) 

179 

180 for index in range(self.num_embedded_images): 

181 self._xml_start_tag("bk") 

182 self._xml_start_tag("extLst") 

183 self._write_value_ext(index) 

184 self._xml_end_tag("extLst") 

185 self._xml_end_tag("bk") 

186 

187 self._xml_end_tag("futureMetadata") 

188 

189 def _write_cell_ext(self): 

190 # Write the <ext> element. 

191 attributes = [("uri", "{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}")] 

192 

193 self._xml_start_tag("ext", attributes) 

194 

195 # Write the xda:dynamicArrayProperties element. 

196 self._write_xda_dynamic_array_properties() 

197 

198 self._xml_end_tag("ext") 

199 

200 def _write_xda_dynamic_array_properties(self): 

201 # Write the <xda:dynamicArrayProperties> element. 

202 attributes = [ 

203 ("fDynamic", 1), 

204 ("fCollapsed", 0), 

205 ] 

206 

207 self._xml_empty_tag("xda:dynamicArrayProperties", attributes) 

208 

209 def _write_value_ext(self, index): 

210 # Write the <ext> element. 

211 attributes = [("uri", "{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}")] 

212 

213 self._xml_start_tag("ext", attributes) 

214 

215 # Write the xlrd:rvb element. 

216 self._write_xlrd_rvb(index) 

217 

218 self._xml_end_tag("ext") 

219 

220 def _write_xlrd_rvb(self, index): 

221 # Write the <xlrd:rvb> element. 

222 attributes = [("i", index)] 

223 

224 self._xml_empty_tag("xlrd:rvb", attributes) 

225 

226 def _write_cell_metadata(self): 

227 # Write the <cellMetadata> element. 

228 attributes = [("count", 1)] 

229 

230 self._xml_start_tag("cellMetadata", attributes) 

231 self._xml_start_tag("bk") 

232 

233 # Write the rc element. 

234 self._write_rc(1, 0) 

235 

236 self._xml_end_tag("bk") 

237 self._xml_end_tag("cellMetadata") 

238 

239 def _write_value_metadata(self): 

240 # Write the <valueMetadata> element. 

241 count = self.num_embedded_images 

242 rc_type = 1 

243 

244 if self.has_dynamic_functions: 

245 rc_type = 2 

246 

247 attributes = [("count", count)] 

248 

249 self._xml_start_tag("valueMetadata", attributes) 

250 

251 # Write the rc elements. 

252 for index in range(self.num_embedded_images): 

253 self._xml_start_tag("bk") 

254 self._write_rc(rc_type, index) 

255 self._xml_end_tag("bk") 

256 

257 self._xml_end_tag("valueMetadata") 

258 

259 def _write_rc(self, rc_type, index): 

260 # Write the <rc> element. 

261 attributes = [ 

262 ("t", rc_type), 

263 ("v", index), 

264 ] 

265 

266 self._xml_empty_tag("rc", attributes)