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

91 statements  

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# 

9 

10from typing import Dict, List, Tuple 

11 

12from . import xmlwriter 

13 

14 

15class App(xmlwriter.XMLwriter): 

16 """ 

17 A class for writing the Excel XLSX App file. 

18 

19 

20 """ 

21 

22 ########################################################################### 

23 # 

24 # Public API. 

25 # 

26 ########################################################################### 

27 

28 def __init__(self): 

29 """ 

30 Constructor. 

31 

32 """ 

33 

34 super().__init__() 

35 

36 self.part_names = [] 

37 self.heading_pairs = [] 

38 self.properties = {} 

39 self.doc_security = 0 

40 

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) 

44 

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'. 

48 

49 # Ignore empty pairs such as chartsheets. 

50 if not heading_pair[1]: 

51 return 

52 

53 self.heading_pairs.append(("lpstr", heading_pair[0])) 

54 self.heading_pairs.append(("i4", heading_pair[1])) 

55 

56 def _set_properties(self, properties: Dict[str, str]): 

57 # Set the document properties. 

58 self.properties = properties 

59 

60 ########################################################################### 

61 # 

62 # Private API. 

63 # 

64 ########################################################################### 

65 

66 def _assemble_xml_file(self): 

67 # Assemble and write the XML file. 

68 

69 # Write the XML declaration. 

70 self._xml_declaration() 

71 

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() 

85 

86 self._xml_end_tag("Properties") 

87 

88 # Close the file. 

89 self._xml_close() 

90 

91 ########################################################################### 

92 # 

93 # XML methods. 

94 # 

95 ########################################################################### 

96 

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" 

102 

103 attributes = [ 

104 ("xmlns", xmlns), 

105 ("xmlns:vt", xmlns_vt), 

106 ] 

107 

108 self._xml_start_tag("Properties", attributes) 

109 

110 def _write_application(self): 

111 # Write the <Application> element. 

112 self._xml_data_element("Application", "Microsoft Excel") 

113 

114 def _write_doc_security(self): 

115 # Write the <DocSecurity> element. 

116 self._xml_data_element("DocSecurity", self.doc_security) 

117 

118 def _write_scale_crop(self): 

119 # Write the <ScaleCrop> element. 

120 self._xml_data_element("ScaleCrop", "false") 

121 

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") 

127 

128 def _write_titles_of_parts(self): 

129 # Write the <TitlesOfParts> element. 

130 parts_data = [] 

131 

132 self._xml_start_tag("TitlesOfParts") 

133 

134 for part_name in self.part_names: 

135 parts_data.append(("lpstr", part_name)) 

136 

137 self._write_vt_vector("lpstr", parts_data) 

138 

139 self._xml_end_tag("TitlesOfParts") 

140 

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 ] 

147 

148 self._xml_start_tag("vt:vector", attributes) 

149 

150 for vt_data in vector_data: 

151 if base_type == "variant": 

152 self._xml_start_tag("vt:variant") 

153 

154 self._write_vt_data(vt_data) 

155 

156 if base_type == "variant": 

157 self._xml_end_tag("vt:variant") 

158 

159 self._xml_end_tag("vt:vector") 

160 

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]) 

164 

165 def _write_company(self): 

166 company = self.properties.get("company", "") 

167 

168 self._xml_data_element("Company", company) 

169 

170 def _write_manager(self): 

171 # Write the <Manager> element. 

172 if "manager" not in self.properties: 

173 return 

174 

175 self._xml_data_element("Manager", self.properties["manager"]) 

176 

177 def _write_links_up_to_date(self): 

178 # Write the <LinksUpToDate> element. 

179 self._xml_data_element("LinksUpToDate", "false") 

180 

181 def _write_shared_doc(self): 

182 # Write the <SharedDoc> element. 

183 self._xml_data_element("SharedDoc", "false") 

184 

185 def _write_hyperlink_base(self): 

186 # Write the <HyperlinkBase> element. 

187 hyperlink_base = self.properties.get("hyperlink_base") 

188 

189 if hyperlink_base is None: 

190 return 

191 

192 self._xml_data_element("HyperlinkBase", hyperlink_base) 

193 

194 def _write_hyperlinks_changed(self): 

195 # Write the <HyperlinksChanged> element. 

196 self._xml_data_element("HyperlinksChanged", "false") 

197 

198 def _write_app_version(self): 

199 # Write the <AppVersion> element. 

200 self._xml_data_element("AppVersion", "12.0000")