Skip to main content

docx_rs/reader/
table.rs

1use std::io::Read;
2use std::str::FromStr;
3
4use super::*;
5use crate::types::*;
6
7impl ElementReader for Table {
8    fn read<R: Read>(r: &mut EventReader<R>, _: &[OwnedAttribute]) -> Result<Self, ReaderError> {
9        let mut t = Table::without_borders(vec![]);
10        let mut grid_col: Vec<usize> = vec![];
11        loop {
12            let e = r.next();
13            match e {
14                Ok(XmlEvent::StartElement {
15                    attributes, name, ..
16                }) => {
17                    let e = XMLElement::from_str(&name.local_name).unwrap();
18
19                    ignore::ignore_element(e.clone(), XMLElement::TablePropertyChange, r);
20                    ignore::ignore_element(e.clone(), XMLElement::TableGridChange, r);
21
22                    match e {
23                        XMLElement::TableRow => {
24                            t = t.add_row(TableRow::read(r, &attributes)?);
25                            continue;
26                        }
27                        XMLElement::TableWidth => {
28                            let (w, width_type) = read_width(&attributes)?;
29                            t = t.width(w as usize, width_type);
30                            continue;
31                        }
32                        XMLElement::TableProperty => {
33                            if let Ok(p) = TableProperty::read(r, &attributes) {
34                                t.property = p;
35                            }
36                        }
37                        XMLElement::Justification => {
38                            t = t.align(TableAlignmentType::from_str(&attributes[0].value)?);
39                        }
40                        XMLElement::TableIndent => {
41                            let (w, _) = read_width(&attributes)?;
42                            t = t.indent(w as i32);
43                            continue;
44                        }
45                        XMLElement::TableBorders => {
46                            if let Ok(borders) = TableBorders::read(r, &attributes) {
47                                t = t.set_borders(borders);
48                            }
49                        }
50                        XMLElement::TableStyle => {
51                            if let Some(s) = read_val(&attributes) {
52                                t = t.style(s);
53                            }
54                        }
55                        XMLElement::TableCellMargin => {
56                            if let Ok(margins) = TableCellMargins::read(r, &attributes) {
57                                t = t.margins(margins)
58                            }
59                        }
60                        XMLElement::GridCol => {
61                            let (w, _) = read_width(&attributes)?;
62                            grid_col.push(w as usize);
63                        }
64                        _ => {}
65                    }
66                }
67                Ok(XmlEvent::EndElement { name, .. }) => {
68                    let e = XMLElement::from_str(&name.local_name).unwrap();
69                    if e == XMLElement::Table {
70                        t = t.set_grid(grid_col);
71                        return Ok(t);
72                    }
73                }
74                Err(_) => return Err(ReaderError::XMLReadError),
75                _ => {}
76            }
77        }
78    }
79}
80
81#[cfg(test)]
82mod tests {
83
84    use super::*;
85    #[cfg(test)]
86    use pretty_assertions::assert_eq;
87
88    #[test]
89    fn test_read_table_with_width_prop() {
90        let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
91<w:tbl>
92    <w:tblPr>
93        <w:tblW w:w="9638" w:type="dxa"/>
94    </w:tblPr>
95    <w:tblGrid>
96        <w:gridCol w:w="3212"/>
97        <w:gridCol w:w="3213"/>
98        <w:gridCol w:w="3213"/>
99    </w:tblGrid>
100</w:tbl>
101</w:document>"#;
102        let mut parser = EventReader::new(c.as_bytes());
103        let t = Table::read(&mut parser, &[]).unwrap();
104        assert_eq!(
105            t,
106            Table::without_borders(vec![])
107                .set_grid(vec![3212, 3213, 3213])
108                .width(9638, WidthType::Dxa)
109        );
110    }
111
112    #[test]
113    fn test_read_table_with_layout() {
114        let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
115<w:tbl>
116    <w:tblPr>
117        <w:jc w:val="center"/>
118        <w:tblInd w:w="100" w:type="dxa"/>
119    </w:tblPr>
120</w:tbl>
121</w:document>"#;
122        let mut parser = EventReader::new(c.as_bytes());
123        let t = Table::read(&mut parser, &[]).unwrap();
124        assert_eq!(
125            t,
126            Table::without_borders(vec![])
127                .align(TableAlignmentType::Center)
128                .indent(100)
129        );
130    }
131}