fpspreadsheet: Implement reading of cell borders. Delete test.xls in examples/excel8demo.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2950 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-04-19 16:58:44 +00:00
parent 41f72fef58
commit 0f73aed718
2 changed files with 111 additions and 3 deletions

View File

@ -66,6 +66,19 @@ type
TXFRecordData = class TXFRecordData = class
public public
FormatIndex: Integer; FormatIndex: Integer;
Borders: TsCellBorders;
{
FontIndex: Integer;
Border: TsBorder;
XFType_Protection: Word;
Align_TextBreak: Byte;
XF_Rotation: Byte;
Indent_Shrink_TextDir: Byte;
UsedAttrib: Byte;
Border_Background1: DWord;
Border_Background2: DWord;
Border_Background3: Word;
}
end; end;
TFormatRecordData = class TFormatRecordData = class
@ -87,6 +100,7 @@ type
FXFList: TFPList; // of TXFRecordData FXFList: TFPList; // of TXFRecordData
FFormatList: TFPList; // of TFormatRecordData FFormatList: TFPList; // of TFormatRecordData
function DecodeRKValue(const ARK: DWORD): Double; function DecodeRKValue(const ARK: DWORD): Double;
procedure ApplyCellFormatting(ARow, ACol: Cardinal; XFIndex: Integer);
procedure ExtractNumberFormat(AXFIndex: WORD; procedure ExtractNumberFormat(AXFIndex: WORD;
out ANumberFormat: TsNumberFormat; out ADecimals: Word; out ANumberFormat: TsNumberFormat; out ADecimals: Word;
out ANumberFormatStr: String); out ANumberFormatStr: String);
@ -1972,6 +1986,9 @@ begin
FWorksheet.WriteDateTime(ARow, ACol, lDateTime, nf, nfs) FWorksheet.WriteDateTime(ARow, ACol, lDateTime, nf, nfs)
else else
FWorksheet.WriteNumber(ARow, ACol, Number, nf); FWorksheet.WriteNumber(ARow, ACol, Number, nf);
{Add attributes}
ApplyCellFormatting(ARow, ACol, XF);
end; end;
procedure TsSpreadBIFF8Reader.ReadMulRKValues(const AStream: TStream); procedure TsSpreadBIFF8Reader.ReadMulRKValues(const AStream: TStream);
@ -2021,6 +2038,26 @@ begin
AXF:=WordLEtoN(AStream.ReadWord); AXF:=WordLEtoN(AStream.ReadWord);
end; end;
{ Applies the XF formatting given by the given index to the specified cell }
procedure TsSpreadBIFF8Reader.ApplyCellFormatting(ARow, ACol: Cardinal;
XFIndex: Integer);
var
lCell: PCell;
XFData: TXFRecordData;
begin
lCell := FWorksheet.FindCell(ARow, ACol);
if Assigned(lCell) then begin
XFData := TXFRecordData(FXFList.Items[XFIndex]);
// Borders
if XFData.Borders <> [] then begin
Include(lCell^.UsedFormattingFields, uffBorder);
lCell^.Border := XFData.Borders;
end else
Exclude(lCell^.UsedFormattingFields, uffBorder);
end;
end;
function TsSpreadBIFF8Reader.ReadString(const AStream: TStream; function TsSpreadBIFF8Reader.ReadString(const AStream: TStream;
const ALength: WORD): UTF8String; const ALength: WORD): UTF8String;
begin begin
@ -2150,22 +2187,31 @@ begin
if SizeOf(Double)<>8 then Raise Exception.Create('Double is not 8 bytes'); if SizeOf(Double)<>8 then Raise Exception.Create('Double is not 8 bytes');
Move(Data[0],ResultFormula,sizeof(Data)); Move(Data[0],ResultFormula,sizeof(Data));
FWorksheet.WriteNumber(ARow,ACol,ResultFormula); FWorksheet.WriteNumber(ARow,ACol,ResultFormula);
{Add attributes}
ApplyCellFormatting(ARow, ACol, XF);
end; end;
procedure TsSpreadBIFF8Reader.ReadLabel(AStream: TStream); procedure TsSpreadBIFF8Reader.ReadLabel(AStream: TStream);
var var
L: Word; L: Word;
StringFlags: BYTE; StringFlags: BYTE;
ARow, ACol: Word; ARow, ACol, XF: Word;
WideStrValue: WideString; WideStrValue: WideString;
AnsiStrValue: AnsiString; AnsiStrValue: AnsiString;
begin begin
{ BIFF Record data } (*
{ BIFF Record data }
ARow := WordLEToN(AStream.ReadWord); ARow := WordLEToN(AStream.ReadWord);
ACol := WordLEToN(AStream.ReadWord); ACol := WordLEToN(AStream.ReadWord);
{ Index to XF record, not used } { Index to XF record, not used }
AStream.ReadWord(); AStream.ReadWord();
*)
{ BIFF Record header }
{ BIFF Record data }
{ Index to XF Record }
ReadRowColXF(AStream,ARow,ACol,XF);
{ Byte String with 16-bit size } { Byte String with 16-bit size }
L := WordLEtoN(AStream.ReadWord()); L := WordLEtoN(AStream.ReadWord());
@ -2175,6 +2221,9 @@ begin
{ Save the data } { Save the data }
FWorksheet.WriteUTF8Text(ARow, ACol, UTF16ToUTF8(WideStrValue)); FWorksheet.WriteUTF8Text(ARow, ACol, UTF16ToUTF8(WideStrValue));
{Add attributes}
ApplyCellFormatting(ARow, ACol, XF);
end; end;
procedure TsSpreadBIFF8Reader.ReadNumber(AStream: TStream); procedure TsSpreadBIFF8Reader.ReadNumber(AStream: TStream);
@ -2200,6 +2249,9 @@ begin
FWorksheet.WriteDateTime(ARow, ACol, lDateTime, nf, nfs) FWorksheet.WriteDateTime(ARow, ACol, lDateTime, nf, nfs)
else else
FWorksheet.WriteNumber(ARow,ACol,AValue,nf,nd); FWorksheet.WriteNumber(ARow,ACol,AValue,nf,nd);
{Add attributes}
ApplyCellFormatting(ARow, ACol, XF);
end; end;
procedure TsSpreadBIFF8Reader.ReadRichString(const AStream: TStream); procedure TsSpreadBIFF8Reader.ReadRichString(const AStream: TStream);
@ -2223,6 +2275,9 @@ begin
AStream.ReadWord; // First formatted character AStream.ReadWord; // First formatted character
AStream.ReadWord; // Index to FONT record AStream.ReadWord; // Index to FONT record
end; end;
{Add attributes}
ApplyCellFormatting(ARow, ACol, XF);
end; end;
procedure TsSpreadBIFF8Reader.ReadSST(const AStream: TStream); procedure TsSpreadBIFF8Reader.ReadSST(const AStream: TStream);
@ -2303,14 +2358,52 @@ begin
Raise Exception.CreateFmt('Index %d in SST out of range (0-%d)',[Integer(SSTIndex),FSharedStringTable.Count-1]); Raise Exception.CreateFmt('Index %d in SST out of range (0-%d)',[Integer(SSTIndex),FSharedStringTable.Count-1]);
end; end;
FWorksheet.WriteUTF8Text(ARow, ACol, FSharedStringTable[SSTIndex]); FWorksheet.WriteUTF8Text(ARow, ACol, FSharedStringTable[SSTIndex]);
{Add attributes}
ApplyCellFormatting(ARow, ACol, XF);
end; end;
procedure TsSpreadBIFF8Reader.ReadXF(const AStream: TStream); procedure TsSpreadBIFF8Reader.ReadXF(const AStream: TStream);
type
TXFRecord = packed record // see p. 224
FontIndex: Word; // Offset 0, Size 2
FormatIndex: Word; // Offset 2, Size 2
XFType_CellProt_ParentStyleXF: Word; // Offset 4, Size 2
Align_TextBreak: Byte; // Offset 6, Size 1
XFRotation: Byte; // Offset 7, Size 1
Indent_Shrink_TextDir: Byte; // Offset 8, Size 1
UnusedAttrib: Byte; // Offset 9, Size 1
Border_Background_1: DWord; // Offset 10, Size 4
Border_Background_2: DWord; // Offset 14, Size 4
Border_Background_3: DWord; // Offset 18, Size 2
end;
var var
lData: TXFRecordData; lData: TXFRecordData;
xf: TXFRecord;
begin begin
AStream.ReadBuffer(xf, SizeOf(xf));
{ xf.FormatIndex := WordLEToN(xf.FormatIndex);
xf.XFType_CellProt_ParentStyleXF := WordLEToN(xf.XFType_CellProt_ParentStyleXF);
}
lData := TXFRecordData.Create; lData := TXFRecordData.Create;
// Format index
lData.FormatIndex := WordLEToN(xf.FormatIndex);
// Cell borders
xf.Border_Background_1 := DWordLEToN(xf.Border_Background_1);
xf.Border_Background_2 := DWordLEToN(xf.Border_Background_2);
xf.Border_Background_3 := WordLEToN(xf.Border_Background_3);
lData.Borders := [];
if xf.Border_Background_1 and $0000000F <> 0 then
Include(lData.Borders, cbWest);
if xf.Border_Background_1 and $000000F0 <> 0 then
Include(lData.Borders, cbEast);
if xf.Border_Background_1 and $00000F00 <> 0 then
Include(lData.Borders, cbNorth);
if xf.Border_Background_1 and $0000F000 <> 0 then
Include(lData.Borders, cbSouth);
(*
// Record XF, BIFF8: // Record XF, BIFF8:
// Offset Size Contents // Offset Size Contents
// 0 2 Index to FONT record (➜5.45)) // 0 2 Index to FONT record (➜5.45))
@ -2319,11 +2412,26 @@ begin
// 2 2 Index to FORMAT record (➜5.49)) // 2 2 Index to FORMAT record (➜5.49))
lData.FormatIndex := WordLEtoN(AStream.ReadWord); lData.FormatIndex := WordLEtoN(AStream.ReadWord);
// 4 2 XF type, cell protection, and parent style XF
// Bit Mask Contents
// 2-0 0007H XF_TYPE_PROT – XF type, cell protection (see above)
// 15-4 FFF0H Index to parent style XF (always FFFH in style XFs)
WordLEtoN(AStream.ReadWord);
// 6 1 Alignment and text break:
// Bit Mask Contents
// 2-0 07H XF_HOR_ALIGN – Horizontal alignment (see above)
// 3 08H 1 = Text is wrapped at right border
// 6-4 70H XF_VERT_ALIGN – Vertical alignment (see above)
// 7 80H 1 = Justify last line in justified or distibuted text
b
{ Offset Size Contents { Offset Size Contents
4 2 XF type, cell protection, and parent style XF: 4 2 XF type, cell protection, and parent style XF:
Bit Mask Contents Bit Mask Contents
2-0 0007H XF_TYPE_PROT – XF type, cell protection (see above) 2-0 0007H XF_TYPE_PROT – XF type, cell protection (see above)
15-4 FFF0H Index to parent style XF (always FFFH in style XFs) 15-4 FFF0H Index to parent style XF (always FFFH in style XFs)
6 1 Alignment and text break: 6 1 Alignment and text break:
Bit Mask Contents Bit Mask Contents
2-0 07H XF_HOR_ALIGN – Horizontal alignment (see above) 2-0 07H XF_HOR_ALIGN – Horizontal alignment (see above)
@ -2341,7 +2449,7 @@ begin
; 1 = Left-to-right; 2 = Right-to-left ; 1 = Left-to-right; 2 = Right-to-left
9 1 Flags for used attribute groups: 9 1 Flags for used attribute groups:
....} ....}
*)
// Add the XF to the list // Add the XF to the list
FXFList.Add(lData); FXFList.Add(lData);
end; end;