umya_spreadsheet/reader/xlsx/
table.rs

1use super::driver::*;
2use super::XlsxError;
3use crate::structs::raw::RawFile;
4use crate::structs::Comment;
5use crate::structs::Worksheet;
6use crate::structs::{Table, TableColumn, TableStyleInfo};
7use quick_xml::events::Event;
8use quick_xml::Reader;
9use std::result;
10
11pub(crate) fn read(
12    worksheet: &mut Worksheet,
13    table_file: &RawFile,
14) -> result::Result<(), XlsxError> {
15    let data = std::io::Cursor::new(table_file.get_file_data());
16    let mut reader = Reader::from_reader(data);
17    reader.config_mut().trim_text(false);
18    let mut buf = Vec::new();
19    let mut table = Table::default();
20    let mut table_column = TableColumn::default();
21    let mut string_value = String::new();
22    loop {
23        match reader.read_event_into(&mut buf) {
24            Ok(Event::Empty(ref e)) => match e.name().into_inner() {
25                b"tableColumn" => {
26                    table_column = TableColumn::default();
27                    for a in e.attributes().with_checks(false) {
28                        match a {
29                            Ok(ref attr) => match attr.key.0 {
30                                b"name" => {
31                                    let attr_val = get_attribute_value(attr)?;
32                                    table_column.set_name(attr_val);
33                                }
34                                b"totalsRowLabel" => {
35                                    let attr_val = get_attribute_value(attr)?;
36                                    table_column.set_totals_row_label_str(&attr_val);
37                                }
38                                b"totalsRowFunction" => {
39                                    let attr_val = get_attribute_value(attr)?;
40                                    table_column.set_totals_row_function_str(&attr_val);
41                                }
42                                _ => {}
43                            },
44                            _ => {}
45                        }
46                    }
47                    // add column to table (if it has a name)
48                    if !table_column.get_name().is_empty() {
49                        table.add_column(table_column);
50                        table_column = TableColumn::default();
51                    }
52                }
53                b"tableStyleInfo" => {
54                    let mut name = String::new();
55                    let mut show_first_col = false;
56                    let mut show_last_col = false;
57                    let mut show_row_stripes = false;
58                    let mut show_col_stripes = false;
59                    for a in e.attributes().with_checks(false) {
60                        match a {
61                            Ok(ref attr) => {
62                                let attr_val = get_attribute_value(attr)?;
63                                match attr.key.0 {
64                                    b"name" => {
65                                        name = attr_val;
66                                    }
67                                    b"showFirstColumn" => {
68                                        show_first_col = attr_val == "1";
69                                    }
70                                    b"showLastColumn" => {
71                                        show_last_col = attr_val == "1";
72                                    }
73                                    b"showRowStripes" => {
74                                        show_row_stripes = attr_val == "1";
75                                    }
76                                    b"showColumnStripes" => {
77                                        show_col_stripes = attr_val == "1";
78                                    }
79                                    _ => {}
80                                }
81                            }
82                            _ => {}
83                        }
84                    }
85                    if !name.is_empty() {
86                        table.set_style_info(Some(TableStyleInfo::new(
87                            &name,
88                            show_first_col,
89                            show_last_col,
90                            show_row_stripes,
91                            show_col_stripes,
92                        )));
93                    }
94                }
95                _ => (),
96            },
97            Ok(Event::Text(e)) => string_value = e.unescape().unwrap().to_string(),
98            Ok(Event::Start(ref e)) => match e.name().into_inner() {
99                b"table" => {
100                    for a in e.attributes().with_checks(false) {
101                        match a {
102                            Ok(ref attr) => {
103                                let attr_val = get_attribute_value(attr)?;
104                                match attr.key.0 {
105                                    b"displayName" => {
106                                        table.set_display_name(&attr_val);
107                                    }
108                                    b"name" => {
109                                        table.set_name(&attr_val);
110                                    }
111                                    b"ref" => {
112                                        let area_coords: Vec<&str> = attr_val.split(':').collect();
113                                        if area_coords.len() == 2 {
114                                            table.set_area((area_coords[0], area_coords[1]));
115                                        }
116                                    }
117                                    b"totalsRowShown" => {
118                                        table.set_totals_row_shown_str(&attr_val);
119                                    }
120                                    b"totalsRowCount" => {
121                                        table.set_totals_row_count_str(&attr_val);
122                                    }
123                                    _ => {}
124                                }
125                            }
126                            _ => {}
127                        }
128                    }
129                }
130                b"tableColumn" => {
131                    table_column = TableColumn::default();
132                    for a in e.attributes().with_checks(false) {
133                        match a {
134                            Ok(ref attr) => match attr.key.0 {
135                                b"name" => {
136                                    let attr_val = get_attribute_value(attr)?;
137                                    table_column.set_name(attr_val);
138                                }
139                                b"totalsRowLabel" => {
140                                    let attr_val = get_attribute_value(attr)?;
141                                    table_column.set_totals_row_label_str(&attr_val);
142                                }
143                                b"totalsRowFunction" => {
144                                    let attr_val = get_attribute_value(attr)?;
145                                    table_column.set_totals_row_function_str(&attr_val);
146                                }
147                                _ => {}
148                            },
149                            _ => {}
150                        }
151                    }
152                }
153                _ => (),
154            },
155            Ok(Event::End(ref e)) => match e.name().into_inner() {
156                b"calculatedColumnFormula" => {
157                    table_column.set_calculated_column_formula(string_value);
158                    string_value = String::new();
159                }
160                b"tableColumn" => {
161                    // add column to table (if it has a name)
162                    if !table_column.get_name().is_empty() {
163                        table.add_column(table_column);
164                        table_column = TableColumn::default();
165                    }
166                }
167                _ => (),
168            },
169            Ok(Event::Eof) => break,
170            Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
171            _ => (),
172        }
173        buf.clear();
174    }
175    // add the table to the sheet (if a few sanity checks pass)
176    if table.is_ok() {
177        worksheet.add_table(table);
178    }
179    Ok(())
180}