diff --git a/src/xlsx/cells_reader.rs b/src/xlsx/cells_reader.rs index 3404d74..53d80a0 100644 --- a/src/xlsx/cells_reader.rs +++ b/src/xlsx/cells_reader.rs @@ -39,6 +39,7 @@ impl<'a> XlsxCellReader<'a> { ) -> Result { let mut buf = Vec::with_capacity(1024); let mut dimensions = Dimensions::default(); + let mut sh_type = None; 'xml: loop { buf.clear(); match xml.read_event_into(&mut buf).map_err(XlsxError::Xml)? { @@ -57,9 +58,19 @@ impl<'a> XlsxCellReader<'a> { return Err(XlsxError::UnexpectedNode("dimension")); } b"sheetData" => break, - _ => (), + typ => { + if sh_type.is_none() { + sh_type = Some(xml.decoder().decode(typ)?.to_string()); + } + } }, - Event::Eof => return Err(XlsxError::XmlEof("sheetData")), + Event::Eof => { + if let Some(typ) = sh_type { + return Err(XlsxError::NotAWorksheet(typ)); + } else { + return Err(XlsxError::XmlEof("worksheet")); + } + } _ => (), } } diff --git a/src/xlsx/mod.rs b/src/xlsx/mod.rs index de42bff..3ee796b 100644 --- a/src/xlsx/mod.rs +++ b/src/xlsx/mod.rs @@ -87,6 +87,8 @@ pub enum XlsxError { WorksheetNotFound(String), /// Table not found TableNotFound(String), + /// The specified sheet is not a worksheet + NotAWorksheet(String), } from_err!(std::io::Error, XlsxError, Io); @@ -136,6 +138,7 @@ impl std::fmt::Display for XlsxError { XlsxError::WorksheetNotFound(n) => write!(f, "Worksheet '{n}' not found"), XlsxError::Password => write!(f, "Workbook is password protected"), XlsxError::TableNotFound(n) => write!(f, "Table '{n}' not found"), + XlsxError::NotAWorksheet(typ) => write!(f, "Expecting a worksheet, got {typ}"), } } } @@ -854,7 +857,14 @@ impl Xlsx { &'a mut self, name: &str, ) -> Result>, XlsxError> { - let mut cell_reader = self.worksheet_cells_reader(name)?; + let mut cell_reader = match self.worksheet_cells_reader(name) { + Ok(reader) => reader, + Err(XlsxError::NotAWorksheet(typ)) => { + log::warn!("'{typ}' not a valid worksheet"); + return Ok(Range::default()); + } + Err(e) => return Err(e), + }; let len = cell_reader.dimensions().len(); let mut cells = Vec::new(); if len < 100_000 { @@ -928,7 +938,14 @@ impl Reader for Xlsx { } fn worksheet_formula(&mut self, name: &str) -> Result, XlsxError> { - let mut cell_reader = self.worksheet_cells_reader(name)?; + let mut cell_reader = match self.worksheet_cells_reader(name) { + Ok(reader) => reader, + Err(XlsxError::NotAWorksheet(typ)) => { + warn!("'{typ}' not a worksheet"); + return Ok(Range::default()); + } + Err(e) => return Err(e), + }; let len = cell_reader.dimensions().len(); let mut cells = Vec::new(); if len < 100_000 { diff --git a/tests/issue438.xlsx b/tests/issue438.xlsx new file mode 100644 index 0000000..7074395 Binary files /dev/null and b/tests/issue438.xlsx differ diff --git a/tests/test.rs b/tests/test.rs index 5cd8404..28c15f6 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1691,6 +1691,14 @@ fn issue_420_empty_s_attribute() { ); } +#[test] +fn issue_438_charts() { + let mut excel: Xlsx<_> = wb("issue438.xlsx"); + let _range = excel + .worksheet_range("Chart1") + .expect("could not open worksheet range"); +} + #[test] fn isssue_446_formulas() { let mut excel: Xlsx<_> = wb("issue446.xlsx");