easy_docx_template/
docx.rs

1use std::collections::HashMap;
2use serde_json::{to_string, Value};
3use crate::utils::*;
4
5/// # DOCX struct
6///
7/// create template for docx file
8///
9/// `file_name` - docx file input name
10///
11/// `content` - content of word file
12///
13/// `placeholder`/`placeholder_block`/`placeholder_images` - saving your placeholders
14pub struct DOCX {
15    pub content: HashMap<String, String>,
16    pub file_name: String,
17    pub placeholders: HashMap<String, Value>,
18    pub placeholders_blocks: HashMap<String, String>,
19    pub placeholder_images: HashMap<String, String>,
20}
21
22impl DOCX {
23    /// Create new docx manager
24    ///
25    /// `file_name` input file name
26    pub fn new(file_name: String) -> DOCX {
27        DOCX {
28            file_name,
29            content: HashMap::new(),
30            placeholders: HashMap::new(),
31            placeholders_blocks: HashMap::new(),
32            placeholder_images: HashMap::new(),
33        }
34    }
35
36    /// Read DOCX file
37    pub fn read(&mut self) {
38        self.content = read_raw_docx(&self.file_name);
39    }
40
41    /// Add placeholders to DOCX
42    ///
43    /// `placeholder` - Placeholder
44    ///
45    /// `replaced_content` - value for placeholder
46    pub fn add_placeholder<T>(&mut self, placeholder: &str, replaced_content: T) where Value: From<T> {
47        self.placeholders.insert(placeholder.to_string(), Value::from(replaced_content));
48    }
49
50    /// Add placeholders from json
51    ///
52    /// `placeholders_content` - json data
53    pub fn add_placeholders_from_json(&mut self, placeholders_content: &str) {
54        let v: Value = serde_json::from_str(placeholders_content).unwrap();
55        if let Value::Object(map) = v {
56            process_json_map(self,"", &map);
57        }
58    }
59
60    /// Add image placeholder
61    ///
62    /// `placeholder` id of image in docx
63    /// `image` directory of image for replace
64    pub fn add_image_placeholder(&mut self, placeholder: &str, image: &str) {
65        let media_dir = "word/media/";
66        self.placeholder_images.insert(format!("{}{}", media_dir, placeholder.to_string()), image.to_string());
67    }
68
69    /// Remove image placeholder
70    ///
71    /// `placeholder` - placeholder tag
72    pub fn remove_image_placeholder(&mut self, placeholder: &str) {
73        let media_dir = "word/media/";
74        self.placeholder_images.remove(&format!("{}{}", media_dir, placeholder));
75    }
76
77    /// Init placeholders
78    pub fn init_placeholders(&mut self) {
79        let mut new_content = HashMap::new();
80        self.placeholders = add_placeholder_helpers(&mut self.placeholders);
81        let rendered = init_each_placeholders(self.content["word/document.xml"].clone(), &mut self.placeholders);
82        let _ = self.content["word/document.xml"].replace(&self.content["word/document.xml"], &*rendered);
83        for (k, v) in &self.content {
84            new_content.insert(k.to_string(), init_placeholders(&mut self.placeholders, v));
85        }
86        self.content = new_content;
87    }
88
89    /// save output file
90    ///
91    /// `output` - output
92    pub fn save(&self, output: &str) {
93        let result = render_docx(&self);
94        std::fs::write(output, result).unwrap();
95    }
96
97    /// Render docx file
98    ///
99    /// You can use this in web
100    pub fn render(&self) -> Vec<u8> {
101        render_docx(&self)
102    }
103}