diff --git a/webapp/app.ironcalc.com/server/Cargo.lock b/webapp/app.ironcalc.com/server/Cargo.lock index 0fe13c1..8a7bab4 100644 --- a/webapp/app.ironcalc.com/server/Cargo.lock +++ b/webapp/app.ironcalc.com/server/Cargo.lock @@ -947,7 +947,6 @@ dependencies = [ "chrono-tz", "csv", "js-sys", - "once_cell", "rand", "regex", "ryu", diff --git a/xlsx/src/export/test/test_export.rs b/xlsx/src/export/test/test_export.rs index 4bebc8d..11d6541 100644 --- a/xlsx/src/export/test/test_export.rs +++ b/xlsx/src/export/test/test_export.rs @@ -88,6 +88,44 @@ fn test_values() { } } +#[test] +fn frozen_rows() { + let mut model = new_empty_model(); + model.set_frozen_rows(0, 23).unwrap(); + model.evaluate(); + let temp_file_name = "temp_file_test_frozen_rows.xlsx"; + save_to_xlsx(&model, temp_file_name).unwrap(); + let model = load_from_xlsx(temp_file_name, "en", "UTC").unwrap(); + assert_eq!(model.get_frozen_rows_count(0).unwrap(), 23); + fs::remove_file(temp_file_name).unwrap(); +} + +#[test] +fn frozen_columns() { + let mut model = new_empty_model(); + model.set_frozen_columns(0, 42).unwrap(); + model.evaluate(); + let temp_file_name = "temp_file_test_frozen_columns.xlsx"; + save_to_xlsx(&model, temp_file_name).unwrap(); + let model = load_from_xlsx(temp_file_name, "en", "UTC").unwrap(); + assert_eq!(model.get_frozen_columns_count(0).unwrap(), 42); + fs::remove_file(temp_file_name).unwrap(); +} + +#[test] +fn frozen_rows_and_columns() { + let mut model = new_empty_model(); + model.set_frozen_rows(0, 23).unwrap(); + model.set_frozen_columns(0, 42).unwrap(); + model.evaluate(); + let temp_file_name = "temp_file_test_frozen_rows_and_columns.xlsx"; + save_to_xlsx(&model, temp_file_name).unwrap(); + let model = load_from_xlsx(temp_file_name, "en", "UTC").unwrap(); + assert_eq!(model.get_frozen_rows_count(0).unwrap(), 23); + assert_eq!(model.get_frozen_columns_count(0).unwrap(), 42); + fs::remove_file(temp_file_name).unwrap(); +} + #[test] fn test_formulas() { let mut model = new_empty_model(); diff --git a/xlsx/src/export/worksheets.rs b/xlsx/src/export/worksheets.rs index 01eabe5..62b844b 100644 --- a/xlsx/src/export/worksheets.rs +++ b/xlsx/src/export/worksheets.rs @@ -301,15 +301,53 @@ pub(crate) fn get_worksheet_xml( "".to_string() }; + let frozen_rows = worksheet.frozen_rows; + let frozen_columns = worksheet.frozen_columns; + + let pane = if frozen_rows > 0 && frozen_columns > 0 { + // There are both frozen rows and columns. There are four panes. + // The first column is the first column after the last frozen column. + let first_column = number_to_column(frozen_columns + 1).unwrap_or("A".to_string()); + // This is the top left cell of the bottom right pane. + let top_left_cell = format!("{}{}", first_column, frozen_rows + 1); + // The meaning of the next two is irrelevant for IronCalc. + let top_right_active_cell = format!("{first_column}1"); + let bottom_left_active_cell = format!("A{}", frozen_rows + 1); + // The bottom right active cell is the "true" selected cell and it does not need to reside on this pane. + format!( + "\ + \ + \ + ", + ) + } else if frozen_rows > 0 { + // Only frozen rows + let top_left_cell = format!("A{}", frozen_rows + 1); + format!( + "\ + ", + ) + } else if frozen_columns > 0 { + let top_left_cell = format!( + "{}1", + number_to_column(frozen_columns + 1).unwrap_or("A".to_string()) + ); + format!( + "\ + " + ) + } else { + // No frozen rows or columns + format!(r#""#) + }; + format!( - "{XML_DECLARATION} -\ + "{XML_DECLARATION}\ +\ \ \ \ - \ + {pane}\ \ \ {cols}\