Fail Web Page export on sheets taller than its row limit instead of dropping cells (#514)
This commit is contained in:
parent
3926d21aa9
commit
c20f4c2fcb
|
|
@ -167,7 +167,7 @@ pub fn save_bytes(wb: &Workbook, path: &str) -> Result<Vec<u8>> {
|
|||
FileKind::Csv => Ok(wb.sheet(sheet).map(|sh| csv(wb, sh, wb.csv_delimiter.unwrap_or(b','))).unwrap_or_default()),
|
||||
FileKind::Tsv => Ok(wb.sheet(sheet).map(|sh| csv(wb, sh, b'\t')).unwrap_or_default()),
|
||||
FileKind::Json => serde_json::to_vec_pretty(wb).map_err(|e| EngineError::Other(e.to_string())),
|
||||
FileKind::Html => Ok(to_html(wb, sheet).into_bytes()),
|
||||
FileKind::Html => to_html(wb, sheet).map(String::into_bytes),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,9 +285,12 @@ impl std::fmt::Write for ClipboardHtml {
|
|||
}
|
||||
}
|
||||
|
||||
/// Most rows Save as Web Page writes. A sheet whose used range is taller fails instead of losing cells.
|
||||
const HTML_EXPORT_MAX_ROWS: u32 = 100_001;
|
||||
|
||||
/// A sheet as a standalone HTML table (Save as Web Page).
|
||||
pub fn to_html(wb: &Workbook, sheet: usize) -> String {
|
||||
let Some(sh) = wb.sheet(sheet) else { return String::new() };
|
||||
pub fn to_html(wb: &Workbook, sheet: usize) -> Result<String> {
|
||||
let Some(sh) = wb.sheet(sheet) else { return Ok(String::new()) };
|
||||
let mut out = String::new();
|
||||
let _ = write!(
|
||||
out,
|
||||
|
|
@ -295,7 +298,13 @@ pub fn to_html(wb: &Workbook, sheet: usize) -> String {
|
|||
esc(&sh.name)
|
||||
);
|
||||
if let Some(r) = sh.used_range() {
|
||||
for row in r.start.row..=r.end.row.min(r.start.row + 100_000) {
|
||||
if r.height() > HTML_EXPORT_MAX_ROWS {
|
||||
return Err(EngineError::Other(format!(
|
||||
"the sheet is too tall for a web page ({} rows, at most {HTML_EXPORT_MAX_ROWS}). Save as .xlsx or CSV instead.",
|
||||
r.height()
|
||||
)));
|
||||
}
|
||||
for row in r.start.row..=r.end.row {
|
||||
if sh.is_row_hidden(row) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -318,7 +327,7 @@ pub fn to_html(wb: &Workbook, sheet: usize) -> String {
|
|||
}
|
||||
}
|
||||
out.push_str("</table></body></html>");
|
||||
out
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
|
@ -418,6 +427,20 @@ pub fn image_size(data: &[u8]) -> Option<(u32, u32)> {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn html_export_fails_instead_of_dropping_cells_past_the_row_limit() {
|
||||
let mut wb = Workbook::new();
|
||||
let sh = wb.sheet_mut(0).unwrap();
|
||||
sh.set_value(CellRef::new(0, 0), gridcraft_core::Value::text("near"));
|
||||
sh.set_value(CellRef::new(149_999, 0), gridcraft_core::Value::text("far"));
|
||||
assert!(save_bytes(&wb, "book.html").is_err());
|
||||
let sh = wb.sheet_mut(0).unwrap();
|
||||
sh.remove_cell(CellRef::new(149_999, 0));
|
||||
sh.set_value(CellRef::new(100_000, 0), gridcraft_core::Value::text("far"));
|
||||
let html = String::from_utf8(save_bytes(&wb, "book.html").unwrap()).unwrap();
|
||||
assert!(html.contains(">near</td>") && html.contains(">far</td>"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macros_are_saved_only_into_xlsm() {
|
||||
let mut wb = Workbook::new();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ support comes from `crates/engine/src/io.rs` (`FileKind`), `crates/xlsx/src` and
|
|||
| `.txt` tab-delimited, Unicode text | R/W | yes (`.txt`, `.tsv`, `.tab`) | yes (displayed values) | Text Import Wizard options partly via Text to Columns |
|
||||
| `.prn` formatted text (space-delimited) | R/W | no | no | |
|
||||
| `.dif`, `.slk` (SYLK) | R/W | no | no | Small, legacy |
|
||||
| `.htm` / `.html` web page | R/W (Windows) | yes, via Get Data ▸ From HTML | yes (one sheet as a table) | Formatting not exported |
|
||||
| `.htm` / `.html` web page | R/W (Windows) | yes, via Get Data ▸ From HTML | yes (one sheet as a table; a used range taller than 100,001 rows fails with an error instead of being cut short) | Formatting not exported |
|
||||
| `.mht` / `.mhtml` single-file web page | R/W (Windows) | no | no | |
|
||||
| `.json` | via Power Query | GridCraft's own workbook JSON (debug) and JSON import | GridCraft JSON | Not Power Query's JSON shaping; notes and hyperlinks break export (#126) |
|
||||
| `.xml` with XML maps | Developer ▸ Import/Export | no | no | |
|
||||
|
|
|
|||
Loading…
Reference in New Issue