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);
}