From 0051d96af6a25250ba81fdac13eb8bc49e207f32 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 15 Jul 2019 22:56:15 +0000 Subject: [PATCH] fpspreadsheet: Read PageLayout/PrintSettings in Excel2003/XML files. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7040 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../read_write/excelxmldemo/excelxmlread.lpr | 30 ++++ .../fpspreadsheet/source/common/xlsxml.pas | 147 +++++++++++++++++- 2 files changed, 175 insertions(+), 2 deletions(-) diff --git a/components/fpspreadsheet/examples/read_write/excelxmldemo/excelxmlread.lpr b/components/fpspreadsheet/examples/read_write/excelxmldemo/excelxmlread.lpr index d2a8b4a8b..ca33607a7 100644 --- a/components/fpspreadsheet/examples/read_write/excelxmldemo/excelxmlread.lpr +++ b/components/fpspreadsheet/examples/read_write/excelxmldemo/excelxmlread.lpr @@ -60,6 +60,36 @@ begin else WriteLn; end; + + WriteLn; + WriteLn('Printer settings/Page layout'); + WriteLn(' Page width: ', worksheet.PageLayout.PageWidth:0:1, ' mm'); + WriteLn(' Page height: ', worksheet.PageLayout.PageHeight:0:1, ' mm'); + WriteLn(' Orientation: ', worksheet.PageLayout.Orientation); + WriteLn(' Left margin: ', worksheet.PageLayout.LeftMargin:0:1, ' mm'); + WriteLn(' Right margin: ', worksheet.PageLayout.RightMargin:0:1, ' mm'); + WriteLn(' Top margin: ', worksheet.PageLayout.TopMargin:0:1, ' mm'); + WriteLn(' Bottom margin: ', worksheet.PageLayout.BottomMargin:0:1, ' mm'); + WriteLn(' Header margin: ', worksheet.PageLayout.HeaderMargin:0:1, ' mm'); + WriteLn(' Header text: ', worksheet.PageLayout.Headers[0]); + WriteLn(' Footer margin: ', worksheet.PageLayout.FooterMargin:0:1, ' mm'); + WriteLn(' Footer text: ', worksheet.PageLayout.Footers[0]); + WriteLn(' Scaling factor: ', worksheet.PageLayout.ScalingFactor, ' %'); + WriteLn(' Start page number: ', worksheet.PageLayout.StartPageNumber); + Write(' Options: '); + if (poPrintGridLines in worksheet.PageLayout.Options) then Write('GridLines '); + if (poMonochrome in worksheet.PageLayout.Options) then Write('Black&White '); + if (poDraftQuality in worksheet.PageLayout.Options) then Write('Draft '); + if (poPrintHeaders in worksheet.PageLayout.Options) then Write('Headers '); + if (poCommentsAtEnd in worksheet.Pagelayout.Options) then Write('CommentsAtEnd '); + if (poPrintCellComments in worksheet.PageLayout.Options) then Write('CellComments '); + if (poHorCentered in worksheet.PageLayout.Options) then Write('HorCentered '); + if (poVertCentered in worksheet.PageLayout.Options) then Write('VertCentered '); + if (poPrintPagesByRows in worksheet.PageLayout.Options) then Write('PagesByRows '); + if (poFitPages in worksheet.PageLayout.Options) then Write('FitPage' ); + WriteLn; + WriteLn(' Fit height to pages: ', worksheet.Pagelayout.FitHeightToPages); + WriteLn(' Fit width to pages: ', worksheet.PageLayout.FitWidthToPages); end; finally diff --git a/components/fpspreadsheet/source/common/xlsxml.pas b/components/fpspreadsheet/source/common/xlsxml.pas index dc19fb6e2..20bcfbce6 100644 --- a/components/fpspreadsheet/source/common/xlsxml.pas +++ b/components/fpspreadsheet/source/common/xlsxml.pas @@ -858,7 +858,7 @@ begin if nodeName = 'Table' then ReadTable(ANode.FirstChild, AWorksheet) else if nodeName = 'WorksheetOptions' then - ReadWorksheetOptions(ANode, AWorksheet); + ReadWorksheetOptions(ANode.FirstChild, AWorksheet); ANode := ANode.NextSibling; end; end; @@ -868,10 +868,153 @@ end; -------------------------------------------------------------------------------} procedure TsSpreadExcelXMLReader.ReadWorksheetOptions(ANode: TDOMNode; AWorksheet: TsBasicWorksheet); +var + sheet: TsWorksheet absolute AWorksheet; + node: TDOMNode; + nodeName: String; + s: String; + x: Double; + n: Integer; + hasFitToPage: Boolean = false; begin - // to do + if ANode = nil then + exit; + + while ANode <> nil do begin + nodeName := ANode.NodeName; + if nodeName = 'PageSetup' then begin + node := ANode.FirstChild; + while node <> nil do begin + nodeName := node.NodeName; + if nodeName = 'Layout' then begin + s := GetAttrValue(node, 'x:Orientation'); + if s = 'Landscape' then + sheet.PageLayout.Orientation := spoLandscape; + s := GetAttrValue(node, 'x:CenterHorizontal'); + if s = '1' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poHorCentered]; + s := GetAttrValue(node, 'x:CenterVertical'); + if s = '1' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poVertCentered]; + s := GetAttrValue(node, 'x:StartPageNumber'); + if (s <> '') and TryStrToInt(s, n) then + sheet.PageLayout.StartPageNumber := n; + end + else if nodeName = 'Header' then begin + s := GetAttrValue(node, 'x:Margin'); + if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then + sheet.PageLayout.HeaderMargin := InToMM(x); + s := GetAttrValue(node, 'x:Data'); + sheet.PageLayout.Headers[0] := s; + sheet.PageLayout.Headers[1] := s; + sheet.PageLayout.Headers[2] := s; + end + else if nodeName = 'Footer' then begin + s := GetAttrValue(node, 'x:Margin'); + if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then + sheet.PageLayout.FooterMargin := InToMM(x); + s := GetAttrValue(node, 'x:Data'); + sheet.PageLayout.Footers[0] := s; + sheet.PageLayout.Footers[1] := s; + sheet.PageLayout.Footers[2] := s; + end + else if nodeName = 'PageMargins' then begin + s := GetAttrValue(node, 'x:Bottom'); + if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then + sheet.PageLayout.BottomMargin := InToMM(x); + s := GetAttrValue(node, 'x:Top'); + if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then + sheet.PageLayout.TopMargin := InToMM(x); + s := GetAttrValue(node, 'x:Left'); + if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then + sheet.PageLayout.LeftMargin := InToMM(x); + s := GetAttrValue(node, 'x:Right'); + if (s <> '') and TryStrToFloat(s, x, FPointSeparatorSettings) then + sheet.PageLayout.RightMargin := InToMM(x); + end; + node := node.NextSibling; + end; + end else + if nodeName = 'FitToPage' then begin + hasFitToPage := true; + sheet.PageLayout.Options := sheet.PageLayout.Options + [poFitPages]; + end else + if nodeName = 'Print' then begin + node := ANode.FirstChild; + while node <> nil do begin + nodeName := node.NodeName; + if nodeName = 'PaperSizeIndex' then begin + s := node.TextContent; + if (s <> '') and TryStrToInt(s, n) and (n < Length(PAPER_SIZES)) then begin + sheet.PageLayout.PageWidth := PAPER_SIZES[n, 0]; + sheet.PageLayout.pageHeight := PAPER_SIZES[n, 1]; + end; + end + else if nodeName = 'FitHeight' then begin + s := node.TextContent; + if (s <> '') and TryStrToInt(s, n) then + sheet.PageLayout.FitHeightToPages := n; + end + else if nodeName = 'FitWidth' then begin + s := node.TextContent; + if (s <> '') and TryStrToInt(s, n) then + sheet.PageLayout.FitWidthToPages := n; + end + else if nodeName = 'Scale' then begin + s := node.TextContent; + if (s <> '') and TryStrToInt(s, n) then + sheet.PageLayout.ScalingFactor := n; + end + else if nodeName = 'Gridlines' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poPrintGridLines] + else if nodeName = 'BlackAndWhite' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poMonochrome] + else if nodeName = 'DraftQuality' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poDraftQuality] + else if nodeName = 'LeftToRight' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poPrintPagesByRows] + else if nodeName = 'RowColHeadings' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poPrintHeaders] + else if nodeName = 'CommentsLayout' then begin + s := node.TextContent; + if s = 'SheetEnd' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poCommentsAtEnd] + else if s = 'InPlace' then + sheet.PageLayout.Options := sheet.PageLayout.Options + [poPrintCellComments]; + end; + node := node.NextSibling; + end; + end; + ANode := ANode.NextSibling; + end; + + // The ScalingFactor is always written to the xml file. This makes TsPageLayout + // automatically remove the poFitPages option which is restored here. + if hasFitToPage and (sheet.PageLayout.ScalingFactor <> 100) then begin + sheet.PageLayout.ScalingFactor := 100; + sheet.Pagelayout.Options := sheet.PageLayout.Options + [poFitPages]; + end; end; + (* + + function TsSpreadExcelXMLWriter.GetLayoutStr(AWorksheet: TsBasicWorksheet): String; + var + sheet: TsWorksheet absolute AWorksheet; + begin + Result := ''; + if sheet.PageLayout.Orientation = spoLandscape then + Result := Result + ' x:Orientation="Landscape"'; + if (poHorCentered in sheet.PageLayout.Options) then + Result := Result + ' x:CenterHorizontal="1"'; + if (poVertCentered in sheet.PageLayout.Options) then + Result := Result + ' x:CenterVertical="1"'; + if (poUseStartPageNumber in sheet.PageLayout.Options) then + Result := Result + ' x:StartPageNumber="' + IntToStr(sheet.PageLayout.StartPageNumber) + '"'; + Result := ''; + end; + *) + {@@ ---------------------------------------------------------------------------- Reads the "Worksheet" nodes -------------------------------------------------------------------------------}