fpspreadsheet: Read page layout from ods file (some simplifications, though)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4107 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
7c5d6d88be
commit
3902f75dfc
@ -65,8 +65,9 @@ type
|
|||||||
FColumnList: TFPList;
|
FColumnList: TFPList;
|
||||||
FRowStyleList: TFPList;
|
FRowStyleList: TFPList;
|
||||||
FRowList: TFPList;
|
FRowList: TFPList;
|
||||||
|
FPageLayoutList: TFPList;
|
||||||
|
FMasterPageList: TFPList;
|
||||||
FDateMode: TDateMode;
|
FDateMode: TDateMode;
|
||||||
FPageLayout: TsPageLayout;
|
|
||||||
// Applies internally stored column widths to current worksheet
|
// Applies internally stored column widths to current worksheet
|
||||||
procedure ApplyColWidths;
|
procedure ApplyColWidths;
|
||||||
// Applies a style to a cell
|
// Applies a style to a cell
|
||||||
@ -86,6 +87,7 @@ type
|
|||||||
// Figures out the base year for times in this file (dates are unambiguous)
|
// Figures out the base year for times in this file (dates are unambiguous)
|
||||||
procedure ReadDateMode(SpreadSheetNode: TDOMNode);
|
procedure ReadDateMode(SpreadSheetNode: TDOMNode);
|
||||||
function ReadFont(ANode: TDOMnode; APreferredIndex: Integer = -1): Integer;
|
function ReadFont(ANode: TDOMnode; APreferredIndex: Integer = -1): Integer;
|
||||||
|
function ReadHeaderFooterAsXMLString(ANode: TDOMNode): String;
|
||||||
procedure ReadRowsAndCells(ATableNode: TDOMNode);
|
procedure ReadRowsAndCells(ATableNode: TDOMNode);
|
||||||
procedure ReadRowStyle(AStyleNode: TDOMNode);
|
procedure ReadRowStyle(AStyleNode: TDOMNode);
|
||||||
|
|
||||||
@ -93,7 +95,9 @@ type
|
|||||||
FPointSeparatorSettings: TFormatSettings;
|
FPointSeparatorSettings: TFormatSettings;
|
||||||
procedure AddBuiltinNumFormats; override;
|
procedure AddBuiltinNumFormats; override;
|
||||||
procedure ReadAutomaticStyles(AStylesNode: TDOMNode);
|
procedure ReadAutomaticStyles(AStylesNode: TDOMNode);
|
||||||
|
procedure ReadMasterStyles(AStylesNode: TDOMNode);
|
||||||
procedure ReadNumFormats(AStylesNode: TDOMNode);
|
procedure ReadNumFormats(AStylesNode: TDOMNode);
|
||||||
|
function ReadPageLayout(AStylesNode: TDOMNode; ATableStyleName: String): PsPageLayout;
|
||||||
procedure ReadSettings(AOfficeSettingsNode: TDOMNode);
|
procedure ReadSettings(AOfficeSettingsNode: TDOMNode);
|
||||||
procedure ReadStyles(AStylesNode: TDOMNode);
|
procedure ReadStyles(AStylesNode: TDOMNode);
|
||||||
{ Record writing methods }
|
{ Record writing methods }
|
||||||
@ -282,6 +286,20 @@ type
|
|||||||
AutoRowHeight: Boolean;
|
AutoRowHeight: Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ PageLayout items stored in PageLayoutList }
|
||||||
|
TPageLayoutData = class
|
||||||
|
public
|
||||||
|
Name: String;
|
||||||
|
PageLayout: TsPageLayout;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ MasterPage items stored in MasterPageList }
|
||||||
|
TMasterPageData = class
|
||||||
|
public
|
||||||
|
Name: String;
|
||||||
|
PageLayoutName: String;
|
||||||
|
end;
|
||||||
|
|
||||||
(* --- presently not used, but this may change... ---
|
(* --- presently not used, but this may change... ---
|
||||||
|
|
||||||
{ Row data items stored in the RowList of the reader }
|
{ Row data items stored in the RowList of the reader }
|
||||||
@ -605,23 +623,24 @@ end;
|
|||||||
constructor TsSpreadOpenDocReader.Create(AWorkbook: TsWorkbook);
|
constructor TsSpreadOpenDocReader.Create(AWorkbook: TsWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
|
|
||||||
FPointSeparatorSettings := DefaultFormatSettings;
|
FPointSeparatorSettings := DefaultFormatSettings;
|
||||||
FPointSeparatorSettings.DecimalSeparator := '.';
|
FPointSeparatorSettings.DecimalSeparator := '.';
|
||||||
FPointSeparatorSettings.ListSeparator := ';'; // for formulas
|
FPointSeparatorSettings.ListSeparator := ';'; // for formulas
|
||||||
|
|
||||||
FCellFormatList := TsCellFormatList.Create(true);
|
FCellFormatList := TsCellFormatList.Create(true);
|
||||||
// Allow duplicates because style names used in cell records will not be found any more.
|
// true = allow duplicates because style names used in cell records will not be found any more.
|
||||||
FColumnStyleList := TFPList.Create;
|
FColumnStyleList := TFPList.Create;
|
||||||
FColumnList := TFPList.Create;
|
FColumnList := TFPList.Create;
|
||||||
FRowStyleList := TFPList.Create;
|
FRowStyleList := TFPList.Create;
|
||||||
FRowList := TFPList.Create;
|
FRowList := TFPList.Create;
|
||||||
// FVolatileNumFmtList := TStringList.Create;
|
FPageLayoutList := TFPList.Create;
|
||||||
|
FMasterPageList := TFPList.Create;
|
||||||
|
|
||||||
// Set up the default palette in order to have the default color names correct.
|
// Set up the default palette in order to have the default color names correct.
|
||||||
Workbook.UseDefaultPalette;
|
Workbook.UseDefaultPalette;
|
||||||
// Initial base date in case it won't be read from file
|
// Initial base date in case it won't be read from file
|
||||||
FDateMode := dm1899;
|
FDateMode := dm1899;
|
||||||
// Initialize internal PageLayout record
|
|
||||||
InitPageLayout(FPageLayout);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TsSpreadOpenDocReader.Destroy;
|
destructor TsSpreadOpenDocReader.Destroy;
|
||||||
@ -640,7 +659,11 @@ begin
|
|||||||
for j := FRowStyleList.Count-1 downto 0 do TObject(FRowStyleList[j]).Free;
|
for j := FRowStyleList.Count-1 downto 0 do TObject(FRowStyleList[j]).Free;
|
||||||
FRowStyleList.Free;
|
FRowStyleList.Free;
|
||||||
|
|
||||||
// FVolatileNumFmtList.Free;
|
for j := FPageLayoutList.Count-1 downto 0 do TObject(FPageLayoutList[j]).Free;
|
||||||
|
FPageLayoutList.Free;
|
||||||
|
|
||||||
|
for j := FMasterPageList.Count-1 downto 0 do TObject(FMasterPageList[j]).Free;
|
||||||
|
FMasterPageList.Free;
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
@ -860,6 +883,7 @@ var
|
|||||||
layoutNode: TDOMNode;
|
layoutNode: TDOMNode;
|
||||||
node: TDOMNode;
|
node: TDOMNode;
|
||||||
s: String;
|
s: String;
|
||||||
|
data: TPageLayoutData;
|
||||||
begin
|
begin
|
||||||
if not Assigned(AStylesNode) then
|
if not Assigned(AStylesNode) then
|
||||||
exit;
|
exit;
|
||||||
@ -868,79 +892,234 @@ begin
|
|||||||
begin
|
begin
|
||||||
nodeName := layoutNode.NodeName;
|
nodeName := layoutNode.NodeName;
|
||||||
if nodeName = 'style:page-layout' then begin
|
if nodeName = 'style:page-layout' then begin
|
||||||
s := GetAttrValue(layoutNode, 'style:name');
|
data := TPageLayoutData.Create;
|
||||||
if s = 'Mpm1' then
|
InitPageLayout(data.PageLayout);
|
||||||
|
data.Name := GetAttrValue(layoutNode, 'style:name');
|
||||||
|
|
||||||
|
node := layoutNode.FirstChild;
|
||||||
|
while node <> nil do
|
||||||
begin
|
begin
|
||||||
node := layoutNode.FirstChild;
|
nodeName := node.NodeName;
|
||||||
while node <> nil do
|
if nodeName = 'style:page-layout-properties' then
|
||||||
begin
|
begin
|
||||||
nodeName := node.NodeName;
|
s := GetAttrValue(node, 'style:print-orientation');
|
||||||
if nodeName = 'style:page-layout-properties' then
|
if s = 'landscape' then
|
||||||
|
data.PageLayout.Orientation := spoLandscape
|
||||||
|
else if s = 'portrait' then
|
||||||
|
data.PageLayout.Orientation := spoPortrait;
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'fo:page-width');
|
||||||
|
if s <> '' then
|
||||||
|
data.PageLayout.PageWidth := PtsToMM(HTMLLengthStrToPts(s));
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'fo:page-height');
|
||||||
|
if s <> '' then
|
||||||
|
data.PageLayout.PageHeight := PtsToMM(HTMLLengthStrToPts(s));
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'fo:margin-top');
|
||||||
|
if s <> '' then
|
||||||
|
data.PageLayout.TopMargin := PtsToMM(HTMLLengthStrToPts(s));
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'fo:margin-bottom');
|
||||||
|
if s <> '' then
|
||||||
|
data.PageLayout.BottomMargin := PtsToMM(HTMLLengthStrToPts(s));
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'fo:margin-left');
|
||||||
|
if s <> '' then
|
||||||
|
data.PageLayout.LeftMargin := PtsToMM(HTMLLengthStrToPts(s));
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'fo:margin-right');
|
||||||
|
if s <> '' then
|
||||||
|
data.PageLayout.RightMargin := PtsToMM(HTMLLengthStrToPts(s));
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'style:scale-to');
|
||||||
|
if (s <> '') then
|
||||||
begin
|
begin
|
||||||
s := GetAttrValue(node, 'style:print-orientation');
|
if s[Length(s)] = '%' then Delete(s, Length(s), 1);
|
||||||
if s = 'landscape' then
|
data.PageLayout.ScalingFactor := StrToFloat(s, FPointSeparatorSettings);
|
||||||
FPageLayout.Orientation := spoLandscape
|
|
||||||
else if s = 'portrait' then
|
|
||||||
FPageLayout.Orientation := spoPortrait;
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'fo:page-width');
|
|
||||||
if s <> '' then
|
|
||||||
FPageLayout.PageWidth := PtsToMM(HTMLLengthStrToPts(s));
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'fo:page-height');
|
|
||||||
if s <> '' then
|
|
||||||
FPageLayout.PageHeight := PtsToMM(HTMLLengthStrToPts(s));
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'fo:margin-top');
|
|
||||||
if s <> '' then
|
|
||||||
FPageLayout.TopMargin := PtsToMM(HTMLLengthStrToPts(s));
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'fo:margin-bottom');
|
|
||||||
if s <> '' then
|
|
||||||
FPageLayout.BottomMargin := PtsToMM(HTMLLengthStrToPts(s));
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'fo:margin-left');
|
|
||||||
if s <> '' then
|
|
||||||
FPageLayout.LeftMargin := PtsToMM(HTMLLengthStrToPts(s));
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'fo:margin-right');
|
|
||||||
if s <> '' then
|
|
||||||
FPageLayout.RightMargin := PtsToMM(HTMLLengthStrToPts(s));
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'style:scale-to');
|
|
||||||
if (s <> '') then
|
|
||||||
begin
|
|
||||||
if s[Length(s)] = '%' then Delete(s, Length(s), 1);
|
|
||||||
FPageLayout.ScalingFactor := StrToFloat(s, FPointSeparatorSettings);
|
|
||||||
end;
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'style:print');
|
|
||||||
if pos('grid', s) > 0 then
|
|
||||||
Include(FPageLayout.Options, poPrintGridLines);
|
|
||||||
if pos('headers', s) > 0 then
|
|
||||||
Include(FPageLayout.Options, poPrintHeaders);
|
|
||||||
if pos('annotations', s) > 0 then
|
|
||||||
Include(FPageLayout.Options, poPrintCellComments);
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'style:print-page-order');
|
|
||||||
if s = 'ltr' then // "left-to-right", the other option is "ttb = top-to-bottom"
|
|
||||||
Include(FPageLayout.Options, poPrintPagesByRows);
|
|
||||||
|
|
||||||
s := GetAttrValue(node, 'style:first-page-number');
|
|
||||||
if s = 'continue' then
|
|
||||||
Exclude(FPageLayout.Options, poUseStartPageNumber)
|
|
||||||
else
|
|
||||||
if TryStrToInt(s, FPageLayout.StartPageNumber) then
|
|
||||||
Include(FPageLayout.Options, poUseStartPageNumber);
|
|
||||||
end;
|
end;
|
||||||
node := node.NextSibling;
|
|
||||||
|
s := GetAttrValue(node, 'style:print');
|
||||||
|
if pos('grid', s) > 0 then
|
||||||
|
Include(data.PageLayout.Options, poPrintGridLines);
|
||||||
|
if pos('headers', s) > 0 then
|
||||||
|
Include(data.PageLayout.Options, poPrintHeaders);
|
||||||
|
if pos('annotations', s) > 0 then
|
||||||
|
Include(data.PageLayout.Options, poPrintCellComments);
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'style:print-page-order');
|
||||||
|
if s = 'ltr' then // "left-to-right", the other option is "ttb = top-to-bottom"
|
||||||
|
Include(data.PageLayout.Options, poPrintPagesByRows);
|
||||||
|
|
||||||
|
s := GetAttrValue(node, 'style:first-page-number');
|
||||||
|
if s = 'continue' then
|
||||||
|
Exclude(data.PageLayout.Options, poUseStartPageNumber)
|
||||||
|
else
|
||||||
|
if TryStrToInt(s, data.PageLayout.StartPageNumber) then
|
||||||
|
Include(data.PageLayout.Options, poUseStartPageNumber);
|
||||||
|
|
||||||
|
FPageLayoutList.Add(data);
|
||||||
end;
|
end;
|
||||||
|
node := node.NextSibling;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
layoutNode := layoutNode.NextSibling;
|
layoutNode := layoutNode.NextSibling;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TsSpreadOpenDocReader.ReadHeaderFooterAsXMLString(ANode: TDOMNode): String;
|
||||||
|
var
|
||||||
|
regionNode, textNode, spanNode: TDOMNode;
|
||||||
|
nodeName: String;
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
regionNode := ANode.FirstChild;
|
||||||
|
while regionNode <> nil do
|
||||||
|
begin
|
||||||
|
nodeName := regionNode.NodeName;
|
||||||
|
if nodeName = 'text:p' then
|
||||||
|
begin
|
||||||
|
if Result <> '' then Result := Result + LineEnding;
|
||||||
|
textNode := regionNode.FirstChild;
|
||||||
|
while textNode <> nil do
|
||||||
|
begin
|
||||||
|
nodeName := textNode.NodeName;
|
||||||
|
case nodeName of
|
||||||
|
'#text':
|
||||||
|
Result := Result + textNode.NodeValue;
|
||||||
|
'text:sheet-name':
|
||||||
|
Result := Result + '&A';
|
||||||
|
'text:page-number':
|
||||||
|
Result := Result + '&P';
|
||||||
|
'text:page-count':
|
||||||
|
Result := Result + '&N';
|
||||||
|
'text:date':
|
||||||
|
Result := Result + '&D';
|
||||||
|
'text:time':
|
||||||
|
Result := Result + '&T';
|
||||||
|
'text:file-name':
|
||||||
|
case GetAttrValue(textNode, 'text:display') of
|
||||||
|
'full': Result := Result + '&Z&F';
|
||||||
|
'path': Result := Result + '&Z';
|
||||||
|
else Result := Result + '&F';
|
||||||
|
end;
|
||||||
|
'text:span':
|
||||||
|
begin
|
||||||
|
spanNode := textNode.FirstChild;
|
||||||
|
while spanNode <> nil do
|
||||||
|
begin
|
||||||
|
nodeName := spanNode.NodeName;
|
||||||
|
case nodeName of
|
||||||
|
'#text': Result := Result + spanNode.NodeValue;
|
||||||
|
end;
|
||||||
|
spanNode := spanNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
textNode := textNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
if (nodeName = 'style:region-left') then
|
||||||
|
begin
|
||||||
|
s := ReadHeaderFooterAsXMLString(regionNode);
|
||||||
|
Result := Result + '&L' + s;
|
||||||
|
end else
|
||||||
|
if (nodeName = 'style:region-center') then
|
||||||
|
begin
|
||||||
|
s := ReadHeaderFooterAsXMLString(regionNode);
|
||||||
|
Result := Result + '&C' + s;
|
||||||
|
end else
|
||||||
|
if (nodeName = 'style:region-right') then
|
||||||
|
begin
|
||||||
|
s := ReadHeaderFooterAsXMLString(regionNode);
|
||||||
|
Result := Result + '&R' + s;
|
||||||
|
end;
|
||||||
|
regionNode := regionNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOpenDocReader.ReadMasterStyles(AStylesNode: TDOMNode);
|
||||||
|
var
|
||||||
|
masternode, stylenode, regionnode: TDOMNode;
|
||||||
|
nodeName: String;
|
||||||
|
s: String;
|
||||||
|
data: TMasterPageData;
|
||||||
|
pagelayout: PsPageLayout;
|
||||||
|
j: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if AStylesNode = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
masterNode := AStylesNode.FirstChild;
|
||||||
|
while (masterNode <> nil) do
|
||||||
|
begin
|
||||||
|
nodeName := masterNode.NodeName;
|
||||||
|
if nodeName = 'style:master-page' then begin
|
||||||
|
s := GetAttrvalue(masterNode, 'style:page-layout-name');
|
||||||
|
|
||||||
|
pageLayout := nil;
|
||||||
|
for j:=0 to FPageLayoutList.Count-1 do
|
||||||
|
if TPageLayoutData(FPageLayoutList[j]).Name = s then
|
||||||
|
begin
|
||||||
|
pageLayout := @TPageLayoutData(FPageLayoutList[j]).PageLayout;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
if pagelayout = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
data := TMasterPageData.create;
|
||||||
|
data.Name := GetAttrValue(masternode, 'style:name');
|
||||||
|
data.PageLayoutName := s;
|
||||||
|
FMasterPageList.Add(data);
|
||||||
|
|
||||||
|
styleNode := masterNode.FirstChild;
|
||||||
|
while styleNode <> nil do begin
|
||||||
|
nodeName := styleNode.NodeName;
|
||||||
|
if nodeName = 'style:header' then
|
||||||
|
begin
|
||||||
|
s := ReadHeaderFooterAsXMLString(styleNode);
|
||||||
|
if s <> '' then
|
||||||
|
pageLayout^.Headers[HEADER_FOOTER_INDEX_ODD] := s;
|
||||||
|
end else
|
||||||
|
if nodeName = 'style:header-left' then
|
||||||
|
begin
|
||||||
|
s := ReadHeaderFooterAsXMLString(styleNode);
|
||||||
|
if s <> '' then
|
||||||
|
begin
|
||||||
|
pageLayout^.Headers[HEADER_FOOTER_INDEX_EVEN] := s;
|
||||||
|
Include(pageLayout^.Options, poDifferentOddEven);
|
||||||
|
end;
|
||||||
|
s := GetAttrValue(styleNode, 'style:display');
|
||||||
|
if s = 'false' then
|
||||||
|
Exclude(pagelayout^.Options, poDifferentOddEven);
|
||||||
|
end else
|
||||||
|
if nodeName = 'style:footer' then
|
||||||
|
begin
|
||||||
|
s := ReadHeaderFooterAsXMLString(styleNode);
|
||||||
|
if s <> '' then
|
||||||
|
pageLayout^.Footers[HEADER_FOOTER_INDEX_ODD] := s;
|
||||||
|
end else
|
||||||
|
if nodeName = 'style:footer-left' then
|
||||||
|
begin
|
||||||
|
s := ReadHeaderFooterAsXMLString(styleNode);
|
||||||
|
if s <> '' then
|
||||||
|
begin
|
||||||
|
pageLayout^.Footers[HEADER_FOOTER_INDEX_EVEN] := s;
|
||||||
|
Include(pageLayout^.Options, poDifferentOddEven);
|
||||||
|
end;
|
||||||
|
s := GetAttrValue(styleNode, 'style:display');
|
||||||
|
if s = 'false' then
|
||||||
|
Exclude(pagelayout^.Options, poDifferentOddEven);
|
||||||
|
end;
|
||||||
|
styleNode := styleNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
masterNode := masterNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadBlank(ARow, ACol: Cardinal;
|
procedure TsSpreadOpenDocReader.ReadBlank(ARow, ACol: Cardinal;
|
||||||
ACellNode: TDOMNode);
|
ACellNode: TDOMNode);
|
||||||
var
|
var
|
||||||
@ -1382,6 +1561,7 @@ var
|
|||||||
StylesNode: TDOMNode;
|
StylesNode: TDOMNode;
|
||||||
OfficeSettingsNode: TDOMNode;
|
OfficeSettingsNode: TDOMNode;
|
||||||
nodename: String;
|
nodename: String;
|
||||||
|
pageLayout: PsPageLayout;
|
||||||
begin
|
begin
|
||||||
//unzip files into AFileName path
|
//unzip files into AFileName path
|
||||||
FilePath := GetTempDir(false);
|
FilePath := GetTempDir(false);
|
||||||
@ -1411,6 +1591,9 @@ begin
|
|||||||
StylesNode := Doc.DocumentElement.FindNode('office:automatic-styles');
|
StylesNode := Doc.DocumentElement.FindNode('office:automatic-styles');
|
||||||
ReadAutomaticStyles(StylesNode);
|
ReadAutomaticStyles(StylesNode);
|
||||||
|
|
||||||
|
StylesNode := Doc.DocumentElement.FindNode('office:master-styles');
|
||||||
|
ReadMasterStyles(StylesNode);
|
||||||
|
|
||||||
Doc.Free;
|
Doc.Free;
|
||||||
|
|
||||||
//process the content.xml file
|
//process the content.xml file
|
||||||
@ -1442,14 +1625,18 @@ begin
|
|||||||
TableNode := TableNode.NextSibling;
|
TableNode := TableNode.NextSibling;
|
||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
FWorkSheet := FWorkbook.AddWorksheet(GetAttrValue(TableNode,'table:name'), true);
|
FWorkSheet := FWorkbook.AddWorksheet(GetAttrValue(TableNode, 'table:name'), true);
|
||||||
FWorksheet.PageLayout := FPageLayout;
|
|
||||||
// Collect column styles used
|
// Collect column styles used
|
||||||
ReadColumns(TableNode);
|
ReadColumns(TableNode);
|
||||||
// Process each row inside the sheet and process each cell of the row
|
// Process each row inside the sheet and process each cell of the row
|
||||||
ReadRowsAndCells(TableNode);
|
ReadRowsAndCells(TableNode);
|
||||||
|
// Read page layout
|
||||||
|
pageLayout := ReadPageLayout(StylesNode, GetAttrValue(TableNode, 'table:style-name'));
|
||||||
|
if pageLayout <> nil then
|
||||||
|
FWorksheet.PageLayout := pagelayout^;
|
||||||
// Handle columns and rows
|
// Handle columns and rows
|
||||||
ApplyColWidths;
|
ApplyColWidths;
|
||||||
|
// Page layout
|
||||||
FixCols(FWorksheet);
|
FixCols(FWorksheet);
|
||||||
FixRows(FWorksheet);
|
FixRows(FWorksheet);
|
||||||
// Continue with next table
|
// Continue with next table
|
||||||
@ -2011,6 +2198,71 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Finds the PageLayout record for a given TableStyle name in the "styles" nodes.
|
||||||
|
First, seeks the TableStyle among the children of the "styles" node in the
|
||||||
|
contents.xml - this node contains the name of the used master page.
|
||||||
|
Then seeks the FMasterPageList for the entry with the determined master page
|
||||||
|
name. This entry contains the name of the associated PageLayoutData stored in
|
||||||
|
the PageLayoutList which, finally, contains the requested PageLayout record. }
|
||||||
|
function TsSpreadOpenDocReader.ReadPageLayout(AStylesNode: TDOMNode;
|
||||||
|
ATableStyleName: String): PsPageLayout;
|
||||||
|
var
|
||||||
|
nodeName, s: String;
|
||||||
|
node: TDOMNode;
|
||||||
|
masterPageName: String;
|
||||||
|
masterPageData: TMasterPageData;
|
||||||
|
pageLayoutData: TPageLayoutData;
|
||||||
|
i, j: Integer;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
|
||||||
|
if AStylesNode = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{ Looking through the "styles" node...}
|
||||||
|
node := AStylesNode.FirstChild;
|
||||||
|
while node <> nil do
|
||||||
|
begin
|
||||||
|
nodeName := node.NodeName;
|
||||||
|
{ ... for the node which is named like the requested TableStyle }
|
||||||
|
if nodeName = 'style:style' then
|
||||||
|
begin
|
||||||
|
s := GetAttrValue(node, 'style:name');
|
||||||
|
if s = ATableStyleName then
|
||||||
|
begin
|
||||||
|
{ Found: extract the name of the master page }
|
||||||
|
masterPageName := GetAttrValue(node, 'style:master-page-name');
|
||||||
|
if masterPageName = '' then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{ Looking through the MasterPage list...}
|
||||||
|
for i:=0 to FMasterPageList.Count-1 do
|
||||||
|
begin
|
||||||
|
masterPageData := TMasterPageData(FMasterPageList[i]);
|
||||||
|
{ ... for the entry with the found master page name }
|
||||||
|
if masterPageData.Name = masterPageName then
|
||||||
|
begin
|
||||||
|
{ Found: looking through the PageLayout list ...}
|
||||||
|
for j:=0 to FPageLayoutList.Count-1 do
|
||||||
|
begin
|
||||||
|
pageLayoutData := TPageLayoutData(FPageLayoutList[j]);
|
||||||
|
{ ... for the entry with the name specified by the master page }
|
||||||
|
if pageLayoutData.Name = masterPageData.PageLayoutName then
|
||||||
|
begin
|
||||||
|
{ Found: Return a pointer to the PageLayout record stored in the list }
|
||||||
|
Result := @pageLayoutData.PageLayout;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ Not found: try next node in the styles list }
|
||||||
|
node := node.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ Reads the cells in the given table. Loops through all rows, and then finds all
|
{ Reads the cells in the given table. Loops through all rows, and then finds all
|
||||||
cells of each row. }
|
cells of each row. }
|
||||||
procedure TsSpreadOpenDocReader.ReadRowsAndCells(ATableNode: TDOMNode);
|
procedure TsSpreadOpenDocReader.ReadRowsAndCells(ATableNode: TDOMNode);
|
||||||
|
@ -2925,16 +2925,16 @@ begin
|
|||||||
AStrings.Add(Format(' Copies=%d', [ASheet.PageLayout.Copies]));
|
AStrings.Add(Format(' Copies=%d', [ASheet.PageLayout.Copies]));
|
||||||
if (ASheet.PageLayout.Options * [poDifferentOddEven, poDifferentFirst] <> []) then
|
if (ASheet.PageLayout.Options * [poDifferentOddEven, poDifferentFirst] <> []) then
|
||||||
begin
|
begin
|
||||||
AStrings.Add(Format(' Header (first)=%s', [ASheet.PageLayout.Headers[0]]));
|
AStrings.Add(Format(' Header (first)=%s', [StringReplace(ASheet.PageLayout.Headers[0], LineEnding, '\n', [rfReplaceAll])]));
|
||||||
AStrings.Add(Format(' Header (odd)=%s', [ASheet.PageLayout.Headers[1]]));
|
AStrings.Add(Format(' Header (odd)=%s', [StringReplace(ASheet.PageLayout.Headers[1], LineEnding, '\n', [rfReplaceAll])]));
|
||||||
AStrings.Add(Format(' Header (even)=%s', [ASheet.PageLayout.Headers[2]]));
|
AStrings.Add(Format(' Header (even)=%s', [StringReplace(ASheet.PageLayout.Headers[2], LineEnding, '\n', [rfReplaceAll])]));
|
||||||
AStrings.Add(Format(' Footer (first)=%s', [ASheet.PageLayout.Footers[0]]));
|
AStrings.Add(Format(' Footer (first)=%s', [StringReplace(ASheet.PageLayout.Footers[0], LineEnding, '\n', [rfReplaceAll])]));
|
||||||
AStrings.Add(Format(' Footer (odd)=%s', [ASheet.PageLayout.Footers[1]]));
|
AStrings.Add(Format(' Footer (odd)=%s', [StringReplace(ASheet.PageLayout.Footers[1], LineEnding, '\n', [rfReplaceall])]));
|
||||||
AStrings.Add(Format(' Footer (even)=%s', [ASheet.PageLayout.Footers[2]]));
|
AStrings.Add(Format(' Footer (even)=%s', [StringReplace(ASheet.PageLayout.Footers[2], LineEnding, '\n', [rfReplaceAll])]));
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
AStrings.Add(Format(' Header=%s', [ASheet.PageLayout.Headers[1]]));
|
AStrings.Add(Format(' Header=%s', [StringReplace(ASheet.PageLayout.Headers[1], LineEnding, '\n', [rfReplaceAll])]));
|
||||||
AStrings.Add(Format(' Footer=%s', [ASheet.PageLayout.Footers[1]]));
|
AStrings.Add(Format(' Footer=%s', [StringReplace(ASheet.PageLayout.Footers[1], LineEnding, '\n', [rfReplaceAll])]));
|
||||||
end;
|
end;
|
||||||
s := '';
|
s := '';
|
||||||
for po in TsPrintOption do
|
for po in TsPrintOption do
|
||||||
|
@ -714,6 +714,8 @@ type
|
|||||||
Footers: array[0..2] of string;
|
Footers: array[0..2] of string;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
PsPageLayout = ^TsPageLayout;
|
||||||
|
|
||||||
const
|
const
|
||||||
{@@ Indexes to be used for the various headers and footers }
|
{@@ Indexes to be used for the various headers and footers }
|
||||||
HEADER_FOOTER_INDEX_FIRST = 0;
|
HEADER_FOOTER_INDEX_FIRST = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user