fpspreadsheet: Add reading of row heights for biff8.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2952 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-04-20 14:57:23 +00:00
parent d617abccca
commit 8c90f30c66
6 changed files with 71 additions and 5 deletions

View File

@ -240,7 +240,7 @@ type
TRow = record TRow = record
Row: Cardinal; Row: Cardinal;
Height: Single; // in milimeters Height: Single; // in millimeters
end; end;
PRow = ^TRow; PRow = ^TRow;
@ -310,6 +310,7 @@ type
{ Properties } { Properties }
property Cells: TAVLTree read FCells; property Cells: TAVLTree read FCells;
property Cols: TIndexedAVLTree read FCols; property Cols: TIndexedAVLTree read FCols;
property Rows: TIndexedAVLTree read FRows;
end; end;
{ TsWorkbook } { TsWorkbook }
@ -358,7 +359,7 @@ type
TsCustomSpreadReader = class TsCustomSpreadReader = class
protected protected
FWorkbook: TsWorkbook; FWorkbook: TsWorkbook;
FCurrentWorksheet: TsWorksheet; FWorksheet: TsWorksheet;
public public
constructor Create; virtual; // To allow descendents to override it constructor Create; virtual; // To allow descendents to override it
{ General writing methods } { General writing methods }

View File

@ -25,6 +25,7 @@ type
FWorksheet: TsWorksheet; FWorksheet: TsWorksheet;
FDisplayFixedColRow: Boolean; FDisplayFixedColRow: Boolean;
function CalcColWidth(AWidth: Single): Integer; function CalcColWidth(AWidth: Single): Integer;
function CalcRowHeight(AHeight: Single): Integer;
procedure SetDisplayFixedColRow(const AValue: Boolean); procedure SetDisplayFixedColRow(const AValue: Boolean);
{ Private declarations } { Private declarations }
protected protected
@ -175,6 +176,9 @@ begin
inherited Destroy; inherited Destroy;
end; end;
// Converts the column width, given in "characters", to pixels
// All chars are assumed to have the same width defined by the "0".
// Therefore, this calculation is only approximate.
function TsCustomWorksheetGrid.CalcColWidth(AWidth: Single): Integer; function TsCustomWorksheetGrid.CalcColWidth(AWidth: Single): Integer;
var var
w0: Integer; w0: Integer;
@ -183,6 +187,12 @@ begin
Result := Round(AWidth * w0); Result := Round(AWidth * w0);
end; end;
// Converts the row height, given in mm, to pixels
function TsCustomWorksheetGrid.CalcRowHeight(AHeight: Single): Integer;
begin
Result := round(AHeight / 25.4 * Screen.PixelsPerInch);
end;
procedure TsCustomWorksheetGrid.DoPrepareCanvas(ACol, ARow: Integer; procedure TsCustomWorksheetGrid.DoPrepareCanvas(ACol, ARow: Integer;
AState: TGridDrawState); AState: TGridDrawState);
var var
@ -309,6 +319,7 @@ procedure TsCustomWorksheetGrid.Setup;
var var
i: Integer; i: Integer;
lCol: PCol; lCol: PCol;
lRow: PRow;
begin begin
if (FWorksheet = nil) or (FWorksheet.GetCellCount = 0) then begin if (FWorksheet = nil) or (FWorksheet.GetCellCount = 0) then begin
if FDisplayFixedColRow then begin if FDisplayFixedColRow then begin
@ -351,6 +362,20 @@ begin
ColWidths[i] := DefaultColWidth; ColWidths[i] := DefaultColWidth;
end; end;
end; end;
if FWorksheet <> nil then begin
RowHeights[0] := DefaultRowHeight;
for i := FixedRows to RowCount-1 do begin
lRow := FWorksheet.FindRow(i - FixedRows);
if (lRow <> nil) then
RowHeights[i] := CalcRowHeight(lRow^.Height)
else
RowHeights[i] := DefaultRowHeight;
end
end
else
for i:=0 to RowCount-1 do begin
RowHeights[i] := DefaultRowHeight;
end;
Invalidate; Invalidate;
end; end;

View File

@ -54,6 +54,9 @@ function GetColString(AColIndex: Integer): String;
function UTF8TextToXMLText(AText: ansistring): ansistring; function UTF8TextToXMLText(AText: ansistring): ansistring;
function TwipsToMillimeters(AValue: Integer): Single;
function MillimetersToTwips(AValue: Single): Integer;
implementation implementation
{ {
@ -431,5 +434,18 @@ begin
Result:=WrkStr; Result:=WrkStr;
end; end;
{ Excel's unit of row heights is "twips", i.e. 1/20 point. 72 pts = 1 inch = 25.4 mm
The procedure TwipsToMillimeters performs the conversion to millimeters. }
function TwipsToMillimeters(AValue: Integer): Single;
begin
Result := 25.4 * AValue / (20 * 72);
end;
{ Converts Millimeters to Twips, i.e. 1/20 pt }
function MillimetersToTwips(AValue: Single): Integer;
begin
Result := Round((AValue * 20 * 72) / 25.4);
end;
end. end.

View File

@ -59,8 +59,6 @@ type
{ TsWikiTableReader } { TsWikiTableReader }
TsWikiTableReader = class(TsCustomSpreadReader) TsWikiTableReader = class(TsCustomSpreadReader)
private
FWorksheet: TsWorksheet;
public public
SubFormat: TsSpreadsheetFormat; SubFormat: TsSpreadsheetFormat;
{ General reading methods } { General reading methods }

View File

@ -93,7 +93,6 @@ type
private private
RecordSize: Word; RecordSize: Word;
PendingRecordSize: SizeInt; PendingRecordSize: SizeInt;
FWorksheet: TsWorksheet;
FWorksheetNames: TStringList; FWorksheetNames: TStringList;
FCurrentWorksheet: Integer; FCurrentWorksheet: Integer;
FSharedStringTable: TStringList; FSharedStringTable: TStringList;
@ -202,6 +201,7 @@ const
INT_EXCEL_ID_INDEX = $020B; INT_EXCEL_ID_INDEX = $020B;
INT_EXCEL_ID_LABEL = $0204; INT_EXCEL_ID_LABEL = $0204;
INT_EXCEL_ID_NUMBER = $0203; INT_EXCEL_ID_NUMBER = $0203;
INT_EXCEL_ID_ROWINFO = $0208;
INT_EXCEL_ID_STYLE = $0293; INT_EXCEL_ID_STYLE = $0293;
INT_EXCEL_ID_WINDOW1 = $003D; INT_EXCEL_ID_WINDOW1 = $003D;
INT_EXCEL_ID_WINDOW2 = $023E; INT_EXCEL_ID_WINDOW2 = $023E;
@ -1922,6 +1922,7 @@ begin
INT_EXCEL_ID_MULRK: ReadMulRKValues(AStream); INT_EXCEL_ID_MULRK: ReadMulRKValues(AStream);
INT_EXCEL_ID_LABELSST:ReadLabelSST(AStream); //BIFF8 only INT_EXCEL_ID_LABELSST:ReadLabelSST(AStream); //BIFF8 only
INT_EXCEL_ID_COLINFO: ReadColInfo(AStream); INT_EXCEL_ID_COLINFO: ReadColInfo(AStream);
INT_EXCEL_ID_ROWINFO: ReadRowInfo(AStream);
INT_EXCEL_ID_BOF: ; INT_EXCEL_ID_BOF: ;
INT_EXCEL_ID_EOF: SectionEOF := True; INT_EXCEL_ID_EOF: SectionEOF := True;
else else

View File

@ -289,6 +289,8 @@ type
procedure ReadCodePage(AStream: TStream); procedure ReadCodePage(AStream: TStream);
// Figures out what the base year for dates is for this file // Figures out what the base year for dates is for this file
procedure ReadDateMode(AStream: TStream); procedure ReadDateMode(AStream: TStream);
// Read row info
procedure ReadRowInfo(const AStream: TStream); virtual;
end; end;
{ TsSpreadBIFFWriter } { TsSpreadBIFFWriter }
@ -461,6 +463,29 @@ begin
end; end;
end; end;
// Read the part of the ROW record that is common to all BIFF versions
procedure TsSpreadBIFFReader.ReadRowInfo(const AStream: TStream);
type
TRowRecord = packed record
RowIndex: Word;
Col1: Word;
Col2: Word;
Height: Word;
end;
var
rowrec: TRowRecord;
lRow: PRow;
h: word;
begin
AStream.ReadBuffer(rowrec, SizeOf(TRowRecord));
h := WordLEToN(rowrec.Height);
if h and $8000 = 0 then begin // if this bit were set, rowheight would be default
lRow := FWorksheet.GetRow(WordLEToN(rowrec.RowIndex));
// Row height is encoded into the 15 remaining bits in units "twips" (1/20 pt)
lRow^.Height := TwipsToMillimeters(h and $7FFF);
end;
end;
function TsSpreadBIFFWriter.FPSColorToExcelPalette(AColor: TsColor): Word; function TsSpreadBIFFWriter.FPSColorToExcelPalette(AColor: TsColor): Word;
begin begin
case AColor of case AColor of