1use crate::helper::const_str::*;
2use crate::reader::driver::*;
3use crate::structs::custom_properties::Properties as CustomProperties;
4use crate::structs::StringValue;
5use crate::structs::Worksheet;
6use crate::writer::driver::*;
7use quick_xml::events::BytesStart;
8use quick_xml::events::Event;
9use quick_xml::Reader;
10use quick_xml::Writer;
11use std::borrow::Cow;
12use std::io::Cursor;
13
14#[derive(Clone, Debug)]
15pub struct Properties {
16 creator: StringValue,
17 last_modified_by: StringValue,
18 created: StringValue,
19 modified: StringValue,
20 title: StringValue,
21 description: StringValue,
22 subject: StringValue,
23 keywords: StringValue,
24 category: StringValue,
25 manager: StringValue,
26 company: StringValue,
27 revision: StringValue,
28 version: StringValue,
29 custom_properties: CustomProperties,
30}
31impl Default for Properties {
32 #[inline]
33 fn default() -> Self {
34 let mut created = StringValue::default();
35 let mut modified = StringValue::default();
36 created.set_value("2006-09-16T00:00:00Z");
37 modified.set_value("2006-09-16T00:00:00Z");
38 Self {
39 creator: StringValue::default(),
40 last_modified_by: StringValue::default(),
41 created,
42 modified,
43 title: StringValue::default(),
44 description: StringValue::default(),
45 subject: StringValue::default(),
46 keywords: StringValue::default(),
47 category: StringValue::default(),
48 manager: StringValue::default(),
49 company: StringValue::default(),
50 revision: StringValue::default(),
51 version: StringValue::default(),
52 custom_properties: CustomProperties::default(),
53 }
54 }
55}
56impl Properties {
57 #[inline]
58 pub fn get_creator(&self) -> &str {
59 &self.creator.get_value_str()
60 }
61
62 #[inline]
63 pub fn set_creator<S: Into<String>>(&mut self, value: S) -> &mut Self {
64 self.creator.set_value(value);
65 self
66 }
67
68 #[inline]
69 pub fn get_last_modified_by(&self) -> &str {
70 &self.last_modified_by.get_value_str()
71 }
72
73 #[inline]
74 pub fn set_last_modified_by<S: Into<String>>(&mut self, value: S) -> &mut Self {
75 self.last_modified_by.set_value(value);
76 self
77 }
78
79 #[inline]
80 pub fn get_created(&self) -> &str {
81 &self.created.get_value_str()
82 }
83
84 #[inline]
85 pub fn set_created<S: Into<String>>(&mut self, value: S) -> &mut Self {
86 self.created.set_value(value);
87 self
88 }
89
90 #[inline]
91 pub fn get_modified(&self) -> &str {
92 &self.modified.get_value_str()
93 }
94
95 #[inline]
96 pub fn set_modified<S: Into<String>>(&mut self, value: S) -> &mut Self {
97 self.modified.set_value(value);
98 self
99 }
100
101 #[inline]
102 pub fn get_title(&self) -> &str {
103 &self.title.get_value_str()
104 }
105
106 #[inline]
107 pub fn set_title<S: Into<String>>(&mut self, value: S) -> &mut Self {
108 self.title.set_value(value);
109 self
110 }
111
112 #[inline]
113 pub fn get_description(&self) -> &str {
114 &self.description.get_value_str()
115 }
116
117 #[inline]
118 pub fn set_description<S: Into<String>>(&mut self, value: S) -> &mut Self {
119 self.description.set_value(value);
120 self
121 }
122
123 #[inline]
124 pub fn get_subject(&self) -> &str {
125 &self.subject.get_value_str()
126 }
127
128 #[inline]
129 pub fn set_subject<S: Into<String>>(&mut self, value: S) -> &mut Self {
130 self.subject.set_value(value);
131 self
132 }
133
134 #[inline]
135 pub fn get_keywords(&self) -> &str {
136 &self.keywords.get_value_str()
137 }
138
139 #[inline]
140 pub fn set_keywords<S: Into<String>>(&mut self, value: S) -> &mut Self {
141 self.keywords.set_value(value);
142 self
143 }
144
145 #[inline]
146 pub fn get_revision(&self) -> &str {
147 &self.revision.get_value_str()
148 }
149
150 #[inline]
151 pub fn set_revision<S: Into<String>>(&mut self, value: S) -> &mut Self {
152 self.revision.set_value(value);
153 self
154 }
155
156 #[inline]
157 pub fn get_category(&self) -> &str {
158 &self.category.get_value_str()
159 }
160
161 #[inline]
162 pub fn set_category<S: Into<String>>(&mut self, value: S) -> &mut Self {
163 self.category.set_value(value);
164 self
165 }
166
167 #[inline]
168 pub fn get_version(&self) -> &str {
169 &self.version.get_value_str()
170 }
171
172 #[inline]
173 pub fn set_version<S: Into<String>>(&mut self, value: S) -> &mut Self {
174 self.version.set_value(value);
175 self
176 }
177
178 #[inline]
179 pub fn get_manager(&self) -> &str {
180 &self.manager.get_value_str()
181 }
182
183 #[inline]
184 pub fn set_manager<S: Into<String>>(&mut self, value: S) -> &mut Self {
185 self.manager.set_value(value);
186 self
187 }
188
189 #[inline]
190 pub fn get_company(&self) -> &str {
191 &self.company.get_value_str()
192 }
193
194 #[inline]
195 pub fn set_company<S: Into<String>>(&mut self, value: S) -> &mut Self {
196 self.company.set_value(value);
197 self
198 }
199
200 #[inline]
201 pub fn get_custom_properties(&self) -> &CustomProperties {
202 &self.custom_properties
203 }
204
205 #[inline]
206 pub fn get_custom_properties_mut(&mut self) -> &mut CustomProperties {
207 &mut self.custom_properties
208 }
209
210 #[inline]
211 pub fn set_custom_properties(&mut self, value: CustomProperties) -> &mut Self {
212 self.custom_properties = value;
213 self
214 }
215
216 pub(crate) fn set_attributes_core<R: std::io::BufRead>(
217 &mut self,
218 reader: &mut Reader<R>,
219 _e: &BytesStart,
220 ) {
221 let mut value: String = String::new();
222 xml_read_loop!(
223 reader,
224 Event::Text(e) => {
225 value = e.unescape().unwrap().to_string();
226 },
227 Event::End(ref e) => match e.name().into_inner() {
228 b"dc:title" => {self.set_title(std::mem::take(&mut value));},
229 b"dc:subject" => {self.set_subject(std::mem::take(&mut value));},
230 b"dc:creator" => {self.set_creator(std::mem::take(&mut value));},
231 b"cp:keywords" => {self.set_keywords(std::mem::take(&mut value));},
232 b"dc:description" => {self.set_description(std::mem::take(&mut value));},
233 b"cp:lastModifiedBy" => {self.set_last_modified_by(std::mem::take(&mut value));},
234 b"cp:revision" => {self.set_revision(std::mem::take(&mut value));},
235 b"dcterms:created" => {self.set_created(std::mem::take(&mut value));},
236 b"dcterms:modified" => {self.set_modified(std::mem::take(&mut value));},
237 b"cp:category" => {self.set_category(std::mem::take(&mut value));},
238 b"cp:version" => {self.set_version(std::mem::take(&mut value));},
239 b"Manager" => {self.set_manager(std::mem::take(&mut value));},
240 b"Company" => {self.set_company(std::mem::take(&mut value));},
241 _ => {}
242 },
243 Event::Eof => return,
244 );
245 }
246
247 pub(crate) fn set_attributes_app<R: std::io::BufRead>(
248 &mut self,
249 reader: &mut Reader<R>,
250 _e: &BytesStart,
251 ) {
252 let mut value: String = String::new();
253 xml_read_loop!(
254 reader,
255 Event::Start(ref e) => {
256 match e.name().into_inner(){
257 b"Manager" => {value = String::new();},
258 b"Company" => {value = String::new();},
259 _ => {}
260 }
261 },
262 Event::Text(e) => {
263 value = e.unescape().unwrap().to_string();
264 },
265 Event::End(ref e) => match e.name().into_inner() {
266 b"Manager" => {self.set_manager(std::mem::take(&mut value));}
267 b"Company" => {self.set_company(std::mem::take(&mut value));}
268 _ =>{}
269 },
270 Event::Eof => return,
271 );
272 }
273
274 #[inline]
275 pub(crate) fn set_attributes_custom<R: std::io::BufRead>(
276 &mut self,
277 reader: &mut Reader<R>,
278 e: &BytesStart,
279 ) {
280 let mut obj = CustomProperties::default();
281 obj.set_attributes(reader, e);
282 self.set_custom_properties(obj);
283 }
284
285 pub(crate) fn write_to_core(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
286 write_start_tag(
288 writer,
289 "cp:coreProperties",
290 vec![
291 ("xmlns:cp", COREPROPS_NS),
292 ("xmlns:dc", DCORE_NS),
293 ("xmlns:dcterms", DCTERMS_NS),
294 ("xmlns:dcmitype", DCMITYPE_NS),
295 ("xmlns:xsi", XSI_NS),
296 ],
297 false,
298 );
299
300 if self.title.has_value() {
302 write_start_tag(writer, "dc:title", vec![], false);
303 write_text_node(writer, self.title.get_value_str());
304 write_end_tag(writer, "dc:title");
305 }
306
307 if self.subject.has_value() {
309 write_start_tag(writer, "dc:subject", vec![], false);
310 write_text_node(writer, self.subject.get_value_str());
311 write_end_tag(writer, "dc:subject");
312 }
313
314 if self.creator.has_value() {
316 write_start_tag(writer, "dc:creator", vec![], false);
317 write_text_node(writer, self.creator.get_value_str());
318 write_end_tag(writer, "dc:creator");
319 }
320
321 if self.keywords.has_value() {
323 write_start_tag(writer, "cp:keywords", vec![], false);
324 write_text_node(writer, self.keywords.get_value_str());
325 write_end_tag(writer, "cp:keywords");
326 }
327
328 if self.description.has_value() {
330 write_start_tag(writer, "dc:description", vec![], false);
331 write_text_node(writer, self.description.get_value_str());
332 write_end_tag(writer, "dc:description");
333 }
334
335 if self.last_modified_by.has_value() {
337 write_start_tag(writer, "cp:lastModifiedBy", vec![], false);
338 write_text_node(writer, self.last_modified_by.get_value_str());
339 write_end_tag(writer, "cp:lastModifiedBy");
340 }
341
342 if self.revision.has_value() {
344 write_start_tag(writer, "cp:revision", vec![], false);
345 write_text_node(writer, self.revision.get_value_str());
346 write_end_tag(writer, "cp:revision");
347 }
348
349 if self.created.has_value() {
351 write_start_tag(
352 writer,
353 "dcterms:created",
354 vec![("xsi:type", "dcterms:W3CDTF")],
355 false,
356 );
357 write_text_node(writer, self.created.get_value_str());
358 write_end_tag(writer, "dcterms:created");
359 }
360
361 if self.modified.has_value() {
363 write_start_tag(
364 writer,
365 "dcterms:modified",
366 vec![("xsi:type", "dcterms:W3CDTF")],
367 false,
368 );
369 write_text_node(writer, self.modified.get_value_str());
370 write_end_tag(writer, "dcterms:modified");
371 }
372
373 if self.category.has_value() {
375 write_start_tag(writer, "cp:category", vec![], false);
376 write_text_node(writer, self.category.get_value_str());
377 write_end_tag(writer, "cp:category");
378 }
379
380 if self.version.has_value() {
382 write_start_tag(writer, "cp:version", vec![], false);
383 write_text_node(writer, self.version.get_value_str());
384 write_end_tag(writer, "cp:version");
385 }
386
387 write_end_tag(writer, "cp:coreProperties");
388 }
389
390 pub(crate) fn write_to_app(
391 &self,
392 writer: &mut Writer<Cursor<Vec<u8>>>,
393 work_sheet_collection: &[Worksheet],
394 ) {
395 let sheet_count_str = work_sheet_collection.len().to_string();
396
397 write_start_tag(
399 writer,
400 "Properties",
401 vec![("xmlns", XPROPS_NS), ("xmlns:vt", VTYPES_NS)],
402 false,
403 );
404
405 write_start_tag(writer, "Application", vec![], false);
407 write_text_node(writer, "Microsoft Excel");
408 write_end_tag(writer, "Application");
409
410 write_start_tag(writer, "DocSecurity", vec![], false);
412 write_text_node(writer, "0");
413 write_end_tag(writer, "DocSecurity");
414
415 write_start_tag(writer, "ScaleCrop", vec![], false);
417 write_text_node(writer, "false");
418 write_end_tag(writer, "ScaleCrop");
419
420 write_start_tag(writer, "HeadingPairs", vec![], false);
422
423 write_start_tag(
425 writer,
426 "vt:vector",
427 vec![("size", "2"), ("baseType", "variant")],
428 false,
429 );
430
431 write_start_tag(writer, "vt:variant", vec![], false);
433
434 write_start_tag(writer, "vt:lpstr", vec![], false);
436 write_text_node(writer, "Worksheets");
437 write_end_tag(writer, "vt:lpstr");
438
439 write_end_tag(writer, "vt:variant");
440
441 write_start_tag(writer, "vt:variant", vec![], false);
443
444 write_start_tag(writer, "vt:i4", vec![], false);
446 write_text_node(writer, &sheet_count_str);
447 write_end_tag(writer, "vt:i4");
448
449 write_end_tag(writer, "vt:variant");
450
451 write_end_tag(writer, "vt:vector");
452
453 write_end_tag(writer, "HeadingPairs");
454
455 write_start_tag(writer, "TitlesOfParts", vec![], false);
457
458 write_start_tag(
460 writer,
461 "vt:vector",
462 vec![("size", &sheet_count_str), ("baseType", "lpstr")],
463 false,
464 );
465
466 for workseet in work_sheet_collection {
467 write_start_tag(writer, "vt:lpstr", vec![], false);
469 write_text_node(writer, workseet.get_name());
470 write_end_tag(writer, "vt:lpstr");
471 }
472
473 write_end_tag(writer, "vt:vector");
474
475 write_end_tag(writer, "TitlesOfParts");
476
477 write_start_tag(writer, "Manager", vec![], false);
479 write_text_node(writer, self.get_manager());
480 write_end_tag(writer, "Manager");
481
482 write_start_tag(writer, "Company", vec![], false);
484 write_text_node(writer, self.get_company());
485 write_end_tag(writer, "Company");
486
487 write_start_tag(writer, "LinksUpToDate", vec![], false);
489 write_text_node(writer, "false");
490 write_end_tag(writer, "LinksUpToDate");
491
492 write_start_tag(writer, "SharedDoc", vec![], false);
494 write_text_node(writer, "false");
495 write_end_tag(writer, "SharedDoc");
496
497 write_start_tag(writer, "HyperlinksChanged", vec![], false);
499 write_text_node(writer, "false");
500 write_end_tag(writer, "HyperlinksChanged");
501
502 write_start_tag(writer, "AppVersion", vec![], false);
504 write_text_node(writer, "14.0300");
505 write_end_tag(writer, "AppVersion");
506
507 write_end_tag(writer, "Properties");
508 }
509
510 #[inline]
511 pub(crate) fn write_to_custom(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
512 self.custom_properties.write_to(writer);
513 }
514}