diff --git a/src/structs/cell_format.rs b/src/structs/cell_format.rs index 99f10945..931f2fa2 100644 --- a/src/structs/cell_format.rs +++ b/src/structs/cell_format.rs @@ -330,6 +330,11 @@ impl CellFormat { set_string_from_xml!(self, e, font_id, "fontId"); set_string_from_xml!(self, e, fill_id, "fillId"); set_string_from_xml!(self, e, border_id, "borderId"); + // `xfId` names the cellStyleXfs entry this cellXfs entry inherits + // from. Leaving it unread resolved every cell against cellStyleXfs[0], + // so a workbook whose Normal style sets applyNumberFormat="0" lost + // every number format, and a round trip rewrote each xfId as 0. + set_string_from_xml!(self, e, format_id, "xfId"); set_string_from_xml!(self, e, apply_number_format, "applyNumberFormat"); set_string_from_xml!(self, e, apply_border, "applyBorder"); set_string_from_xml!(self, e, apply_font, "applyFont"); @@ -425,3 +430,56 @@ impl CellFormat { } } } + +#[cfg(test)] +mod tests { + use super::*; + + fn read_xf(xml: &str) -> CellFormat { + let mut reader = Reader::from_reader(std::io::BufReader::new(xml.as_bytes())); + let mut buf = Vec::new(); + loop { + match reader.read_event_into(&mut buf) { + Ok(Event::Start(ref e)) if e.name().into_inner() == b"xf" => { + let mut obj = CellFormat::default(); + obj.set_attributes(&mut reader, e, false); + return obj; + } + Ok(Event::Empty(ref e)) if e.name().into_inner() == b"xf" => { + let mut obj = CellFormat::default(); + obj.set_attributes(&mut reader, e, true); + return obj; + } + Ok(Event::Eof) => panic!("xf element not found"), + _ => (), + } + buf.clear(); + } + } + + // `xfId` names the cellStyleXfs entry a cellXfs entry inherits from. It was + // written back on save but never read, so every cell resolved against + // cellStyleXfs[0]: a workbook whose Normal style carries + // applyNumberFormat="0" lost every number format, and a round trip + // rewrote each xfId as 0. + #[test] + fn reads_the_xf_id() { + let obj = read_xf(r#""#); + assert_eq!(obj.format_id(), 6); + assert_eq!(obj.number_format_id(), 9); + } + + #[test] + fn an_absent_xf_id_stays_zero() { + let obj = read_xf(r#""#); + assert_eq!(obj.format_id(), 0); + } + + #[test] + fn reads_a_non_zero_xf_id_from_a_non_empty_element() { + let obj = read_xf( + r#""#, + ); + assert_eq!(obj.format_id(), 42); + } +} diff --git a/src/writer/csv.rs b/src/writer/csv.rs index 89cdc523..8bb21a7d 100644 --- a/src/writer/csv.rs +++ b/src/writer/csv.rs @@ -44,7 +44,12 @@ pub fn write_writer( } // wrap_with_char. if option.wrap_with_char() != "" { - value = format! {"{}{}{}", option.wrap_with_char(), value, option.wrap_with_char()}; + value = format!( + "{}{}{}", + option.wrap_with_char(), + value, + option.wrap_with_char() + ); } row_vec.push(value); }