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
This commit is contained in:
wp_xxyyzz
2014-05-26 08:03:36 +00:00
parent a4bc6fc8cf
commit 070845d3ae
2 changed files with 60 additions and 21 deletions

View File

@ -68,7 +68,7 @@ type
procedure ReadDateMode(SpreadSheetNode: TDOMNode); procedure ReadDateMode(SpreadSheetNode: TDOMNode);
protected protected
procedure CreateNumFormatList; override; procedure CreateNumFormatList; override;
procedure ReadAutomaticStyles; procedure ReadNumFormats(AStylesNode: TDOMNode);
{ Record writing methods } { Record writing methods }
procedure ReadFormula(ARow : Word; ACol : Word; ACellNode: TDOMNode); procedure ReadFormula(ARow : Word; ACol : Word; ACellNode: TDOMNode);
procedure ReadLabel(ARow : Word; ACol : Word; ACellNode: TDOMNode); procedure ReadLabel(ARow : Word; ACol : Word; ACellNode: TDOMNode);
@ -240,6 +240,7 @@ var
UnZip : TUnZipper; UnZip : TUnZipper;
FileList : TStringList; FileList : TStringList;
BodyNode, SpreadSheetNode, TableNode, RowNode, CellNode : TDOMNode; BodyNode, SpreadSheetNode, TableNode, RowNode, CellNode : TDOMNode;
StylesNode: TDOMNode;
ParamRowsRepeated, ParamColsRepeated, ParamValueType, ParamFormula : string; ParamRowsRepeated, ParamColsRepeated, ParamValueType, ParamFormula : string;
RowsCount, ColsCount : integer; RowsCount, ColsCount : integer;
begin begin
@ -248,6 +249,7 @@ begin
UnZip:=TUnZipper.Create; UnZip:=TUnZipper.Create;
UnZip.OutputPath:=FilePath; UnZip.OutputPath:=FilePath;
FileList:=TStringList.Create; FileList:=TStringList.Create;
FileList.Add('styles.xml');
FileList.Add('content.xml'); FileList.Add('content.xml');
try try
Unzip.UnZipFiles(AFileName,FileList); Unzip.UnZipFiles(AFileName,FileList);
@ -258,11 +260,21 @@ begin
FDoc := nil; FDoc := nil;
try 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'); ReadXMLFile(FDoc, FilePath+'content.xml');
DeleteFile(FilePath+'content.xml'); DeleteFile(FilePath+'content.xml');
ReadAutomaticStyles; StylesNode := FDoc.DocumentElement.FindNode('office:automatic-styles');
ReadNumFormats(StylesNode);
BodyNode := FDoc.DocumentElement.FindNode('office:body'); BodyNode := FDoc.DocumentElement.FindNode('office:body');
if not Assigned(BodyNode) then Exit; if not Assigned(BodyNode) then Exit;
@ -472,30 +484,36 @@ begin
end; end;
end; end;
procedure TsSpreadOpenDocReader.ReadAutomaticStyles; procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
var var
StylesNode, NumFormatNode, node: TDOMNode; NumFormatNode, node: TDOMNode;
decs: Integer; decs: Integer;
fmtName: String; fmtName: String;
grouping: boolean; grouping: boolean;
fmt: String; fmt: String;
nf: TsNumberFormat; nf: TsNumberFormat;
nex: Integer; nex: Integer;
s: String;
begin begin
StylesNode := FDoc.DocumentElement.FindNode('office:automatic-styles'); if not Assigned(AStylesNode) then
if not Assigned(StylesNode) then Exit; exit;
NumFormatNode := StylesNode.FirstChild; NumFormatNode := AStylesNode.FirstChild;
while Assigned(NumFormatNode) do begin while Assigned(NumFormatNode) do begin
if NumFormatNode.NodeName = 'number:number-style' then begin if NumFormatNode.NodeName = 'number:number-style' then begin
fmtName := GetAttrValue(NumFormatNode, 'style:name'); fmtName := GetAttrValue(NumFormatNode, 'style:name');
node := NumFormatNode.FindNode('number:number'); node := NumFormatNode.FindNode('number:number');
if node <> nil then begin if node <> nil then begin
decs := StrToInt(GetAttrValue(node, 'number:decimal-places')); s := GetAttrValue(node, 'number:decimal-places');
grouping := GetAttrValue(node, 'grouping') = 'true'; if s = '' then
nf := IfThen(grouping, nfFixedTh, nfFixed); nf := nfGeneral
else begin
decs := StrToInt(s);
grouping := GetAttrValue(node, 'grouping') = 'true';
nf := IfThen(grouping, nfFixedTh, nfFixed);
end;
fmt := BuildNumberFormatString(nf, Workbook.FormatSettings, decs); fmt := BuildNumberFormatString(nf, Workbook.FormatSettings, decs);
NumFormatList.AddFormat(fmt, nf, decs); NumFormatList.AddFormat(fmtName, fmt, nf, decs);
end; end;
node := NumFormatNode.FindNode('number:scientific-number'); node := NumFormatNode.FindNode('number:scientific-number');
if node <> nil then begin if node <> nil then begin
@ -504,7 +522,7 @@ begin
nex := StrToInt(GetAttrValue(node, 'number:min-exponent-digits')); nex := StrToInt(GetAttrValue(node, 'number:min-exponent-digits'));
fmt := BuildNumberFormatString(nfFixed, Workbook.FormatSettings, decs); fmt := BuildNumberFormatString(nfFixed, Workbook.FormatSettings, decs);
fmt := fmt + 'E+' + DupeString('0', nex); fmt := fmt + 'E+' + DupeString('0', nex);
NumFormatList.AddFormat(fmt, nf, decs); NumFormatList.AddFormat(fmtName, fmt, nf, decs);
end; end;
end else end else
if NumFormatNode.NodeName = 'number:percentage-style' then begin if NumFormatNode.NodeName = 'number:percentage-style' then begin
@ -514,7 +532,7 @@ begin
nf := nfPercentage; nf := nfPercentage;
decs := StrToInt(GetAttrValue(node, 'number:decimal-places')); decs := StrToInt(GetAttrValue(node, 'number:decimal-places'));
fmt := BuildNumberFormatString(nf, Workbook.FormatSettings, decs); fmt := BuildNumberFormatString(nf, Workbook.FormatSettings, decs);
NumFormatList.AddFormat(fmt, nf, decs); NumFormatList.AddFormat(fmtName, fmt, nf, decs);
end; end;
end; end;
NumFormatNode := NumFormatNode.NextSibling; NumFormatNode := NumFormatNode.NextSibling;

View File

@ -568,6 +568,7 @@ type
TsNumFormatData = class TsNumFormatData = class
public public
Index: Integer; Index: Integer;
Name: String;
NumFormat: TsNumberFormat; NumFormat: TsNumberFormat;
Decimals: Byte; Decimals: Byte;
CurrencySymbol: String; CurrencySymbol: String;
@ -590,9 +591,15 @@ type
constructor Create(AWorkbook: TsWorkbook); constructor Create(AWorkbook: TsWorkbook);
destructor Destroy; override; destructor Destroy; override;
function AddFormat(AFormatCell: PCell): Integer; overload; 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; function AddFormat(AFormatIndex: Integer; AFormatString: String;
ANumFormat: TsNumberFormat; ADecimals: Byte = 0; ANumFormat: TsNumberFormat; ADecimals: Byte = 0;
ACurrencySymbol: String = ''): Integer; overload; ACurrencySymbol: String = ''): Integer; overload;
function AddFormat(AFormatName, AFormatString: String;
ANumFormat: TsNumberFormat; ADecimals: Byte = 0;
ACurrencySymbol: String = ''): Integer; overload;
function AddFormat(AFormatString: String; ANumFormat: TsNumberFormat; function AddFormat(AFormatString: String; ANumFormat: TsNumberFormat;
ADecimals: Byte = 0; ACurrencySymbol: String = ''): Integer; overload; ADecimals: Byte = 0; ACurrencySymbol: String = ''): Integer; overload;
procedure AnalyzeAndAdd(AFormatIndex: Integer; AFormatString: String); procedure AnalyzeAndAdd(AFormatIndex: Integer; AFormatString: String);
@ -2952,22 +2959,22 @@ begin
end; end;
{ Adds a new number format data to the list and returns the list index of the { 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; function TsCustomNumFormatList.AddFormat(AFormatIndex: Integer;
AFormatString: String; ANumFormat: TsNumberFormat; ADecimals: byte = 0; AFormatName, AFormatString: String; ANumFormat: TsNumberFormat;
ACurrencySymbol: String = ''): integer; ADecimals: Byte = 0; ACurrencySymbol: String = ''): Integer;
var var
item: TsNumFormatData; item: TsNumFormatData;
begin begin
item := TsNumFormatData.Create; item := TsNumFormatData.Create;
item.Index := AFormatIndex; item.Index := AFormatIndex;
item.Name := AFormatName;
item.NumFormat := ANumFormat; item.NumFormat := ANumFormat;
if AFormatString = '' then begin if AFormatString = '' then begin
if IsDateTimeFormat(ANumFormat) then if IsDateTimeFormat(ANumFormat) then
AFormatString := BuildDateTimeFormatString(ANumFormat, Workbook.FormatSettings, AFormatString := BuildDateTimeFormatString(ANumFormat, Workbook.FormatSettings,
AFormatString) AFormatString)
else else
if item.NumFormat <> nfCustom then
AFormatString := BuildNumberFormatString(ANumFormat, Workbook.FormatSettings, AFormatString := BuildNumberFormatString(ANumFormat, Workbook.FormatSettings,
ADecimals, ACurrencySymbol); ADecimals, ACurrencySymbol);
end; end;
@ -2977,7 +2984,14 @@ begin
Result := inherited Add(item); Result := inherited Add(item);
end; 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; ANumFormat: TsNumberFormat; ADecimals: Byte = 0;
ACurrencySymbol: String = ''): Integer; ACurrencySymbol: String = ''): Integer;
begin begin
@ -2985,11 +2999,18 @@ begin
Result := 0; Result := 0;
exit; exit;
end; end;
Result := AddFormat(FNextFormatIndex, AFormatString, ANumFormat, ADecimals, Result := AddFormat(FNextFormatIndex, '', AFormatString, ANumFormat,
ACurrencySymbol); ADecimals, ACurrencySymbol);
inc(FNextFormatIndex); inc(FNextFormatIndex);
end; 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; function TsCustomNumFormatList.AddFormat(AFormatCell: PCell): Integer;
var var
item: TsNumFormatData; item: TsNumFormatData;