fpspreadsheet: OOXML reading support for cell borders and diagonals. Unit tests adapted. Passed.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3403 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
3064b8a13f
commit
ead4186b6e
@ -21,8 +21,12 @@
|
|||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="spready"/>
|
||||||
|
</Target>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<Parsing>
|
<Parsing>
|
||||||
<SyntaxOptions>
|
<SyntaxOptions>
|
||||||
@ -54,8 +58,12 @@
|
|||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="spready"/>
|
||||||
|
</Target>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<Parsing>
|
<Parsing>
|
||||||
<SyntaxOptions>
|
<SyntaxOptions>
|
||||||
|
@ -119,6 +119,8 @@ type
|
|||||||
procedure TestWriteRead_ODS_WordWrap;
|
procedure TestWriteRead_ODS_WordWrap;
|
||||||
|
|
||||||
{ OOXML Tests }
|
{ OOXML Tests }
|
||||||
|
procedure TestWriteRead_OOXML_Border;
|
||||||
|
procedure TestWriteRead_OOXML_BorderStyles;
|
||||||
procedure TestWriteRead_OOXML_DateTimeFormats;
|
procedure TestWriteRead_OOXML_DateTimeFormats;
|
||||||
procedure TestWriteRead_OOXML_NumberFormats;
|
procedure TestWriteRead_OOXML_NumberFormats;
|
||||||
|
|
||||||
@ -645,6 +647,11 @@ begin
|
|||||||
TestWriteReadBorder(sfOpenDocument);
|
TestWriteReadBorder(sfOpenDocument);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSpreadWriteReadFormatTests.TestWriteRead_OOXML_Border;
|
||||||
|
begin
|
||||||
|
TestWriteReadBorder(sfOOXML);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ --- BorderStyle tests --- }
|
{ --- BorderStyle tests --- }
|
||||||
|
|
||||||
@ -782,6 +789,11 @@ begin
|
|||||||
TestWriteReadBorderStyles(sfOpenDocument);
|
TestWriteReadBorderStyles(sfOpenDocument);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSpreadWriteReadFormatTests.TestWriteRead_OOXML_BorderStyles;
|
||||||
|
begin
|
||||||
|
TestWriteReadBorderStyles(sfOOXML);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ --- Column widths tests --- }
|
{ --- Column widths tests --- }
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ type
|
|||||||
FFillList: TFPList;
|
FFillList: TFPList;
|
||||||
FBorderList: TFPList;
|
FBorderList: TFPList;
|
||||||
FWrittenByFPS: Boolean;
|
FWrittenByFPS: Boolean;
|
||||||
|
procedure ReadBorders(ANode: TDOMNode);
|
||||||
procedure ReadCell(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
procedure ReadCell(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||||
procedure ReadCellXfs(ANode: TDOMNode);
|
procedure ReadCellXfs(ANode: TDOMNode);
|
||||||
procedure ReadDateMode(ANode: TDOMNode);
|
procedure ReadDateMode(ANode: TDOMNode);
|
||||||
@ -197,6 +198,11 @@ type
|
|||||||
BgColor: Tscolor;
|
BgColor: Tscolor;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TBorderListData = class
|
||||||
|
Borders: TsCellBorders;
|
||||||
|
BorderStyles: TsCellBorderStyles;
|
||||||
|
end;
|
||||||
|
|
||||||
TXFListData = class
|
TXFListData = class
|
||||||
NumFmtIndex: Integer;
|
NumFmtIndex: Integer;
|
||||||
FontIndex: Integer;
|
FontIndex: Integer;
|
||||||
@ -321,6 +327,7 @@ var
|
|||||||
xf: TXfListData;
|
xf: TXfListData;
|
||||||
numFmtData: TsNumFormatData;
|
numFmtData: TsNumFormatData;
|
||||||
fillData: TFillListData;
|
fillData: TFillListData;
|
||||||
|
borderData: TBorderListData;
|
||||||
j: Integer;
|
j: Integer;
|
||||||
begin
|
begin
|
||||||
if Assigned(ACell) then begin
|
if Assigned(ACell) then begin
|
||||||
@ -350,15 +357,17 @@ begin
|
|||||||
else
|
else
|
||||||
Exclude(ACell^.UsedFormattingFields, uffTextRotation);
|
Exclude(ACell^.UsedFormattingFields, uffTextRotation);
|
||||||
ACell^.TextRotation := xf.TextRotation;
|
ACell^.TextRotation := xf.TextRotation;
|
||||||
|
*)
|
||||||
// Borders
|
// Borders
|
||||||
ACell^.BorderStyles := xf.BorderStyles;
|
borderData := FBorderList[xf.BorderIndex];
|
||||||
if xf.Borders <> [] then begin
|
if (borderData <> nil) then begin
|
||||||
Include(ACell^.UsedFormattingFields, uffBorder);
|
ACell^.BorderStyles := borderData.BorderStyles;
|
||||||
ACell^.Border := xf.Borders;
|
if borderData.Borders <> [] then begin
|
||||||
|
Include(Acell^.UsedFormattingFields, uffBorder);
|
||||||
|
ACell^.Border := borderData.Borders;
|
||||||
end else
|
end else
|
||||||
Exclude(ACell^.UsedFormattingFields, uffBorder);
|
Exclude(ACell^.UsedFormattingFields, uffBorder);
|
||||||
*)
|
end;
|
||||||
|
|
||||||
// Background color
|
// Background color
|
||||||
fillData := FFillList[xf.FillIndex];
|
fillData := FFillList[xf.FillIndex];
|
||||||
@ -387,6 +396,115 @@ begin
|
|||||||
FNumFormatList := TsOOXMLNumFormatList.Create(Workbook);
|
FNumFormatList := TsOOXMLNumFormatList.Create(Workbook);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsSpreadOOXMLReader.ReadBorders(ANode: TDOMNode);
|
||||||
|
|
||||||
|
function ReadBorderStyle(ANode: TDOMNode; var ABorderStyle: TsCellBorderStyle): Boolean;
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
colorNode: TDOMNode;
|
||||||
|
nodeName: String;
|
||||||
|
begin
|
||||||
|
Result := false;
|
||||||
|
|
||||||
|
s := GetAttrValue(ANode, 'style');
|
||||||
|
if s = '' then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
ABorderStyle.LineStyle := lsThin;
|
||||||
|
if s = 'thin' then
|
||||||
|
ABorderStyle.LineStyle := lsThin
|
||||||
|
else if s = 'medium' then
|
||||||
|
ABorderStyle.LineStyle := lsMedium
|
||||||
|
else if s = 'thick' then
|
||||||
|
ABorderStyle.LineStyle := lsThick
|
||||||
|
else if s = 'dotted' then
|
||||||
|
ABorderStyle.LineStyle := lsDotted
|
||||||
|
else if s = 'dashed' then
|
||||||
|
ABorderStyle.LineStyle := lsDashed
|
||||||
|
else if s = 'double' then
|
||||||
|
ABorderStyle.LineStyle := lsDouble
|
||||||
|
else if s = 'hair' then
|
||||||
|
ABorderStyle.LineStyle := lsHair;
|
||||||
|
|
||||||
|
ABorderStyle.Color := scBlack;
|
||||||
|
colorNode := ANode.FirstChild;
|
||||||
|
while Assigned(colorNode) do begin
|
||||||
|
nodeName := colorNode.NodeName;
|
||||||
|
if nodeName = 'color' then begin
|
||||||
|
s := GetAttrValue(colorNode, 'rgb');
|
||||||
|
if s <> '' then
|
||||||
|
ABorderStyle.Color := FWorkbook.AddColorToPalette(HTMLColorStrToColor('#' + s))
|
||||||
|
else begin
|
||||||
|
s := GetAttrValue(colorNode, 'indexed');
|
||||||
|
if s <> '' then
|
||||||
|
ABorderStyle.Color := StrToInt(s);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
colorNode := colorNode.NextSibling;
|
||||||
|
end;
|
||||||
|
Result := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
borderNode: TDOMNode;
|
||||||
|
edgeNode: TDOMNode;
|
||||||
|
nodeName: String;
|
||||||
|
borders: TsCellBorders;
|
||||||
|
borderStyles: TsCellBorderStyles;
|
||||||
|
borderData: TBorderListData;
|
||||||
|
s: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if ANode = nil then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
borderNode := ANode.FirstChild;
|
||||||
|
while Assigned(borderNode) do begin
|
||||||
|
nodeName := borderNode.NodeName;
|
||||||
|
if nodeName = 'border' then begin
|
||||||
|
borders := [];
|
||||||
|
s := GetAttrValue(borderNode, 'diagonalUp');
|
||||||
|
if s = '1' then
|
||||||
|
Include(borders, cbDiagUp);
|
||||||
|
s := GetAttrValue(borderNode, 'diagonalDown');
|
||||||
|
if s = '1' then
|
||||||
|
Include(borders, cbDiagDown);
|
||||||
|
edgeNode := borderNode.FirstChild;
|
||||||
|
while Assigned(edgeNode) do begin
|
||||||
|
nodeName := edgeNode.NodeName;
|
||||||
|
if nodeName = 'left' then begin
|
||||||
|
if ReadBorderStyle(edgeNode, borderStyles[cbWest]) then
|
||||||
|
Include(borders, cbWest);
|
||||||
|
end
|
||||||
|
else if nodeName = 'right' then begin
|
||||||
|
if ReadBorderStyle(edgeNode, borderStyles[cbEast]) then
|
||||||
|
Include(borders, cbEast);
|
||||||
|
end
|
||||||
|
else if nodeName = 'top' then begin
|
||||||
|
if ReadBorderStyle(edgeNode, borderStyles[cbNorth]) then
|
||||||
|
Include(borders, cbNorth);
|
||||||
|
end
|
||||||
|
else if nodeName = 'bottom' then begin
|
||||||
|
if ReadBorderStyle(edgeNode, borderStyles[cbSouth]) then
|
||||||
|
Include(borders, cbSouth);
|
||||||
|
end
|
||||||
|
else if nodeName = 'diagonal' then begin
|
||||||
|
if ReadBorderStyle(edgeNode, borderStyles[cbDiagUp]) then
|
||||||
|
borderStyles[cbDiagDown] := borderStyles[cbDiagUp];
|
||||||
|
end;
|
||||||
|
edgeNode := edgeNode.NextSibling;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// add to border list
|
||||||
|
borderData := TBorderListData.Create;
|
||||||
|
borderData.Borders := borders;
|
||||||
|
borderData.BorderStyles := borderStyles;
|
||||||
|
FBorderList.Add(borderData);
|
||||||
|
end;
|
||||||
|
borderNode := borderNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOOXMLReader.ReadCell(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
procedure TsSpreadOOXMLReader.ReadCell(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
@ -869,6 +987,7 @@ begin
|
|||||||
ReadPalette(Doc.DocumentElement.FindNode('colors'));
|
ReadPalette(Doc.DocumentElement.FindNode('colors'));
|
||||||
ReadFonts(Doc.DocumentElement.FindNode('fonts'));
|
ReadFonts(Doc.DocumentElement.FindNode('fonts'));
|
||||||
ReadFills(Doc.DocumentElement.FindNode('fills'));
|
ReadFills(Doc.DocumentElement.FindNode('fills'));
|
||||||
|
ReadBorders(Doc.DocumentElement.FindNode('borders'));
|
||||||
ReadNumFormats(Doc.DocumentElement.FindNode('numFmts'));
|
ReadNumFormats(Doc.DocumentElement.FindNode('numFmts'));
|
||||||
ReadCellXfs(Doc.DocumentElement.FindNode('cellXfs'));
|
ReadCellXfs(Doc.DocumentElement.FindNode('cellXfs'));
|
||||||
FreeAndNil(Doc);
|
FreeAndNil(Doc);
|
||||||
|
Loading…
Reference in New Issue
Block a user