From 070845d3ae2b576b046e22f92d1fcb211dc1e025 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 26 May 2014 08:03:36 +0000 Subject: [PATCH] fpspreadsheet: Add property "Name" to TsNumFormatData. When reading ods files consider also styles in "styles.xml". git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3099 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/fpspreadsheet/fpsopendocument.pas | 46 ++++++++++++++------ components/fpspreadsheet/fpspreadsheet.pas | 35 ++++++++++++--- 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/components/fpspreadsheet/fpsopendocument.pas b/components/fpspreadsheet/fpsopendocument.pas index 3d7efbd20..dc111786c 100755 --- a/components/fpspreadsheet/fpsopendocument.pas +++ b/components/fpspreadsheet/fpsopendocument.pas @@ -68,7 +68,7 @@ type procedure ReadDateMode(SpreadSheetNode: TDOMNode); protected procedure CreateNumFormatList; override; - procedure ReadAutomaticStyles; + procedure ReadNumFormats(AStylesNode: TDOMNode); { Record writing methods } procedure ReadFormula(ARow : Word; ACol : Word; ACellNode: TDOMNode); procedure ReadLabel(ARow : Word; ACol : Word; ACellNode: TDOMNode); @@ -240,6 +240,7 @@ var UnZip : TUnZipper; FileList : TStringList; BodyNode, SpreadSheetNode, TableNode, RowNode, CellNode : TDOMNode; + StylesNode: TDOMNode; ParamRowsRepeated, ParamColsRepeated, ParamValueType, ParamFormula : string; RowsCount, ColsCount : integer; begin @@ -248,6 +249,7 @@ begin UnZip:=TUnZipper.Create; UnZip.OutputPath:=FilePath; FileList:=TStringList.Create; + FileList.Add('styles.xml'); FileList.Add('content.xml'); try Unzip.UnZipFiles(AFileName,FileList); @@ -258,11 +260,21 @@ begin FDoc := nil; try - //process the xml file + // process the styles.xml file + ReadXMLFile(FDoc, FilePath+'styles.xml'); + DeleteFile(FilePath+'styles.xml'); + + StylesNode := FDoc.DocumentElement.FindNode('office:styles'); + ReadNumFormats(StylesNode); + + // FDoc.Free; + + //process the content.xml file ReadXMLFile(FDoc, FilePath+'content.xml'); DeleteFile(FilePath+'content.xml'); - ReadAutomaticStyles; + StylesNode := FDoc.DocumentElement.FindNode('office:automatic-styles'); + ReadNumFormats(StylesNode); BodyNode := FDoc.DocumentElement.FindNode('office:body'); if not Assigned(BodyNode) then Exit; @@ -472,30 +484,36 @@ begin end; end; -procedure TsSpreadOpenDocReader.ReadAutomaticStyles; +procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode); var - StylesNode, NumFormatNode, node: TDOMNode; + NumFormatNode, node: TDOMNode; decs: Integer; fmtName: String; grouping: boolean; fmt: String; nf: TsNumberFormat; nex: Integer; + s: String; begin - StylesNode := FDoc.DocumentElement.FindNode('office:automatic-styles'); - if not Assigned(StylesNode) then Exit; + if not Assigned(AStylesNode) then + exit; - NumFormatNode := StylesNode.FirstChild; + NumFormatNode := AStylesNode.FirstChild; while Assigned(NumFormatNode) do begin if NumFormatNode.NodeName = 'number:number-style' then begin fmtName := GetAttrValue(NumFormatNode, 'style:name'); node := NumFormatNode.FindNode('number:number'); if node <> nil then begin - decs := StrToInt(GetAttrValue(node, 'number:decimal-places')); - grouping := GetAttrValue(node, 'grouping') = 'true'; - nf := IfThen(grouping, nfFixedTh, nfFixed); + s := GetAttrValue(node, 'number:decimal-places'); + if s = '' then + nf := nfGeneral + else begin + decs := StrToInt(s); + grouping := GetAttrValue(node, 'grouping') = 'true'; + nf := IfThen(grouping, nfFixedTh, nfFixed); + end; fmt := BuildNumberFormatString(nf, Workbook.FormatSettings, decs); - NumFormatList.AddFormat(fmt, nf, decs); + NumFormatList.AddFormat(fmtName, fmt, nf, decs); end; node := NumFormatNode.FindNode('number:scientific-number'); if node <> nil then begin @@ -504,7 +522,7 @@ begin nex := StrToInt(GetAttrValue(node, 'number:min-exponent-digits')); fmt := BuildNumberFormatString(nfFixed, Workbook.FormatSettings, decs); fmt := fmt + 'E+' + DupeString('0', nex); - NumFormatList.AddFormat(fmt, nf, decs); + NumFormatList.AddFormat(fmtName, fmt, nf, decs); end; end else if NumFormatNode.NodeName = 'number:percentage-style' then begin @@ -514,7 +532,7 @@ begin nf := nfPercentage; decs := StrToInt(GetAttrValue(node, 'number:decimal-places')); fmt := BuildNumberFormatString(nf, Workbook.FormatSettings, decs); - NumFormatList.AddFormat(fmt, nf, decs); + NumFormatList.AddFormat(fmtName, fmt, nf, decs); end; end; NumFormatNode := NumFormatNode.NextSibling; diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index 467707594..9e2217953 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -568,6 +568,7 @@ type TsNumFormatData = class public Index: Integer; + Name: String; NumFormat: TsNumberFormat; Decimals: Byte; CurrencySymbol: String; @@ -590,9 +591,15 @@ type constructor Create(AWorkbook: TsWorkbook); destructor Destroy; override; function AddFormat(AFormatCell: PCell): Integer; overload; + function AddFormat(AFormatIndex: Integer; AFormatName, AFormatString: String; + ANumFormat: TsNumberFormat; ADecimals: Byte = 0; + ACurrencySymbol: String = ''): Integer; overload; function AddFormat(AFormatIndex: Integer; AFormatString: String; ANumFormat: TsNumberFormat; ADecimals: Byte = 0; ACurrencySymbol: String = ''): Integer; overload; + function AddFormat(AFormatName, AFormatString: String; + ANumFormat: TsNumberFormat; ADecimals: Byte = 0; + ACurrencySymbol: String = ''): Integer; overload; function AddFormat(AFormatString: String; ANumFormat: TsNumberFormat; ADecimals: Byte = 0; ACurrencySymbol: String = ''): Integer; overload; procedure AnalyzeAndAdd(AFormatIndex: Integer; AFormatString: String); @@ -2952,22 +2959,22 @@ begin end; { Adds a new number format data to the list and returns the list index of the - new (or present) item. } + new item. } function TsCustomNumFormatList.AddFormat(AFormatIndex: Integer; - AFormatString: String; ANumFormat: TsNumberFormat; ADecimals: byte = 0; - ACurrencySymbol: String = ''): integer; + AFormatName, AFormatString: String; ANumFormat: TsNumberFormat; + ADecimals: Byte = 0; ACurrencySymbol: String = ''): Integer; var item: TsNumFormatData; begin item := TsNumFormatData.Create; item.Index := AFormatIndex; + item.Name := AFormatName; item.NumFormat := ANumFormat; if AFormatString = '' then begin if IsDateTimeFormat(ANumFormat) then AFormatString := BuildDateTimeFormatString(ANumFormat, Workbook.FormatSettings, AFormatString) else - if item.NumFormat <> nfCustom then AFormatString := BuildNumberFormatString(ANumFormat, Workbook.FormatSettings, ADecimals, ACurrencySymbol); end; @@ -2977,7 +2984,14 @@ begin Result := inherited Add(item); end; -function TsCustomNumFormatList.AddFormat(AFormatString: String; +function TsCustomNumFormatList.AddFormat(AFormatIndex: Integer; + AFormatString: String; ANumFormat: TsNumberFormat; ADecimals: byte = 0; + ACurrencySymbol: String = ''): integer; +begin + Result := AddFormat(AFormatIndex, '', AFormatString, ANumFormat, ADecimals, ACurrencySymbol); +end; + +function TsCustomNumFormatList.AddFormat(AFormatName, AFormatString: String; ANumFormat: TsNumberFormat; ADecimals: Byte = 0; ACurrencySymbol: String = ''): Integer; begin @@ -2985,11 +2999,18 @@ begin Result := 0; exit; end; - Result := AddFormat(FNextFormatIndex, AFormatString, ANumFormat, ADecimals, - ACurrencySymbol); + Result := AddFormat(FNextFormatIndex, '', AFormatString, ANumFormat, + ADecimals, ACurrencySymbol); inc(FNextFormatIndex); end; +function TsCustomNumFormatList.AddFormat(AFormatString: String; + ANumFormat: TsNumberFormat; ADecimals: Byte = 0; + ACurrencySymbol: String = ''): Integer; +begin + Result := AddFormat('', AFormatString, ANumFormat, ADecimals, ACurrencySymbol); +end; + function TsCustomNumFormatList.AddFormat(AFormatCell: PCell): Integer; var item: TsNumFormatData;