From abe882b551a2bc40bf92cd97daf02bd3f3581188 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Wed, 24 Jul 2019 08:23:38 +0000 Subject: [PATCH] fpspreadsheet: Excel2003/XML fileformat now fully supports page breaks. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7070 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../fpspreadsheet/source/common/xlsxml.pas | 82 +++++++++++++++++-- .../source/visual/fpspreadsheetctrls.pas | 1 - .../fpspreadsheet/tests/colrowtests.pas | 42 ++++++++++ 3 files changed, 118 insertions(+), 7 deletions(-) diff --git a/components/fpspreadsheet/source/common/xlsxml.pas b/components/fpspreadsheet/source/common/xlsxml.pas index ab5b8f7be..33424792d 100644 --- a/components/fpspreadsheet/source/common/xlsxml.pas +++ b/components/fpspreadsheet/source/common/xlsxml.pas @@ -49,6 +49,8 @@ type procedure ReadInterior(ANode: TDOMNode; var AFormat: TsCellFormat); procedure ReadNames(ANode: TDOMNode; AWorksheet: TsBasicWorksheet); procedure ReadNumberFormat(ANode: TDOMNode; var AFormat: TsCellFormat); + procedure ReadPageBreak(ANode: TDOMNode; AWorksheet: TsBasicWorksheet); + procedure ReadPageBreaks(ANode: TDOMNode; AWorksheet: TsBasicWorksheet); procedure ReadPageSetup(ANode: TDOMNode; AWorksheet: TsBasicWorksheet); procedure ReadPrint(ANode: TDOMNode; AWorksheet: TsBasicWorksheet); procedure ReadRow(ANode: TDOMNode; AWorksheet: TsBasicWorksheet; ARow: Integer); @@ -930,6 +932,72 @@ begin Include(AFormat.UsedFormattingFields, uffNumberFormat); end; +{@@ ---------------------------------------------------------------------------- + Reads a "Worksheet / PageBreaks / RowBreaks / RowBreak" node + or a "Worksheet / PageBreaks / ColBreaks / ColBreak" node +-------------------------------------------------------------------------------} +procedure TsSpreadExcelXMLReader.ReadPageBreak(ANode: TDOMNode; + AWorksheet: TsBasicWorksheet); +var + sheet: TsWorksheet absolute AWorksheet; + node: TDOMNode; + nodeName: String; + s: String; + n: Integer; +begin + while ANode <> nil do begin + nodeName := ANode.NodeName; + if nodeName = 'Row' then begin + s := ANode.TextContent; + if (s <> '') and TryStrToInt(s, n) then + sheet.AddPageBreakToRow(n); + end else + if nodeName = 'Column' then begin + s := ANode.TextContent; + if (s <> '') and TryStrToInt(s, n) then + sheet.AddPageBreakToCol(n); + end; + ANode := ANode.NextSibling; + end; +end; + +{@@ ---------------------------------------------------------------------------- + Reads the "Wrksheet / PageBreaks" node +-------------------------------------------------------------------------------} +procedure TsSpreadExcelXMLReader.ReadPageBreaks(ANode: TDOMNode; + AWorksheet: TsBasicWorksheet); +var + sheet: TsWorksheet absolute AWorksheet; + nodeName: String; + node: TDOMNode; + child: TDOMNode; + s: String; +begin + while ANode <> nil do + begin + nodeName := ANode.NodeName; + if nodeName = 'RowBreaks' then begin + node := ANode.FirstChild; + while node <> nil do begin + nodeName := node.NodeName; + if nodeName = 'RowBreak' then + ReadPageBreak(node.FirstChild, AWorksheet); + node := node.NextSibling; + end; + end else + if nodeName = 'ColBreaks' then begin + node := ANode.FirstChild; + while node <> nil do begin + nodeName := node.NodeName; + if nodeName = 'ColBreak' then + ReadPageBreak(node.FirstChild, AWorksheet); + node := node.NextSibling; + end; + end; + ANode := ANode.NextSibling; + end; +end; + {@@ ---------------------------------------------------------------------------- Reads the "WorksheetOptions/PageSetup" node -------------------------------------------------------------------------------} @@ -1163,6 +1231,11 @@ begin while ANode <> nil do begin nodeName := ANode.NodeName; if nodeName = 'Column' then begin + // Default column width + s := GetAttrValue(ANode, 'ss:DefaultColumnWidth'); + if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then + sheet.WriteDefaultColWidth(x, suPoints); + // Column index s := GetAttrValue(ANode, 'ss:Index'); if (s <> '') and TryStrToInt(s, c) then @@ -1193,11 +1266,6 @@ begin end else if nodeName = 'Row' then begin - // Default column width - s := GetAttrValue(ANode, 'ss:DefaultColumnWidth'); - if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then - sheet.WriteDefaultColWidth(x, suPoints); - // Default row height s := GetAttrValue(ANode, 'ss:DefaultRowHeight'); if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then @@ -1268,7 +1336,9 @@ begin else if nodeName = 'WorksheetOptions' then ReadWorksheetOptions(ANode.FirstChild, AWorksheet) else if nodeName = 'Names' then - ReadNames(ANode.FirstChild, AWorksheet); + ReadNames(ANode.FirstChild, AWorksheet) + else if nodeName = 'PageBreaks' then + ReadPageBreaks(ANode.FirstChild, AWorksheet); ANode := ANode.NextSibling; end; end; diff --git a/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas b/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas index fd42c4939..47b41b2b8 100644 --- a/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas +++ b/components/fpspreadsheet/source/visual/fpspreadsheetctrls.pas @@ -3852,7 +3852,6 @@ begin Worksheet.ReadDefaultRowHeight(Workbook.Units), unitStr, Worksheet.ReadDefaultRowHeight(suPoints) ])); - // UpdateFormatProperties(-1, AStrings); end; end; diff --git a/components/fpspreadsheet/tests/colrowtests.pas b/components/fpspreadsheet/tests/colrowtests.pas index 3ae231e26..d729c3af2 100644 --- a/components/fpspreadsheet/tests/colrowtests.pas +++ b/components/fpspreadsheet/tests/colrowtests.pas @@ -288,12 +288,21 @@ type procedure TestWriteRead_AddPageBreak_Row_OOXML; procedure TestWriteRead_AddPageBreak_RowHidden_OOXML; + procedure TestWriteRead_AddPageBreak_Col_XML; + procedure TestWriteRead_AddPageBreak_ColHidden_XML; + procedure TestWriteRead_AddPageBreak_Row_XML; + procedure TestWriteRead_AddPageBreak_RowHidden_XML; + // Remove a page break column procedure TestWriteRead_RemovePageBreak_Col_OOXML; procedure TestWriteRead_RemovePageBreak_ColHidden_OOXML; procedure TestWriteRead_RemovePageBreak_Row_OOXML; procedure TestWriteRead_RemovePageBreak_RowHidden_OOXML; + procedure TestWriteRead_RemovePageBreak_Col_XML; + procedure TestWriteRead_RemovePageBreak_ColHidden_XML; + procedure TestWriteRead_RemovePageBreak_Row_XML; + procedure TestWriteRead_RemovePageBreak_RowHidden_XML; end; implementation @@ -2238,6 +2247,23 @@ begin TestWriteRead_AddPageBreak_Row(true, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_AddPageBreak_Col_XML; +begin + TestWriteRead_AddPageBreak_Col(false, sfExcelXML); +end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_AddPageBreak_Row_XML; +begin + TestWriteRead_AddPageBreak_Row(false, sfExcelXML); +end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_AddPageBreak_ColHidden_XML; +begin + TestWriteRead_AddPageBreak_Col(true, sfExcelXML); +end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_AddPageBreak_RowHidden_XML; +begin + TestWriteRead_AddPageBreak_Row(true, sfExcelXML); +end; + { Remove page break - Hidden: set the Hidden flag in the options to test whether it is damaged @@ -2405,6 +2431,22 @@ begin TestWriteRead_RemovePageBreak_Row(true, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_RemovePageBreak_Col_XML; +begin + TestWriteRead_RemovePageBreak_Col(false, sfExcelXML); +end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_RemovePageBreak_Row_XML; +begin + TestWriteRead_RemovePageBreak_Row(false, sfExcelXML); +end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_RemovePageBreak_ColHidden_XML; +begin + TestWriteRead_RemovePageBreak_Col(true, sfExcelXML); +end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_RemovePageBreak_RowHidden_XML; +begin + TestWriteRead_RemovePageBreak_Row(true, sfExcelXML); +end; initialization RegisterTest(TSpreadWriteRead_ColRow_Tests);