FIX: Export views and showGridLines properly (#72)
This commit is contained in:
committed by
GitHub
parent
b37397acb8
commit
c3a9b006d2
@@ -68,6 +68,10 @@ pub fn save_to_xlsx(model: &Model, file_name: &str) -> Result<(), XlsxError> {
|
||||
|
||||
pub fn save_xlsx_to_writer<W: Write + Seek>(model: &Model, writer: W) -> Result<W, XlsxError> {
|
||||
let workbook = &model.workbook;
|
||||
let selected_sheet = match workbook.views.get(&0) {
|
||||
Some(view) => view.sheet,
|
||||
_ => 0,
|
||||
};
|
||||
let mut zip = zip::ZipWriter::new(writer);
|
||||
|
||||
let options = zip::write::FileOptions::default();
|
||||
@@ -94,7 +98,7 @@ pub fn save_xlsx_to_writer<W: Write + Seek>(model: &Model, writer: W) -> Result<
|
||||
zip.start_file("xl/styles.xml", options)?;
|
||||
zip.write_all(styles::get_styles_xml(workbook).as_bytes())?;
|
||||
zip.start_file("xl/workbook.xml", options)?;
|
||||
zip.write_all(workbook::get_workbook_xml(workbook).as_bytes())?;
|
||||
zip.write_all(workbook::get_workbook_xml(workbook, selected_sheet).as_bytes())?;
|
||||
|
||||
zip.add_directory("xl/_rels", options)?;
|
||||
zip.start_file("xl/_rels/workbook.xml.rels", options)?;
|
||||
@@ -114,11 +118,13 @@ pub fn save_xlsx_to_writer<W: Write + Seek>(model: &Model, writer: W) -> Result<
|
||||
let min_row = dimension.min_row;
|
||||
let max_row = dimension.max_row;
|
||||
let sheet_dimension_str = &format!("{column_min_str}{min_row}:{column_max_str}{max_row}");
|
||||
let is_sheet_selected = selected_sheet as usize == sheet_index;
|
||||
zip.write_all(
|
||||
worksheets::get_worksheet_xml(
|
||||
worksheet,
|
||||
&model.parsed_formulas[sheet_index],
|
||||
sheet_dimension_str,
|
||||
is_sheet_selected,
|
||||
)
|
||||
.as_bytes(),
|
||||
)?;
|
||||
|
||||
@@ -34,7 +34,7 @@ use ironcalc_base::types::{SheetState, Workbook};
|
||||
use super::escape::escape_xml;
|
||||
use super::xml_constants::XML_DECLARATION;
|
||||
|
||||
pub(crate) fn get_workbook_xml(workbook: &Workbook) -> String {
|
||||
pub(crate) fn get_workbook_xml(workbook: &Workbook, selected_sheet: u32) -> String {
|
||||
// sheets
|
||||
// <sheet name="Sheet1" sheetId="1" r:id="rId1"/>
|
||||
let mut sheets_str: Vec<String> = vec![];
|
||||
@@ -80,6 +80,9 @@ pub(crate) fn get_workbook_xml(workbook: &Workbook) -> String {
|
||||
let defined_names = defined_names_str.join("");
|
||||
format!("{XML_DECLARATION}\n\
|
||||
<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\
|
||||
<bookViews>
|
||||
<workbookView activeTab=\"{selected_sheet}\"/>\
|
||||
</bookViews>
|
||||
<sheets>\
|
||||
{sheets}\
|
||||
</sheets>\
|
||||
|
||||
@@ -55,6 +55,7 @@ pub(crate) fn get_worksheet_xml(
|
||||
worksheet: &Worksheet,
|
||||
parsed_formulas: &[Node],
|
||||
dimension: &str,
|
||||
is_sheet_selected: bool,
|
||||
) -> String {
|
||||
let mut sheet_data_str: Vec<String> = vec![];
|
||||
let mut cols_str: Vec<String> = vec![];
|
||||
@@ -247,6 +248,38 @@ pub(crate) fn get_worksheet_xml(
|
||||
format!("<cols>{cols}</cols>")
|
||||
};
|
||||
|
||||
let tab_selected = if is_sheet_selected {
|
||||
" tabSelected=\"1\""
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
let show_grid_lines = if !worksheet.show_grid_lines {
|
||||
" showGridLines=\"0\""
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
let mut active_cell = "A1".to_string();
|
||||
let mut sqref = "A1".to_string();
|
||||
|
||||
let views = &worksheet.views;
|
||||
if let Some(view) = views.get(&0) {
|
||||
let range = view.range;
|
||||
let row = view.row;
|
||||
let column = view.column;
|
||||
let column_name = number_to_column(column).unwrap_or("A".to_string());
|
||||
active_cell = format!("{column_name}{row}");
|
||||
|
||||
let column_start = number_to_column(range[1]).unwrap_or("A".to_string());
|
||||
let column_end = number_to_column(range[3]).unwrap_or("A".to_string());
|
||||
if range[0] == range[2] && range[1] == range[3] {
|
||||
sqref = format!("{column_start}{}", range[0]);
|
||||
} else {
|
||||
sqref = format!("{}{}:{}{}", column_start, range[0], column_end, range[2]);
|
||||
}
|
||||
}
|
||||
|
||||
format!(
|
||||
"{XML_DECLARATION}
|
||||
<worksheet \
|
||||
@@ -254,8 +287,8 @@ xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" \
|
||||
xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\
|
||||
<dimension ref=\"{dimension}\"/>\
|
||||
<sheetViews>\
|
||||
<sheetView workbookViewId=\"0\">\
|
||||
<selection activeCell=\"A1\" sqref=\"A1\"/>\
|
||||
<sheetView workbookViewId=\"0\"{show_grid_lines}{tab_selected}>\
|
||||
<selection activeCell=\"{active_cell}\" sqref=\"{sqref}\"/>\
|
||||
</sheetView>\
|
||||
</sheetViews>\
|
||||
{cols}\
|
||||
|
||||
@@ -51,22 +51,47 @@ fn test_example() {
|
||||
#[test]
|
||||
fn no_grid() {
|
||||
let model = load_from_xlsx("tests/NoGrid.xlsx", "en", "UTC").unwrap();
|
||||
let workbook = model.workbook;
|
||||
let ws = &workbook.worksheets;
|
||||
{
|
||||
let workbook = &model.workbook;
|
||||
let ws = &workbook.worksheets;
|
||||
|
||||
// NoGrid does not show grid lines
|
||||
let no_grid_sheet = &ws[0];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
assert!(!no_grid_sheet.show_grid_lines);
|
||||
// NoGrid does not show grid lines
|
||||
let no_grid_sheet = &ws[0];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
assert!(!no_grid_sheet.show_grid_lines);
|
||||
|
||||
let sheet2 = &ws[1];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
assert!(sheet2.show_grid_lines);
|
||||
let sheet2 = &ws[1];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
assert!(sheet2.show_grid_lines);
|
||||
|
||||
let no_grid_no_headers_sheet = &ws[2];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
// There is also no headers
|
||||
assert!(!no_grid_no_headers_sheet.show_grid_lines);
|
||||
let no_grid_no_headers_sheet = &ws[2];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
// There is also no headers
|
||||
assert!(!no_grid_no_headers_sheet.show_grid_lines);
|
||||
}
|
||||
{
|
||||
// save it and check again
|
||||
let temp_file_name = "temp_file_no_grid.xlsx";
|
||||
save_to_xlsx(&model, temp_file_name).unwrap();
|
||||
let model = load_from_xlsx(temp_file_name, "en", "UTC").unwrap();
|
||||
let workbook = &model.workbook;
|
||||
let ws = &workbook.worksheets;
|
||||
|
||||
// NoGrid does not show grid lines
|
||||
let no_grid_sheet = &ws[0];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
assert!(!no_grid_sheet.show_grid_lines);
|
||||
|
||||
let sheet2 = &ws[1];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
assert!(sheet2.show_grid_lines);
|
||||
|
||||
let no_grid_no_headers_sheet = &ws[2];
|
||||
assert_eq!(no_grid_sheet.name, "NoGrid".to_string());
|
||||
// There is also no headers
|
||||
assert!(!no_grid_no_headers_sheet.show_grid_lines);
|
||||
fs::remove_file(temp_file_name).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -82,6 +107,20 @@ fn test_save_to_xlsx() {
|
||||
assert_eq!(metadata.application, "IronCalc Sheets");
|
||||
// FIXME: This will need to be updated once we fix versioning
|
||||
assert_eq!(metadata.app_version, "10.0000");
|
||||
|
||||
let workbook = model.workbook;
|
||||
let ws = &workbook.worksheets;
|
||||
|
||||
assert_eq!(workbook.views[&0].sheet, 7);
|
||||
|
||||
// Test selection:
|
||||
// First sheet (Sheet1)
|
||||
// E13 and E13:N20
|
||||
assert_eq!(ws[0].frozen_rows, 0);
|
||||
assert_eq!(ws[0].frozen_columns, 0);
|
||||
assert_eq!(ws[0].views[&0].row, 13);
|
||||
assert_eq!(ws[0].views[&0].column, 5);
|
||||
assert_eq!(ws[0].views[&0].range, [13, 5, 20, 14]);
|
||||
// TODO: can we show it is the 'same' model?
|
||||
fs::remove_file(temp_file_name).unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user