Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/xlsxwriter/app.py: 97%
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# App - A class for writing the Excel XLSX App file.
4#
5# SPDX-License-Identifier: BSD-2-Clause
6#
7# Copyright (c) 2013-2025, John McNamara, jmcnamara@cpan.org
8#
10from typing import Dict, List, Tuple
12from . import xmlwriter
15class App(xmlwriter.XMLwriter):
16 """
17 A class for writing the Excel XLSX App file.
20 """
22 ###########################################################################
23 #
24 # Public API.
25 #
26 ###########################################################################
28 def __init__(self):
29 """
30 Constructor.
32 """
34 super().__init__()
36 self.part_names = []
37 self.heading_pairs = []
38 self.properties = {}
39 self.doc_security = 0
41 def _add_part_name(self, part_name: str):
42 # Add the name of a workbook Part such as 'Sheet1' or 'Print_Titles'.
43 self.part_names.append(part_name)
45 def _add_heading_pair(self, heading_pair: Tuple[str, int]):
46 # Add the name of a workbook Heading Pair such as 'Worksheets',
47 # 'Charts' or 'Named Ranges'.
49 # Ignore empty pairs such as chartsheets.
50 if not heading_pair[1]:
51 return
53 self.heading_pairs.append(("lpstr", heading_pair[0]))
54 self.heading_pairs.append(("i4", heading_pair[1]))
56 def _set_properties(self, properties: Dict[str, str]):
57 # Set the document properties.
58 self.properties = properties
60 ###########################################################################
61 #
62 # Private API.
63 #
64 ###########################################################################
66 def _assemble_xml_file(self):
67 # Assemble and write the XML file.
69 # Write the XML declaration.
70 self._xml_declaration()
72 self._write_properties()
73 self._write_application()
74 self._write_doc_security()
75 self._write_scale_crop()
76 self._write_heading_pairs()
77 self._write_titles_of_parts()
78 self._write_manager()
79 self._write_company()
80 self._write_links_up_to_date()
81 self._write_shared_doc()
82 self._write_hyperlink_base()
83 self._write_hyperlinks_changed()
84 self._write_app_version()
86 self._xml_end_tag("Properties")
88 # Close the file.
89 self._xml_close()
91 ###########################################################################
92 #
93 # XML methods.
94 #
95 ###########################################################################
97 def _write_properties(self):
98 # Write the <Properties> element.
99 schema = "http://schemas.openxmlformats.org/officeDocument/2006/"
100 xmlns = schema + "extended-properties"
101 xmlns_vt = schema + "docPropsVTypes"
103 attributes = [
104 ("xmlns", xmlns),
105 ("xmlns:vt", xmlns_vt),
106 ]
108 self._xml_start_tag("Properties", attributes)
110 def _write_application(self):
111 # Write the <Application> element.
112 self._xml_data_element("Application", "Microsoft Excel")
114 def _write_doc_security(self):
115 # Write the <DocSecurity> element.
116 self._xml_data_element("DocSecurity", self.doc_security)
118 def _write_scale_crop(self):
119 # Write the <ScaleCrop> element.
120 self._xml_data_element("ScaleCrop", "false")
122 def _write_heading_pairs(self):
123 # Write the <HeadingPairs> element.
124 self._xml_start_tag("HeadingPairs")
125 self._write_vt_vector("variant", self.heading_pairs)
126 self._xml_end_tag("HeadingPairs")
128 def _write_titles_of_parts(self):
129 # Write the <TitlesOfParts> element.
130 parts_data = []
132 self._xml_start_tag("TitlesOfParts")
134 for part_name in self.part_names:
135 parts_data.append(("lpstr", part_name))
137 self._write_vt_vector("lpstr", parts_data)
139 self._xml_end_tag("TitlesOfParts")
141 def _write_vt_vector(self, base_type: str, vector_data: List[Tuple[str, int]]):
142 # Write the <vt:vector> element.
143 attributes = [
144 ("size", len(vector_data)),
145 ("baseType", base_type),
146 ]
148 self._xml_start_tag("vt:vector", attributes)
150 for vt_data in vector_data:
151 if base_type == "variant":
152 self._xml_start_tag("vt:variant")
154 self._write_vt_data(vt_data)
156 if base_type == "variant":
157 self._xml_end_tag("vt:variant")
159 self._xml_end_tag("vt:vector")
161 def _write_vt_data(self, vt_data: Tuple[str, int]):
162 # Write the <vt:*> elements such as <vt:lpstr> and <vt:if>.
163 self._xml_data_element(f"vt:{vt_data[0]}", vt_data[1])
165 def _write_company(self):
166 company = self.properties.get("company", "")
168 self._xml_data_element("Company", company)
170 def _write_manager(self):
171 # Write the <Manager> element.
172 if "manager" not in self.properties:
173 return
175 self._xml_data_element("Manager", self.properties["manager"])
177 def _write_links_up_to_date(self):
178 # Write the <LinksUpToDate> element.
179 self._xml_data_element("LinksUpToDate", "false")
181 def _write_shared_doc(self):
182 # Write the <SharedDoc> element.
183 self._xml_data_element("SharedDoc", "false")
185 def _write_hyperlink_base(self):
186 # Write the <HyperlinkBase> element.
187 hyperlink_base = self.properties.get("hyperlink_base")
189 if hyperlink_base is None:
190 return
192 self._xml_data_element("HyperlinkBase", hyperlink_base)
194 def _write_hyperlinks_changed(self):
195 # Write the <HyperlinksChanged> element.
196 self._xml_data_element("HyperlinksChanged", "false")
198 def _write_app_version(self):
199 # Write the <AppVersion> element.
200 self._xml_data_element("AppVersion", "12.0000")