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
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
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#
10from . import xmlwriter
13class Metadata(xmlwriter.XMLwriter):
14 """
15 A class for writing the Excel XLSX Metadata file.
18 """
20 ###########################################################################
21 #
22 # Public API.
23 #
24 ###########################################################################
26 def __init__(self) -> None:
27 """
28 Constructor.
30 """
32 super().__init__()
33 self.has_dynamic_functions = False
34 self.has_embedded_images = False
35 self.num_embedded_images = 0
37 ###########################################################################
38 #
39 # Private API.
40 #
41 ###########################################################################
43 def _assemble_xml_file(self) -> None:
44 # Assemble and write the XML file.
46 if self.num_embedded_images > 0:
47 self.has_embedded_images = True
49 # Write the XML declaration.
50 self._xml_declaration()
52 # Write the metadata element.
53 self._write_metadata()
55 # Write the metadataTypes element.
56 self._write_metadata_types()
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()
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()
70 self._xml_end_tag("metadata")
72 # Close the file.
73 self._xml_close()
75 ###########################################################################
76 #
77 # XML methods.
78 #
79 ###########################################################################
81 def _write_metadata(self) -> None:
82 # Write the <metadata> element.
83 xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
84 schema = "http://schemas.microsoft.com/office/spreadsheetml"
86 attributes = [("xmlns", xmlns)]
88 if self.has_embedded_images:
89 attributes.append(("xmlns:xlrd", schema + "/2017/richdata"))
91 if self.has_dynamic_functions:
92 attributes.append(("xmlns:xda", schema + "/2017/dynamicarray"))
94 self._xml_start_tag("metadata", attributes)
96 def _write_metadata_types(self) -> None:
97 # Write the <metadataTypes> element.
98 count = 0
100 if self.has_dynamic_functions:
101 count += 1
102 if self.has_embedded_images:
103 count += 1
105 attributes = [("count", count)]
107 self._xml_start_tag("metadataTypes", attributes)
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()
115 self._xml_end_tag("metadataTypes")
117 def _write_cell_metadata_type(self) -> None:
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 ]
135 self._xml_empty_tag("metadataType", attributes)
137 def _write_value_metadata_type(self) -> None:
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 ]
154 self._xml_empty_tag("metadataType", attributes)
156 def _write_cell_future_metadata(self) -> None:
157 # Write the <futureMetadata> element.
158 attributes = [
159 ("name", "XLDAPR"),
160 ("count", 1),
161 ]
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")
171 def _write_value_future_metadata(self) -> None:
172 # Write the <futureMetadata> element.
173 attributes = [
174 ("name", "XLRICHVALUE"),
175 ("count", self.num_embedded_images),
176 ]
178 self._xml_start_tag("futureMetadata", attributes)
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")
187 self._xml_end_tag("futureMetadata")
189 def _write_cell_ext(self) -> None:
190 # Write the <ext> element.
191 attributes = [("uri", "{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}")]
193 self._xml_start_tag("ext", attributes)
195 # Write the xda:dynamicArrayProperties element.
196 self._write_xda_dynamic_array_properties()
198 self._xml_end_tag("ext")
200 def _write_xda_dynamic_array_properties(self) -> None:
201 # Write the <xda:dynamicArrayProperties> element.
202 attributes = [
203 ("fDynamic", 1),
204 ("fCollapsed", 0),
205 ]
207 self._xml_empty_tag("xda:dynamicArrayProperties", attributes)
209 def _write_value_ext(self, index) -> None:
210 # Write the <ext> element.
211 attributes = [("uri", "{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}")]
213 self._xml_start_tag("ext", attributes)
215 # Write the xlrd:rvb element.
216 self._write_xlrd_rvb(index)
218 self._xml_end_tag("ext")
220 def _write_xlrd_rvb(self, index) -> None:
221 # Write the <xlrd:rvb> element.
222 attributes = [("i", index)]
224 self._xml_empty_tag("xlrd:rvb", attributes)
226 def _write_cell_metadata(self) -> None:
227 # Write the <cellMetadata> element.
228 attributes = [("count", 1)]
230 self._xml_start_tag("cellMetadata", attributes)
231 self._xml_start_tag("bk")
233 # Write the rc element.
234 self._write_rc(1, 0)
236 self._xml_end_tag("bk")
237 self._xml_end_tag("cellMetadata")
239 def _write_value_metadata(self) -> None:
240 # Write the <valueMetadata> element.
241 count = self.num_embedded_images
242 rc_type = 1
244 if self.has_dynamic_functions:
245 rc_type = 2
247 attributes = [("count", count)]
249 self._xml_start_tag("valueMetadata", attributes)
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")
257 self._xml_end_tag("valueMetadata")
259 def _write_rc(self, rc_type, index) -> None:
260 # Write the <rc> element.
261 attributes = [
262 ("t", rc_type),
263 ("v", index),
264 ]
266 self._xml_empty_tag("rc", attributes)