You've already forked lazarus-ccr
fpspreadsheet: Style support in Excel2003-xml reader.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7031 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -18,6 +18,9 @@
|
|||||||
<Version Value="2"/>
|
<Version Value="2"/>
|
||||||
</PublishOptions>
|
</PublishOptions>
|
||||||
<RunParams>
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
|
||||||
|
</local>
|
||||||
<FormatVersion Value="2"/>
|
<FormatVersion Value="2"/>
|
||||||
<Modes Count="1">
|
<Modes Count="1">
|
||||||
<Mode0 Name="default">
|
<Mode0 Name="default">
|
||||||
|
@@ -23,7 +23,7 @@ var
|
|||||||
begin
|
begin
|
||||||
// Open the input file
|
// Open the input file
|
||||||
dir := ExtractFilePath(ParamStr(0));
|
dir := ExtractFilePath(ParamStr(0));
|
||||||
inputFileName := dir + 'test.xml';
|
// inputFileName := dir + 'test.xml';
|
||||||
inputFileName := dir + 'datatypes.xml';
|
inputFileName := dir + 'datatypes.xml';
|
||||||
|
|
||||||
if not FileExists(inputFileName) then begin
|
if not FileExists(inputFileName) then begin
|
||||||
|
@@ -31,21 +31,35 @@ type
|
|||||||
private
|
private
|
||||||
FPointSeparatorSettings: TFormatSettings;
|
FPointSeparatorSettings: TFormatSettings;
|
||||||
function ExtractDateTime(AText: String): TDateTime;
|
function ExtractDateTime(AText: String): TDateTime;
|
||||||
|
procedure ReadAlignment(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||||
|
procedure ReadBorder(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||||
|
procedure ReadBorders(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||||
|
procedure ReadCellProtection(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||||
|
procedure ReadFont(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||||
|
procedure ReadInterior(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||||
|
procedure ReadNumberFormat(ANode: TDOMNode; var AFormat: TsCellFormat);
|
||||||
|
|
||||||
|
protected
|
||||||
|
FFirstNumFormatIndexInFile: Integer;
|
||||||
|
procedure AddBuiltinNumFormats; override;
|
||||||
|
|
||||||
|
protected
|
||||||
procedure ReadCell(ANode: TDOMNode; AWorksheet: TsBasicWorksheet; ARow, ACol: Integer);
|
procedure ReadCell(ANode: TDOMNode; AWorksheet: TsBasicWorksheet; ARow, ACol: Integer);
|
||||||
procedure ReadRow(ANode: TDOMNode; AWorksheet: TsBasicWorksheet; ARow: Integer);
|
procedure ReadRow(ANode: TDOMNode; AWorksheet: TsBasicWorksheet; ARow: Integer);
|
||||||
|
procedure ReadStyle(ANode: TDOMNode);
|
||||||
|
procedure ReadStyles(ANode: TDOMNode);
|
||||||
procedure ReadTable(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
procedure ReadTable(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||||
procedure ReadWorksheet(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
procedure ReadWorksheet(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||||
procedure ReadWorksheetOptions(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
procedure ReadWorksheetOptions(ANode: TDOMNode; AWorksheet: TsBasicWorksheet);
|
||||||
procedure ReadWorksheets(ANode: TDOMNode);
|
procedure ReadWorksheets(ANode: TDOMNode);
|
||||||
protected
|
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
procedure ReadFromStream(AStream: TStream; APassword: String = '';
|
procedure ReadFromStream(AStream: TStream; APassword: String = '';
|
||||||
AParams: TsStreamParams = []); override;
|
AParams: TsStreamParams = []); override;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TsSpreadExcelXMLWriter }
|
{ TsSpreadExcelXMLWriter }
|
||||||
|
|
||||||
TsSpreadExcelXMLWriter = class(TsCustomSpreadWriter)
|
TsSpreadExcelXMLWriter = class(TsCustomSpreadWriter)
|
||||||
@@ -109,7 +123,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
StrUtils, DateUtils, Math,
|
StrUtils, DateUtils, Math,
|
||||||
fpsStrings, fpspreadsheet, fpsUtils, fpsNumFormat, fpsHTMLUtils;
|
fpsStrings, fpsClasses, fpspreadsheet, fpsUtils, fpsNumFormat, fpsHTMLUtils;
|
||||||
|
|
||||||
const
|
const
|
||||||
FMT_OFFSET = 61;
|
FMT_OFFSET = 61;
|
||||||
@@ -184,27 +198,201 @@ constructor TsSpreadExcelXMLReader.Create(AWorkbook: TsBasicWorkbook);
|
|||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
|
|
||||||
|
// Cell formats (named "Styles" here).
|
||||||
|
FCellFormatList := TsCellFormatList.Create(true); // is destroyed by ancestor
|
||||||
|
|
||||||
// Special version of FormatSettings using a point decimal separator for sure.
|
// Special version of FormatSettings using a point decimal separator for sure.
|
||||||
FPointSeparatorSettings := DefaultFormatSettings;
|
FPointSeparatorSettings := DefaultFormatSettings;
|
||||||
FPointSeparatorSettings.DecimalSeparator := '.';
|
FPointSeparatorSettings.DecimalSeparator := '.';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadExcelXMLReader.AddBuiltinNumFormats;
|
||||||
|
begin
|
||||||
|
FFirstNumFormatIndexInFile := 164;
|
||||||
|
AddBuiltInBiffFormats(
|
||||||
|
FNumFormatList, FWorkbook.FormatSettings, FFirstNumFormatIndexInFile-1
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Extracts the date/time value from the given string.
|
Extracts the date/time value from the given string.
|
||||||
The string is formatted as 'yyyy-mm-dd"T"hh:nn:ss.zzz'
|
The string is formatted as 'yyyy-mm-dd"T"hh:nn:ss.zzz'
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsSpreadExcelXMLReader.ExtractDateTime(AText: String): TDateTime;
|
function TsSpreadExcelXMLReader.ExtractDateTime(AText: String): TDateTime;
|
||||||
//var
|
|
||||||
// syr, smon, sday, shr, smin, ssec, smsec: String;
|
|
||||||
const
|
|
||||||
PATTERN = 'yyyy-mm-ddTdd:nn:ss.zzz';
|
|
||||||
var
|
var
|
||||||
dateStr, timeStr: String;
|
dateStr, timeStr: String;
|
||||||
begin
|
begin
|
||||||
dateStr := Copy(AText, 1, 10);
|
dateStr := Copy(AText, 1, 10);
|
||||||
timeStr := Copy(AText, 12, MaxInt);
|
timeStr := Copy(AText, 12, MaxInt);
|
||||||
Result := ScanDateTime('yyyy-mm-dd', dateStr) + ScanDateTime('hh:nn:ss.zzz', timeStr);
|
Result := ScanDateTime('yyyy-mm-dd', dateStr) + ScanDateTime('hh:nn:ss.zzz', timeStr);
|
||||||
//Result := ScanDateTime(PATTERN, AText);
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads the cell alignment from the given node attributes
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLReader.ReadAlignment(ANode: TDOMNode;
|
||||||
|
var AFormat: TsCellFormat);
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
// Vertical alignment
|
||||||
|
s := GetAttrValue(ANode, 'ss:Vertical');
|
||||||
|
if s <> '' then
|
||||||
|
with AFormat do begin
|
||||||
|
Include(UsedFormattingFields, uffVertAlign);
|
||||||
|
case s of
|
||||||
|
'Top':
|
||||||
|
VertAlignment := vaTop;
|
||||||
|
'Center':
|
||||||
|
VertAlignment := vaCenter;
|
||||||
|
'Bottom':
|
||||||
|
VertAlignment := vaBottom;
|
||||||
|
else
|
||||||
|
Exclude(UsedFormattingFields, uffVertAlign);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Horizontal alignment
|
||||||
|
s := GetAttrValue(ANode, 'ss:Horizontal');
|
||||||
|
if s <> '' then
|
||||||
|
with AFormat do begin
|
||||||
|
Include(UsedFormattingFields, uffHorAlign);
|
||||||
|
case s of
|
||||||
|
'Left':
|
||||||
|
HorAlignment := haLeft;
|
||||||
|
'Center':
|
||||||
|
HorAlignment := haCenter;
|
||||||
|
'Right':
|
||||||
|
HorAlignment := haRight;
|
||||||
|
else
|
||||||
|
Exclude(UsedFormattingFields, uffHorAlign);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Vertical text
|
||||||
|
s := GetAttrValue(ANode, 'ss:Rotate');
|
||||||
|
if s = '90' then
|
||||||
|
with AFormat do begin
|
||||||
|
TextRotation := rt90DegreeCounterClockwiseRotation;
|
||||||
|
Include(UsedFormattingFields, uffTextRotation);
|
||||||
|
end
|
||||||
|
else if s = '-90' then
|
||||||
|
with AFormat do begin
|
||||||
|
TextRotation := rt90DegreeClockwiseRotation;
|
||||||
|
Include(UsedFormattingFields, uffTextRotation);
|
||||||
|
end;
|
||||||
|
s := GetAttrValue(ANode, 'ss:VerticalText');
|
||||||
|
if s <> '' then
|
||||||
|
with AFormat do begin
|
||||||
|
TextRotation := rtStacked;
|
||||||
|
Include(UsedFormattingFields, uffTextRotation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Word wrap
|
||||||
|
s := GetAttrValue(ANode, 'ss:WrapText');
|
||||||
|
if s = '1' then
|
||||||
|
with AFormat do
|
||||||
|
Include(UsedFormattingFields, uffWordWrap);
|
||||||
|
|
||||||
|
// BiDi
|
||||||
|
s := GetAttrValue(ANode, 'ss:ReadingOrder');
|
||||||
|
if s <> '' then
|
||||||
|
with AFormat do begin
|
||||||
|
case s of
|
||||||
|
'RightToLeft': BiDiMode := bdRTL;
|
||||||
|
'LeftToRight': BiDiMode := bdLTR;
|
||||||
|
end;
|
||||||
|
Include(UsedFormattingFields, uffBiDi);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Read a "Style/Borders/Border" node
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLReader.ReadBorder(ANode: TDOMNode;
|
||||||
|
var AFormat: TsCellFormat);
|
||||||
|
// <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="3" ss:Color="#ED7D31"/>
|
||||||
|
var
|
||||||
|
s, sw: String;
|
||||||
|
b: TsCellBorder;
|
||||||
|
begin
|
||||||
|
AFormat.UsedFormattingFields := AFormat.UsedFormattingFields + [uffBorder];
|
||||||
|
|
||||||
|
// Border position
|
||||||
|
s := GetAttrValue(ANode, 'ss:Position');
|
||||||
|
case s of
|
||||||
|
'Left':
|
||||||
|
b := cbWest;
|
||||||
|
'Right':
|
||||||
|
b := cbEast;
|
||||||
|
'Top':
|
||||||
|
b := cbNorth;
|
||||||
|
'Bottom':
|
||||||
|
b := cbSouth;
|
||||||
|
'DiagonalRight':
|
||||||
|
b := cbDiagUp;
|
||||||
|
'DiagonalLeft':
|
||||||
|
b := cbDiagDown;
|
||||||
|
end;
|
||||||
|
Include(AFormat.Border, b);
|
||||||
|
|
||||||
|
// Border color
|
||||||
|
s := GetAttrValue(ANode, 'ss:Color');
|
||||||
|
AFormat.BorderStyles[b].Color := HTMLColorStrToColor(s);
|
||||||
|
|
||||||
|
// Line style
|
||||||
|
s := GetAttrValue(ANode, 'ss:LineStyle');
|
||||||
|
sw := GetAttrValue(ANode, 'ss:Weight');
|
||||||
|
case s of
|
||||||
|
'Continuous':
|
||||||
|
if sw = '1' then
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsThin
|
||||||
|
else if sw = '2' then
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsMedium
|
||||||
|
else if sw = '3' then
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsThick
|
||||||
|
else if sw = '' then
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsHair;
|
||||||
|
'Double':
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsDouble;
|
||||||
|
'Dot':
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsDotted;
|
||||||
|
'Dash':
|
||||||
|
if sw = '2' then
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsMediumDash
|
||||||
|
else
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsDashed;
|
||||||
|
'DashDot':
|
||||||
|
if sw = '2' then
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsMediumDashDot
|
||||||
|
else
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsDashDot;
|
||||||
|
'DashDotDot':
|
||||||
|
if sw = '2' then
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsMediumDashDotDot
|
||||||
|
else
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsDashDotDot;
|
||||||
|
'SlantDashDot':
|
||||||
|
AFormat.BorderStyles[b].LineStyle := lsSlantDashDot;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads the "Styles/Style/Borders" nodes
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLReader.ReadBorders(ANode: TDOMNode;
|
||||||
|
var AFormat: TsCellFormat);
|
||||||
|
var
|
||||||
|
nodeName: String;
|
||||||
|
begin
|
||||||
|
if ANode = nil then exit;
|
||||||
|
ANode := ANode.FirstChild;
|
||||||
|
while ANode <> nil do begin
|
||||||
|
nodeName := ANode.NodeName;
|
||||||
|
if nodeName = 'Border' then
|
||||||
|
ReadBorder(ANode, AFormat);
|
||||||
|
ANode := ANode.NextSibling;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@@ -215,20 +403,30 @@ procedure TsSpreadExcelXMLReader.ReadCell(ANode: TDOMNode;
|
|||||||
var
|
var
|
||||||
sheet: TsWorksheet absolute AWorksheet;
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
nodeName: string;
|
nodeName: string;
|
||||||
st: String;
|
s, st, sv: String;
|
||||||
sv: String;
|
|
||||||
node: TDOMNode;
|
node: TDOMNode;
|
||||||
err: TsErrorValue;
|
err: TsErrorValue;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
|
fmt: TsCellFormat;
|
||||||
|
idx: Integer;
|
||||||
begin
|
begin
|
||||||
if ANode = nil then
|
if ANode = nil then
|
||||||
exit;
|
exit;
|
||||||
nodeName := ANode.NodeName;
|
nodeName := ANode.NodeName;
|
||||||
if nodeName <> 'Cell' then
|
if nodeName <> 'Cell' then
|
||||||
raise Exception.Create('Only Cell nodes expected.');
|
raise Exception.Create('[ReadCell] Only "Cell" nodes expected.');
|
||||||
|
|
||||||
cell := sheet.GetCell(ARow, ACol);
|
cell := sheet.GetCell(ARow, ACol);
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'ss:StyleID');
|
||||||
|
if s <> '' then begin
|
||||||
|
idx := FCellFormatList.FindIndexOfName(s);
|
||||||
|
if idx <> -1 then begin
|
||||||
|
fmt := FCellFormatList.Items[idx]^;
|
||||||
|
cell^.FormatIndex := TsWorkbook(FWorkbook).AddCellFormat(fmt);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
node := ANode.FirstChild;
|
node := ANode.FirstChild;
|
||||||
if node = nil then
|
if node = nil then
|
||||||
sheet.WriteBlank(cell)
|
sheet.WriteBlank(cell)
|
||||||
@@ -259,6 +457,158 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads the "Styles/Style/Protection" node
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLReader.ReadCellProtection(ANode: TDOMNode;
|
||||||
|
var AFormat: TsCellFormat);
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
if ANode = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'ss:Protected');
|
||||||
|
if s = '0' then
|
||||||
|
Exclude(AFormat.Protection, cpLockCell);
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'x:HideFormula');
|
||||||
|
if s = '1' then
|
||||||
|
Include(AFormat.Protection, cpHideFormulas);
|
||||||
|
|
||||||
|
if AFormat.Protection <> DEFAULT_CELL_PROTECTION then
|
||||||
|
Include(AFormat.UsedFormattingFields, uffProtection);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads the "Styles/Style/Font" node
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLreader.ReadFont(ANode: TDOMNode;
|
||||||
|
var AFormat: TsCellFormat);
|
||||||
|
var
|
||||||
|
book: TsWorkbook;
|
||||||
|
fname: String;
|
||||||
|
fsize: Single;
|
||||||
|
fcolor: TsColor;
|
||||||
|
fstyle: TsFontStyles;
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
if ANode = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
book := TsWorkbook(FWorkbook);
|
||||||
|
|
||||||
|
fname := GetAttrValue(ANode, 'ss:FontName');
|
||||||
|
if fname = '' then
|
||||||
|
fname := book.GetDefaultFont.FontName;
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'ss:Size');
|
||||||
|
if (s = '') or not TryStrToFloat(s, fsize, FPointSeparatorSettings) then
|
||||||
|
fsize := book.GetDefaultFont.Size;
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'ss:Color');
|
||||||
|
if s <> '' then
|
||||||
|
fcolor := HTMLColorStrToColor(s)
|
||||||
|
else
|
||||||
|
fcolor := book.GetDefaultFont.Color;
|
||||||
|
|
||||||
|
fstyle := [];
|
||||||
|
s := GetAttrValue(ANode, 'ss:Bold');
|
||||||
|
if s = '1' then
|
||||||
|
Include(fstyle, fssBold);
|
||||||
|
s := GetAttrValue(ANode, 'ss:Italic');
|
||||||
|
if s = '1' then
|
||||||
|
Include(fstyle, fssItalic);
|
||||||
|
s := GetAttrValue(ANode, 'ss:UnderLine');
|
||||||
|
if s <> '' then
|
||||||
|
Include(fstyle, fssUnderline);
|
||||||
|
s := GetAttrValue(ANode, 'ss:StrikeThrough');
|
||||||
|
if s = '1' then
|
||||||
|
Include(fstyle, fssStrikeout);
|
||||||
|
|
||||||
|
AFormat.FontIndex := book.AddFont(fname, fsize, fstyle, fcolor);
|
||||||
|
Include(AFormat.UsedFormattingFields, uffFont);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads the "Styles/Style/Interior" node
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLReader.ReadInterior(ANode: TDOMNode;
|
||||||
|
var AFormat: TsCellFormat);
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
fs: TsFillStyle;
|
||||||
|
begin
|
||||||
|
if ANode = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'ss:Pattern');
|
||||||
|
if s = '' then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
for fs in TsFillStyle do
|
||||||
|
if FILL_NAMES[fs] = s then begin
|
||||||
|
AFormat.Background.Style := fs;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'ss:PatternColor');
|
||||||
|
if s = '' then
|
||||||
|
AFormat.Background.FgColor := scBlack
|
||||||
|
else
|
||||||
|
AFormat.Background.FgColor := HTMLColorStrToColor(s);
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'ss:Color');
|
||||||
|
if s = '' then
|
||||||
|
AFormat.Background.BgColor := scWhite
|
||||||
|
else begin
|
||||||
|
AFormat.Background.BgColor := HTMLColorStrToColor(s);
|
||||||
|
if AFormat.Background.Style = fsSolidFill then
|
||||||
|
AFormat.Background.FgColor := AFormat.Background.BgColor;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Include(AFormat.UsedFormattingFields, uffBackground);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads a "Styles/Style/NumberFormat" node
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLReader.ReadNumberFormat(ANode: TDOMNode;
|
||||||
|
var AFormat: TsCellFormat);
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
nf: TsNumberFormat = nfGeneral;
|
||||||
|
nfs: String;
|
||||||
|
begin
|
||||||
|
if ANode = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'ss:Format');
|
||||||
|
case s of
|
||||||
|
'General':
|
||||||
|
exit;
|
||||||
|
'Short Date':
|
||||||
|
begin
|
||||||
|
nf := nfShortDate;
|
||||||
|
nfs := BuildDateTimeFormatString(nf, FWorkbook.FormatSettings);
|
||||||
|
end;
|
||||||
|
'Short Time':
|
||||||
|
begin
|
||||||
|
nf := nfShortTime;
|
||||||
|
nfs := BuildDateTimeFormatString(nf, FWorkbook.FormatSettings);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
nfs := s;
|
||||||
|
end;
|
||||||
|
if nfs = '' then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
AFormat.NumberFormatIndex := TsWorkbook(FWorkbook).AddNumberFormat(nfs);
|
||||||
|
AFormat.NumberFormatStr := nfs;
|
||||||
|
AFormat.NumberFormat := nf;
|
||||||
|
Include(AFormat.UsedFormattingFields, uffNumberFormat);
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Reads a "Worksheet/Table/Row" node
|
Reads a "Worksheet/Table/Row" node
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
@@ -282,6 +632,72 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads a "Styles/Style" node
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLReader.ReadStyle(ANode: TDOMNode);
|
||||||
|
var
|
||||||
|
nodeName: String;
|
||||||
|
fmt: TsCellFormat;
|
||||||
|
s: String;
|
||||||
|
id: Integer;
|
||||||
|
idx: Integer;
|
||||||
|
childNode: TDOMNode;
|
||||||
|
begin
|
||||||
|
// Respect ancestor of current style
|
||||||
|
s := GetAttrValue(ANode, 'ss:Parent');
|
||||||
|
if s <> '' then begin
|
||||||
|
idx := FCellFormatList.FindIndexOfName(s);
|
||||||
|
if idx > -1 then
|
||||||
|
fmt := FCellFormatList.Items[idx]^;
|
||||||
|
end else
|
||||||
|
InitFormatRecord(fmt);
|
||||||
|
|
||||||
|
// ID of current style. We store it in the "Name" field of the TsCellFormat
|
||||||
|
// because it is a string while ID is an Integer (mostly "s<number>", but also
|
||||||
|
// "Default").
|
||||||
|
fmt.Name := GetAttrValue(ANode, 'ss:ID');
|
||||||
|
|
||||||
|
childNode := ANode.FirstChild;
|
||||||
|
while childNode <> nil do begin
|
||||||
|
nodeName := childNode.NodeName;
|
||||||
|
if nodeName = 'Alignment' then
|
||||||
|
ReadAlignment(childNode, fmt)
|
||||||
|
else if nodeName = 'Borders' then
|
||||||
|
ReadBorders(childNode, fmt)
|
||||||
|
else if nodeName = 'Interior' then
|
||||||
|
ReadInterior(childNode, fmt)
|
||||||
|
else if nodeName = 'Font' then
|
||||||
|
ReadFont(childNode, fmt)
|
||||||
|
else if nodeName = 'NumberFormat' then
|
||||||
|
ReadNumberFormat(childnode, fmt)
|
||||||
|
else if nodeName = 'Protection' then
|
||||||
|
ReadCellProtection(childNode, fmt);
|
||||||
|
childNode := childNode.NextSibling;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FCellFormatList.Add(fmt);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Reads the "Styles" node
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsSpreadExcelXMLReader.ReadStyles(ANode: TDOMNode);
|
||||||
|
var
|
||||||
|
nodeName: String;
|
||||||
|
styleNode: TDOMNode;
|
||||||
|
begin
|
||||||
|
if ANode = nil then
|
||||||
|
exit;
|
||||||
|
styleNode := ANode.FirstChild;
|
||||||
|
while styleNode <> nil do begin
|
||||||
|
nodeName := styleNode.NodeName;
|
||||||
|
if nodeName = 'Style' then
|
||||||
|
ReadStyle(styleNode);
|
||||||
|
styleNode := styleNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Reads the "Worksheet/Table" node
|
Reads the "Worksheet/Table" node
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
@@ -351,7 +767,7 @@ end;
|
|||||||
procedure TsSpreadExcelXMLReader.ReadWorksheets(ANode: TDOMNode);
|
procedure TsSpreadExcelXMLReader.ReadWorksheets(ANode: TDOMNode);
|
||||||
var
|
var
|
||||||
nodeName: String;
|
nodeName: String;
|
||||||
s: STring;
|
s: String;
|
||||||
begin
|
begin
|
||||||
while ANode <> nil do begin
|
while ANode <> nil do begin
|
||||||
nodeName := ANode.NodeName;
|
nodeName := ANode.NodeName;
|
||||||
@@ -377,6 +793,7 @@ var
|
|||||||
begin
|
begin
|
||||||
try
|
try
|
||||||
ReadXMLStream(doc, AStream);
|
ReadXMLStream(doc, AStream);
|
||||||
|
ReadStyles(doc.DocumentElement.FindNode('Styles'));
|
||||||
ReadWorksheets(doc.DocumentElement.FindNode('Worksheet'));
|
ReadWorksheets(doc.DocumentElement.FindNode('Worksheet'));
|
||||||
finally
|
finally
|
||||||
doc.Free;
|
doc.Free;
|
||||||
|
Reference in New Issue
Block a user