Skip to main content

umya_spreadsheet/structs/
column.rs

1use super::BooleanValue;
2use super::DoubleValue;
3use super::Style;
4use super::Stylesheet;
5use super::UInt32Value;
6use crate::reader::driver::*;
7use crate::structs::Cells;
8use crate::traits::AdjustmentValue;
9use md5::Digest;
10use quick_xml::events::BytesStart;
11use quick_xml::Reader;
12
13/// # Examples
14/// ## set auto width
15/// ```rust
16/// use umya_spreadsheet::*;
17/// let mut book = new_file();
18/// let mut worksheet = book.get_sheet_by_name_mut("Sheet1").unwrap();
19/// worksheet.get_column_dimension_mut("A").set_auto_width(true);
20/// ```
21/// ## set manual width
22/// ```rust
23/// use umya_spreadsheet::*;
24/// let mut book = new_file();
25/// let mut worksheet = book.get_sheet_by_name_mut("Sheet1").unwrap();
26/// worksheet.get_column_dimension_mut("A").set_width(60f64);
27/// ```
28#[derive(Clone, Debug)]
29pub struct Column {
30    col_num: UInt32Value,
31    pub(crate) width: DoubleValue,
32    pub(crate) hidden: BooleanValue,
33    pub(crate) best_fit: BooleanValue,
34    style: Box<Style>,
35    auto_width: BooleanValue,
36}
37
38impl Default for Column {
39    #[inline]
40    fn default() -> Self {
41        let mut width = DoubleValue::default();
42        width.set_value(8.38f64);
43        Self {
44            col_num: UInt32Value::default(),
45            width,
46            hidden: BooleanValue::default(),
47            best_fit: BooleanValue::default(),
48            style: Box::new(Style::default()),
49            auto_width: BooleanValue::default(),
50        }
51    }
52}
53
54impl Column {
55    #[inline]
56    pub fn get_col_num(&self) -> &u32 {
57        self.col_num.get_value()
58    }
59
60    #[inline]
61    pub fn set_col_num(&mut self, value: u32) -> &mut Self {
62        self.col_num.set_value(value);
63        self
64    }
65
66    #[inline]
67    pub fn get_width(&self) -> &f64 {
68        self.width.get_value()
69    }
70
71    #[inline]
72    pub fn set_width(&mut self, value: f64) -> &mut Self {
73        self.width.set_value(value);
74        self
75    }
76
77    #[inline]
78    pub fn get_hidden(&self) -> &bool {
79        self.hidden.get_value()
80    }
81
82    #[inline]
83    pub fn set_hidden(&mut self, value: bool) -> &mut Self {
84        self.hidden.set_value(value);
85        self
86    }
87
88    #[inline]
89    pub fn get_best_fit(&self) -> &bool {
90        self.best_fit.get_value()
91    }
92
93    #[inline]
94    pub fn set_best_fit(&mut self, value: bool) -> &mut Self {
95        self.best_fit.set_value(value);
96        self
97    }
98
99    #[inline]
100    pub fn get_style(&self) -> &Style {
101        &self.style
102    }
103
104    #[inline]
105    pub fn get_style_mut(&mut self) -> &mut Style {
106        &mut self.style
107    }
108
109    #[inline]
110    pub fn set_style(&mut self, value: Style) -> &mut Self {
111        self.style = Box::new(value);
112        self
113    }
114
115    #[inline]
116    pub fn get_auto_width(&self) -> &bool {
117        self.auto_width.get_value()
118    }
119
120    #[inline]
121    pub fn set_auto_width(&mut self, value: bool) -> &mut Self {
122        self.auto_width.set_value(value);
123        self
124    }
125
126    pub(crate) fn calculation_auto_width(&mut self, cells: &Cells) -> &mut Self {
127        if !*self.get_auto_width() {
128            return self;
129        }
130
131        let mut column_width_max = 0f64;
132
133        // default font size len.
134        let column_font_size = match self.get_style().get_font() {
135            Some(font) => *font.get_font_size().get_val(),
136            None => 11f64,
137        };
138
139        for cell in cells.iter_cells_by_column(*self.get_col_num()) {
140            let column_width = cell.get_width_point(&column_font_size);
141
142            if column_width > column_width_max {
143                column_width_max = column_width;
144            }
145        }
146
147        // set default width if empty column.
148        if column_width_max == 0f64 {
149            column_width_max = 8.38f64;
150        }
151
152        self.set_width(column_width_max);
153        self
154    }
155
156    #[inline]
157    pub(crate) fn has_style(&self) -> bool {
158        &*self.style != &Style::default()
159    }
160
161    #[inline]
162    pub(crate) fn get_hash_code(&self) -> String {
163        format!(
164            "{:x}",
165            md5::Md5::digest(format!(
166                "{}{}{}",
167                &self.width.get_value_string(),
168                &self.hidden.get_value_string(),
169                &self.best_fit.get_value_string(),
170            ))
171        )
172    }
173
174    pub(crate) fn set_attributes<R: std::io::BufRead>(
175        &mut self,
176        _reader: &mut Reader<R>,
177        e: &BytesStart,
178        stylesheet: &Stylesheet,
179    ) {
180        set_string_from_xml!(self, e, width, "width");
181        set_string_from_xml!(self, e, hidden, "hidden");
182        set_string_from_xml!(self, e, best_fit, "bestFit");
183
184        if let Some(v) = get_attribute(e, b"style") {
185            let style = stylesheet.get_style(v.parse::<usize>().unwrap());
186            self.set_style(style);
187        }
188    }
189}
190impl AdjustmentValue for Column {
191    #[inline]
192    fn adjustment_insert_value(&mut self, root_num: &u32, offset_num: &u32) {
193        if self.col_num.get_value() >= root_num {
194            self.col_num
195                .set_value(self.col_num.get_value() + offset_num);
196        }
197    }
198
199    #[inline]
200    fn adjustment_remove_value(&mut self, root_num: &u32, offset_num: &u32) {
201        if self.col_num.get_value() >= root_num {
202            self.col_num
203                .set_value(self.col_num.get_value() - offset_num);
204        }
205    }
206
207    #[inline]
208    fn is_remove_value(&self, root_num: &u32, offset_num: &u32) -> bool {
209        self.col_num.get_value() >= root_num
210            && self.col_num.get_value() <= &(root_num + offset_num - 1)
211    }
212}