You've already forked lazarus-ccr
fpspreadsheet: ods reader supports number formats in charts.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9023 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -26,12 +26,27 @@ function GetLineStr(ALine: TsChartLine): String;
|
|||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
if ALine.Style = -1 then
|
if ALine.Style = -1 then
|
||||||
s := 'solid'
|
s := 'solid'
|
||||||
else if ALine.Style = -2 then
|
else if ALine.Style = -2 then
|
||||||
s := 'noLine'
|
s := 'noLine'
|
||||||
|
else if ALine.Style = clsFineDot then
|
||||||
|
s := 'fine-dot'
|
||||||
|
else if ALine.Style = clsDot then
|
||||||
|
s := 'dot'
|
||||||
|
else if ALine.Style = clsDash then
|
||||||
|
s := 'dash'
|
||||||
|
else if ALine.Style = clsDashDot then
|
||||||
|
s := 'dash-dot'
|
||||||
|
else if ALine.Style = clsLongDash then
|
||||||
|
s := 'long dash'
|
||||||
|
else if ALine.Style = clsLongDashDot then
|
||||||
|
s := 'long dash-dot'
|
||||||
|
else if ALine.Style = clsLongDashDotDot then
|
||||||
|
s := 'long dash-dot-dot'
|
||||||
else
|
else
|
||||||
s := IntToStr(ALine.Style);
|
s := 'custom #' + IntToStr(ALine.Style);
|
||||||
|
|
||||||
Result := Format('Style=%s, Width=%.0fmm, Color=%.6x, Transparency=%.2f', [
|
Result := Format('Style=%s, Width=%.0fmm, Color=%.6x, Transparency=%.2f', [
|
||||||
s, ALine.Width, ALine.Color, ALine.Transparency
|
s, ALine.Width, ALine.Color, ALine.Transparency
|
||||||
@ -42,6 +57,8 @@ function GetRangeStr(ARange: TsChartRange): String;
|
|||||||
begin
|
begin
|
||||||
with ARange do
|
with ARange do
|
||||||
Result := GetCellRangeString(Sheet1, Sheet2, Row1, Col1, Row2, Col2, rfAllRel, false);
|
Result := GetCellRangeString(Sheet1, Sheet2, Row1, Col1, Row2, Col2, rfAllRel, false);
|
||||||
|
if Result = '' then
|
||||||
|
Result := '(none)';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetCellAddrStr(ACellAddr: TsChartCellAddr): String;
|
function GetCellAddrStr(ACellAddr: TsChartCellAddr): String;
|
||||||
@ -144,6 +161,7 @@ begin
|
|||||||
WriteLn(' CATEGORIES ', GetRangeStr(chart.XAxis.CategoryRange));
|
WriteLn(' CATEGORIES ', GetRangeStr(chart.XAxis.CategoryRange));
|
||||||
WriteLn(' RANGE AutomaticMin=', chart.XAxis.AutomaticMin, ', Minimum=', chart.XAxis.Min:0:3);
|
WriteLn(' RANGE AutomaticMin=', chart.XAxis.AutomaticMin, ', Minimum=', chart.XAxis.Min:0:3);
|
||||||
WriteLn(' AutomaticMax=', chart.XAxis.AutomaticMax, ', Maximum=', chart.XAxis.Max:0:3);
|
WriteLn(' AutomaticMax=', chart.XAxis.AutomaticMax, ', Maximum=', chart.XAxis.Max:0:3);
|
||||||
|
WriteLn(' LABELS Format="', chart.XAxis.LabelFormat, '"');
|
||||||
WriteLn(' POSITION ', GetEnumName(TypeInfo(TsChartAxisPosition), ord(chart.XAXis.Position)),
|
WriteLn(' POSITION ', GetEnumName(TypeInfo(TsChartAxisPosition), ord(chart.XAXis.Position)),
|
||||||
', Value=', chart.XAxis.PositionValue:0:3);
|
', Value=', chart.XAxis.PositionValue:0:3);
|
||||||
WriteLn(' AXIS TICKS: Major interval=', chart.XAxis.MajorInterval:0:2,
|
WriteLn(' AXIS TICKS: Major interval=', chart.XAxis.MajorInterval:0:2,
|
||||||
@ -161,6 +179,7 @@ begin
|
|||||||
WriteLn(' Font: ', GetFontStr(chart.YAxis.Title.Font));
|
WriteLn(' Font: ', GetFontStr(chart.YAxis.Title.Font));
|
||||||
WriteLn(' RANGE AutomaticMin=', chart.YAxis.AutomaticMin, ', Minimum=', chart.YAxis.Min:0:3);
|
WriteLn(' RANGE AutomaticMin=', chart.YAxis.AutomaticMin, ', Minimum=', chart.YAxis.Min:0:3);
|
||||||
WriteLn(' AutomaticMax=', chart.YAxis.AutomaticMax, ', Maximum=', chart.YAxis.Max:0:3);
|
WriteLn(' AutomaticMax=', chart.YAxis.AutomaticMax, ', Maximum=', chart.YAxis.Max:0:3);
|
||||||
|
WriteLn(' LABELS Format="', chart.YAxis.LabelFormat, '", FormatPercent="', chart.YAxis.LabelFormatPercent,'"');
|
||||||
WriteLn(' POSITION ', GetEnumName(TypeInfo(TsChartAxisPosition), ord(chart.YAXis.Position)),
|
WriteLn(' POSITION ', GetEnumName(TypeInfo(TsChartAxisPosition), ord(chart.YAXis.Position)),
|
||||||
', Value:', chart.YAxis.PositionValue:0:3);
|
', Value:', chart.YAxis.PositionValue:0:3);
|
||||||
WriteLn(' AXIS TICKS Major interval=', chart.YAxis.MajorInterval:0:2,
|
WriteLn(' AXIS TICKS Major interval=', chart.YAxis.MajorInterval:0:2,
|
||||||
@ -177,7 +196,7 @@ begin
|
|||||||
WriteLn;
|
WriteLn;
|
||||||
WriteLn( ' SERIES #', j, ': ', series.ClassName);
|
WriteLn( ' SERIES #', j, ': ', series.ClassName);
|
||||||
WriteLn( ' TITLE: ', GetCellAddrStr(series.TitleAddr));
|
WriteLn( ' TITLE: ', GetCellAddrStr(series.TitleAddr));
|
||||||
WriteLn( ' LABEL RANGE: ', GetRangeStr(series.LabelRange));
|
WriteLn( ' LABEL RANGE: ', GetRangeStr(series.LabelRange), ', Format="', series.LabelFormat, '"');
|
||||||
if (series is TsScatterSeries) or (series is TsBubbleSeries) then
|
if (series is TsScatterSeries) or (series is TsBubbleSeries) then
|
||||||
WriteLn(' X RANGE: ', GetRangeStr(series.XRange));
|
WriteLn(' X RANGE: ', GetRangeStr(series.XRange));
|
||||||
WriteLn( ' Y RANGE: ', GetRangeStr(series.YRange));
|
WriteLn( ' Y RANGE: ', GetRangeStr(series.YRange));
|
||||||
@ -222,7 +241,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
with regression.Equation do
|
with regression.Equation do
|
||||||
begin
|
begin
|
||||||
WriteLn(' REGR. EQUATION: XName="', XName,'", YName="', YName,'" ');
|
WriteLn(' REGR. EQUATION: XName="', XName,'", YName="', YName,'", Number format="', NumberFormat, '"');
|
||||||
WriteLn(' FONT: ', GetFontStr(regression.Equation.Font));
|
WriteLn(' FONT: ', GetFontStr(regression.Equation.Font));
|
||||||
WriteLn(' FILL: ', GetFillStr(regression.Equation.Fill));
|
WriteLn(' FILL: ', GetFillStr(regression.Equation.Fill));
|
||||||
WriteLn(' BORDER: ', GetLineStr(regression.Equation.Border));
|
WriteLn(' BORDER: ', GetLineStr(regression.Equation.Border));
|
||||||
|
@ -190,7 +190,6 @@ type
|
|||||||
function NeedsPassword(AStream: TStream): Boolean; override;
|
function NeedsPassword(AStream: TStream): Boolean; override;
|
||||||
procedure ReadAutomaticStyles(AStylesNode: TDOMNode);
|
procedure ReadAutomaticStyles(AStylesNode: TDOMNode);
|
||||||
procedure ReadMasterStyles(AStylesNode: TDOMNode);
|
procedure ReadMasterStyles(AStylesNode: TDOMNode);
|
||||||
procedure ReadNumFormats(AStylesNode: TDOMNode);
|
|
||||||
procedure ReadPageLayout(AStylesNode: TDOMNode; ATableStyleName: String;
|
procedure ReadPageLayout(AStylesNode: TDOMNode; ATableStyleName: String;
|
||||||
APageLayout: TsPageLayout);
|
APageLayout: TsPageLayout);
|
||||||
procedure ReadSettings(AOfficeSettingsNode: TDOMNode);
|
procedure ReadSettings(AOfficeSettingsNode: TDOMNode);
|
||||||
@ -232,6 +231,7 @@ type
|
|||||||
{ Helper methods, public because needed by the chart reader }
|
{ Helper methods, public because needed by the chart reader }
|
||||||
function CreateXMLStream: TStream;
|
function CreateXMLStream: TStream;
|
||||||
procedure ReadFont(ANode: TDOMNode; AFont: TsFont);
|
procedure ReadFont(ANode: TDOMNode; AFont: TsFont);
|
||||||
|
procedure ReadNumFormats(AStylesNode: TDOMNode; ANumFormatList: TStrings);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TsSpreadOpenDocWriter }
|
{ TsSpreadOpenDocWriter }
|
||||||
@ -3046,7 +3046,7 @@ begin
|
|||||||
ReadFontFaces(Doc.DocumentElement.FindNode('office:font-face-decls'));
|
ReadFontFaces(Doc.DocumentElement.FindNode('office:font-face-decls'));
|
||||||
|
|
||||||
StylesNode := Doc.DocumentElement.FindNode('office:styles');
|
StylesNode := Doc.DocumentElement.FindNode('office:styles');
|
||||||
ReadNumFormats(StylesNode);
|
ReadNumFormats(StylesNode, NumFormatList);
|
||||||
ReadStyles(StylesNode);
|
ReadStyles(StylesNode);
|
||||||
ReadAutomaticStyles(Doc.DocumentElement.FindNode('office:automatic-styles'));
|
ReadAutomaticStyles(Doc.DocumentElement.FindNode('office:automatic-styles'));
|
||||||
ReadMasterStyles(Doc.DocumentElement.FindNode('office:master-styles'));
|
ReadMasterStyles(Doc.DocumentElement.FindNode('office:master-styles'));
|
||||||
@ -3067,7 +3067,7 @@ begin
|
|||||||
if Assigned(Doc) then begin
|
if Assigned(Doc) then begin
|
||||||
ReadFontFaces(Doc.DocumentElement.FindNode('office:font-face-decls'));
|
ReadFontFaces(Doc.DocumentElement.FindNode('office:font-face-decls'));
|
||||||
StylesNode := Doc.DocumentElement.FindNode('office:automatic-styles');
|
StylesNode := Doc.DocumentElement.FindNode('office:automatic-styles');
|
||||||
ReadNumFormats(StylesNode);
|
ReadNumFormats(StylesNode, NumFormatList);
|
||||||
ReadStyles(StylesNode);
|
ReadStyles(StylesNode);
|
||||||
|
|
||||||
BodyNode := Doc.DocumentElement.FindNode('office:body');
|
BodyNode := Doc.DocumentElement.FindNode('office:body');
|
||||||
@ -3450,7 +3450,8 @@ begin
|
|||||||
(Workbook as TsWorkbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
(Workbook as TsWorkbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
|
procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode;
|
||||||
|
ANumFormatList: TStrings);
|
||||||
|
|
||||||
procedure ReadStyleMap(ANode: TDOMNode; var ANumFormat: TsNumberFormat;
|
procedure ReadStyleMap(ANode: TDOMNode; var ANumFormat: TsNumberFormat;
|
||||||
var AFormatStr: String);
|
var AFormatStr: String);
|
||||||
@ -3502,7 +3503,7 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
|
|||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
fmt := NumFormatList[styleIndex];
|
fmt := ANumFormatList[styleIndex];
|
||||||
fmt := Copy(fmt, pos(':', fmt)+1, Length(fmt));
|
fmt := Copy(fmt, pos(':', fmt)+1, Length(fmt));
|
||||||
parser := TsNumFormatParser.Create(fmt, Workbook.FormatSettings);
|
parser := TsNumFormatParser.Create(fmt, Workbook.FormatSettings);
|
||||||
try
|
try
|
||||||
@ -3682,7 +3683,7 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
|
|||||||
if (ANumFormatNode.NodeName = 'number:currency-style') then
|
if (ANumFormatNode.NodeName = 'number:currency-style') then
|
||||||
nf := IfThen(hasColor, nfCurrencyRed, nfCurrency);
|
nf := IfThen(hasColor, nfCurrencyRed, nfCurrency);
|
||||||
|
|
||||||
NumFormatList.Add(Format('%s:%s', [ANumFormatName, nfs]));
|
ANumFormatList.Add(Format('%s:%s', [ANumFormatName, nfs]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ReadDateTimeStyle(ANumFormatNode: TDOMNode; ANumFormatName: String);
|
procedure ReadDateTimeStyle(ANumFormatNode: TDOMNode; ANumFormatName: String);
|
||||||
@ -3786,8 +3787,8 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
|
|||||||
if node <> nil then
|
if node <> nil then
|
||||||
ReadStyleMap(node, nf, nfs);
|
ReadStyleMap(node, nf, nfs);
|
||||||
|
|
||||||
NumFormatList.Add(ANumFormatName + ':' + nfs);
|
ANumFormatList.Add(ANumFormatName + ':' + nfs);
|
||||||
// NumFormatList.AddFormat(ANumFormatName, nf, nfs);
|
// ANumFormatList.AddFormat(ANumFormatName, nf, nfs);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ReadTextStyle(ANumFormatNode: TDOMNode; ANumFormatName: String);
|
procedure ReadTextStyle(ANumFormatNode: TDOMNode; ANumFormatName: String);
|
||||||
@ -3825,9 +3826,9 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
|
|||||||
ReadStyleMap(node, nf, nfs);
|
ReadStyleMap(node, nf, nfs);
|
||||||
nf := nfCustom;
|
nf := nfCustom;
|
||||||
|
|
||||||
NumFormatList.Add(Format('%s:%s', [ANumFormatName, nfs]));
|
ANumFormatList.Add(Format('%s:%s', [ANumFormatName, nfs]));
|
||||||
|
|
||||||
//NumFormatList.AddFormat(ANumFormatName, nf, nfs);
|
//ANumFormatList.AddFormat(ANumFormatName, nf, nfs);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
@ -22,6 +22,7 @@ type
|
|||||||
private
|
private
|
||||||
FChartFiles: TStrings;
|
FChartFiles: TStrings;
|
||||||
FPointSeparatorSettings: TFormatSettings;
|
FPointSeparatorSettings: TFormatSettings;
|
||||||
|
FNumberFormatList: TStrings;
|
||||||
function FindStyleNode(AStyleNodes: TDOMNode; AStyleName: String): TDOMNode;
|
function FindStyleNode(AStyleNodes: TDOMNode; AStyleName: String): TDOMNode;
|
||||||
procedure GetChartFillProps(ANode: TDOMNode; AChart: TsChart; AFill: TsChartFill);
|
procedure GetChartFillProps(ANode: TDOMNode; AChart: TsChart; AFill: TsChartFill);
|
||||||
procedure GetChartLineProps(ANode: TDOMNode; AChart: TsChart; ALine: TsChartLine);
|
procedure GetChartLineProps(ANode: TDOMNode; AChart: TsChart; ALine: TsChartLine);
|
||||||
@ -261,6 +262,7 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
function Add(const ANumFormat: String): Integer; override;
|
function Add(const ANumFormat: String): Integer; override;
|
||||||
|
function FindFormatByName(const AName: String): String;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TsChartNumberFormatList.Create;
|
constructor TsChartNumberFormatList.Create;
|
||||||
@ -282,6 +284,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ The reader adds formats in the form "name:format" where "name" is the
|
||||||
|
identifier used in the style definition, e.g. "N0". }
|
||||||
|
function TsChartNumberFormatList.FindFormatByName(const AName: String): String;
|
||||||
|
var
|
||||||
|
idx: Integer;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
idx := IndexOfName(AName);
|
||||||
|
if idx <> -1 then
|
||||||
|
begin
|
||||||
|
Result := Values[AName];
|
||||||
|
if Result = 'General' then
|
||||||
|
Result := '';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
{ TsSpreadOpenDocChartReader }
|
{ TsSpreadOpenDocChartReader }
|
||||||
@ -295,10 +313,13 @@ begin
|
|||||||
FPointSeparatorSettings.DecimalSeparator:='.';
|
FPointSeparatorSettings.DecimalSeparator:='.';
|
||||||
|
|
||||||
FChartFiles := TStringList.Create;
|
FChartFiles := TStringList.Create;
|
||||||
|
FNumberFormatList := TsChartNumberFormatList.Create;
|
||||||
|
FNumberFormatList.NameValueSeparator := ':';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TsSpreadOpenDocChartReader.Destroy;
|
destructor TsSpreadOpenDocChartReader.Destroy;
|
||||||
begin
|
begin
|
||||||
|
FNumberFormatList.Free;
|
||||||
FChartFiles.Free;
|
FChartFiles.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
@ -446,6 +467,10 @@ var
|
|||||||
chartChartNode: TDOMNode;
|
chartChartNode: TDOMNode;
|
||||||
chartElementNode: TDOMNode;
|
chartElementNode: TDOMNode;
|
||||||
begin
|
begin
|
||||||
|
nodeName := AStyleNode.NodeName;
|
||||||
|
if nodeName = 'office:automatic-styles' then
|
||||||
|
TsSpreadOpenDocReader(Reader).ReadNumFormats(AStyleNode, FNumberFormatList);
|
||||||
|
|
||||||
nodeName := AChartNode.NodeName;
|
nodeName := AChartNode.NodeName;
|
||||||
officeChartNode := AChartNode.FirstChild;
|
officeChartNode := AChartNode.FirstChild;
|
||||||
while officeChartNode <> nil do
|
while officeChartNode <> nil do
|
||||||
@ -544,6 +569,15 @@ var
|
|||||||
n: Integer;
|
n: Integer;
|
||||||
ticks: TsChartAxisTicks = [];
|
ticks: TsChartAxisTicks = [];
|
||||||
begin
|
begin
|
||||||
|
nodeName := AStyleNode.NodeName;
|
||||||
|
s := GetAttrValue(AStyleNode, 'style:data-style-name');
|
||||||
|
if s <> '' then
|
||||||
|
s := TsChartNumberFormatList(FNumberFormatList).FindFormatByName(s);
|
||||||
|
if (AChart.StackMode = csmStackedPercentage) and ((Axis = AChart.YAxis) or (Axis = AChart.Y2Axis)) then
|
||||||
|
Axis.LabelFormatPercent := s
|
||||||
|
else
|
||||||
|
Axis.LabelFormat := s;
|
||||||
|
|
||||||
AStyleNode := AStyleNode.FirstChild;
|
AStyleNode := AStyleNode.FirstChild;
|
||||||
while AStyleNode <> nil do
|
while AStyleNode <> nil do
|
||||||
begin
|
begin
|
||||||
@ -899,7 +933,11 @@ begin
|
|||||||
series := TsScatterSeries(ASeries);
|
series := TsScatterSeries(ASeries);
|
||||||
odsReader := TsSpreadOpenDocReader(Reader);
|
odsReader := TsSpreadOpenDocReader(Reader);
|
||||||
|
|
||||||
// here: read number format! (still missing...)
|
nodeName := AStyleNode.NodeName;
|
||||||
|
s := GetAttrValue(AStyleNode, 'style:data-style-name');
|
||||||
|
if s <> '' then
|
||||||
|
s := TsChartNumberFormatList(FNumberFormatList).FindFormatByName(s);
|
||||||
|
series.Regression.Equation.NumberFormat := s;
|
||||||
|
|
||||||
AStyleNode := AStyleNode.FirstChild;
|
AStyleNode := AStyleNode.FirstChild;
|
||||||
while Assigned(AStyleNode) do
|
while Assigned(AStyleNode) do
|
||||||
@ -1108,6 +1146,11 @@ var
|
|||||||
rel: Boolean;
|
rel: Boolean;
|
||||||
begin
|
begin
|
||||||
nodeName := AStyleNode.NodeName;
|
nodeName := AStyleNode.NodeName;
|
||||||
|
s := GetAttrValue(AStyleNode, 'style:data-style-name');
|
||||||
|
if s <> '' then
|
||||||
|
s := TsChartNumberFormatList(FNumberFormatList).FindFormatByName(s);
|
||||||
|
ASeries.LabelFormat := s;
|
||||||
|
|
||||||
AStyleNode := AStyleNode.FirstChild;
|
AStyleNode := AStyleNode.FirstChild;
|
||||||
while AStyleNode <> nil do begin
|
while AStyleNode <> nil do begin
|
||||||
nodeName := AStyleNode.NodeName;
|
nodeName := AStyleNode.NodeName;
|
||||||
|
Reference in New Issue
Block a user