You've already forked lazarus-ccr
fpspreadsheet: Row height and column width reading/writing code for ods files complete. Test cases ok, but extremely slow speed of test application for numbertest and datetimetests. Changed units of row heights in worksheet: used to be points, is "lines" now (more consistent user interface - column width is in "standard characters", I prefer these units over centimeters because row heights/column widths become independent of screen pixels per inch this way)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3118 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -33,7 +33,7 @@ begin
|
||||
//MyWorksheet.WriteColWidth(0, 5);
|
||||
//MyWorksheet.WriteColWidth(1, 30);
|
||||
|
||||
MyWorksheet.WriteRowHeight(0, 30); // 30 mm
|
||||
MyWorksheet.WriteRowHeight(0, 3); // 3 lines
|
||||
|
||||
// Turn off grid lines and hide headers
|
||||
//MyWorksheet.Options := MyWorksheet.Options - [soShowGridLines, soShowHeaders];
|
||||
@ -367,16 +367,16 @@ begin
|
||||
inc(r);
|
||||
|
||||
// Set width of columns 0 to 3
|
||||
MyWorksheet.WriteColWidth(0, 50);
|
||||
lCol.Width := 15;
|
||||
MyWorksheet.WriteColWidth(0, 48); // 48 characters, default is 12 --> 4x default width
|
||||
lCol.Width := 24; // 24 characters, default is 12 --> 2x default width
|
||||
MyWorksheet.WriteColInfo(1, lCol);
|
||||
MyWorksheet.WriteColInfo(2, lCol);
|
||||
MyWorksheet.WriteColInfo(3, lCol);
|
||||
|
||||
// Set height of rows 5 and 6
|
||||
lRow.Height := 10;
|
||||
lRow.Height := 4; // 4 lines
|
||||
MyWorksheet.WriteRowInfo(5, lRow);
|
||||
lRow.Height := 5;
|
||||
lRow.Height := 2; // 2 lines
|
||||
MyWorksheet.WriteRowInfo(6, lRow);
|
||||
|
||||
// Save the spreadsheet to a file
|
||||
|
@ -45,7 +45,7 @@ begin
|
||||
MyWorkbook.AddFont('Calibri', 20, [], scRed);
|
||||
|
||||
// Change row height
|
||||
MyWorksheet.WriteRowHeight(0, 20); // modify height of row 0 to 20 mm
|
||||
MyWorksheet.WriteRowHeight(0, 1.1); // modify height of row 0 to 3 lines
|
||||
|
||||
// Change colum widths
|
||||
MyWorksheet.WriteColWidth(0, 40);
|
||||
|
@ -383,7 +383,7 @@ begin
|
||||
MyWorksheet.WriteColInfo(5, lCol);
|
||||
|
||||
// Set height of rows 0
|
||||
MyWorksheet.WriteRowHeight(0, 30); // 30 mm
|
||||
MyWorksheet.WriteRowHeight(0, 5); // 5 lines
|
||||
|
||||
// Creates a new worksheet
|
||||
MyWorksheet := MyWorkbook.AddWorksheet(Str_Worksheet2);
|
||||
|
@ -32,6 +32,7 @@ begin
|
||||
MyWorksheet.WriteUTF8Text(4, 2, 'Total:');// C5
|
||||
MyWorksheet.WriteNumber(4, 3, 10); // D5
|
||||
MyWorksheet.WriteDateTime(5, 0, now);
|
||||
|
||||
// Add some formatting
|
||||
MyWorksheet.WriteUsedFormatting(0, 0, [uffBold]);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -335,16 +335,22 @@ type
|
||||
|
||||
PCell = ^TCell;
|
||||
|
||||
const
|
||||
// Takes account of effect of cell margins on row height by adding this
|
||||
// value to the nominal row height. Note that this is an empirical value and may be wrong.
|
||||
ROW_HEIGHT_CORRECTION = 0.2;
|
||||
|
||||
type
|
||||
TRow = record
|
||||
Row: Cardinal;
|
||||
Height: Single; // in millimeters
|
||||
Height: Single; // in "lines"
|
||||
end;
|
||||
|
||||
PRow = ^TRow;
|
||||
|
||||
TCol = record
|
||||
Col: Cardinal;
|
||||
Width: Single; // in "characters". Excel uses the with of char "0" in 1st font
|
||||
Width: Single; // in "characters". Excel uses the width of char "0" in 1st font
|
||||
end;
|
||||
|
||||
PCol = ^TCol;
|
||||
@ -368,7 +374,7 @@ type
|
||||
FWorkbook: TsWorkbook;
|
||||
FCells: TAvlTree; // Items are TCell
|
||||
FCurrentNode: TAVLTreeNode; // For GetFirstCell and GetNextCell
|
||||
FRows, FCols: TIndexedAVLTree; // This lists contain only rows or cols with styles different from the standard
|
||||
FRows, FCols: TIndexedAVLTree; // This lists contain only rows or cols with styles different from default
|
||||
FLeftPaneWidth: Integer;
|
||||
FTopPaneHeight: Integer;
|
||||
FOptions: TsSheetOptions;
|
||||
@ -475,8 +481,12 @@ type
|
||||
{ Data manipulation methods - For Rows and Cols }
|
||||
function FindRow(ARow: Cardinal): PRow;
|
||||
function FindCol(ACol: Cardinal): PCol;
|
||||
function GetCellCountInRow(ARow: Cardinal): Cardinal;
|
||||
function GetCellCountInCol(ACol: Cardinal): Cardinal;
|
||||
function GetRow(ARow: Cardinal): PRow;
|
||||
function GetRowHeight(ARow: Cardinal): Single;
|
||||
function GetCol(ACol: Cardinal): PCol;
|
||||
function GetColWidth(ACol: Cardinal): Single;
|
||||
procedure RemoveAllRows;
|
||||
procedure RemoveAllCols;
|
||||
procedure WriteRowInfo(ARow: Cardinal; AData: TRow);
|
||||
@ -511,10 +521,15 @@ type
|
||||
FBuiltinFontCount: Integer;
|
||||
FPalette: array of TsColorValue;
|
||||
FReadFormulas: Boolean;
|
||||
FDefaultColWidth: Single; // in "characters". Excel uses the width of char "0" in 1st font
|
||||
FDefaultRowHeight: Single; // in "character heights", i.e. line count
|
||||
|
||||
{ Internal methods }
|
||||
procedure RemoveWorksheetsCallback(data, arg: pointer);
|
||||
|
||||
public
|
||||
FormatSettings: TFormatSettings;
|
||||
|
||||
{ Base methods }
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -530,6 +545,7 @@ type
|
||||
const AOverwriteExisting: Boolean = False); overload;
|
||||
procedure WriteToFile(const AFileName: String; const AOverwriteExisting: Boolean = False); overload;
|
||||
procedure WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat);
|
||||
|
||||
{ Worksheet list handling methods }
|
||||
function AddWorksheet(AName: string): TsWorksheet;
|
||||
function GetFirstWorksheet: TsWorksheet;
|
||||
@ -537,6 +553,7 @@ type
|
||||
function GetWorksheetByName(AName: String): TsWorksheet;
|
||||
function GetWorksheetCount: Cardinal;
|
||||
procedure RemoveAllWorksheets;
|
||||
|
||||
{ Font handling }
|
||||
function AddFont(const AFontName: String; ASize: Single;
|
||||
AStyle: TsFontStyles; AColor: TsColor): Integer; overload;
|
||||
@ -544,11 +561,13 @@ type
|
||||
procedure CopyFontList(ASource: TFPList);
|
||||
function FindFont(const AFontName: String; ASize: Single;
|
||||
AStyle: TsFontStyles; AColor: TsColor): Integer;
|
||||
function GetDefaultFontSize: Single;
|
||||
function GetFont(AIndex: Integer): TsFont;
|
||||
function GetFontCount: Integer;
|
||||
procedure InitFonts;
|
||||
procedure RemoveAllFonts;
|
||||
procedure SetDefaultFont(const AFontName: String; ASize: Single);
|
||||
|
||||
{ Color handling }
|
||||
function AddColorToPalette(AColorValue: TsColorValue): TsColor;
|
||||
function FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): String;
|
||||
@ -560,6 +579,13 @@ type
|
||||
procedure UseDefaultPalette;
|
||||
procedure UsePalette(APalette: PsPalette; APaletteCount: Word;
|
||||
ABigEndian: Boolean = false);
|
||||
|
||||
{@@ The default column width given in "character units" (width of the
|
||||
character "0" in the default font) }
|
||||
property DefaultColWidth: Single read FDefaultColWidth;
|
||||
{@@ The default row height is given in "line count" (height of the
|
||||
default font }
|
||||
property DefaultRowHeight: Single read FDefaultRowHeight;
|
||||
{@@ This property is only used for formats which don't support unicode
|
||||
and support a single encoding for the whole document, like Excel 2 to 5 }
|
||||
property Encoding: TsEncoding read FEncoding write FEncoding;
|
||||
@ -1366,6 +1392,7 @@ end;
|
||||
function TsWorksheet.GetLastColIndex: Cardinal;
|
||||
var
|
||||
AVLNode: TAVLTreeNode;
|
||||
i: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
|
||||
@ -1378,6 +1405,12 @@ begin
|
||||
Result := Math.Max(Result, PCell(AVLNode.Data)^.Col);
|
||||
AVLNode := FCells.FindSuccessor(AVLNode);
|
||||
end;
|
||||
|
||||
// In addition, there may be column records defining the column width even
|
||||
// without content
|
||||
for i:=0 to FCols.Count-1 do
|
||||
if FCols[i] <> nil then
|
||||
Result := Math.Max(Result, PCol(FCols[i])^.Col);
|
||||
end;
|
||||
|
||||
function TsWorksheet.GetLastColNumber: Cardinal;
|
||||
@ -1424,12 +1457,18 @@ end;
|
||||
function TsWorksheet.GetLastRowIndex: Cardinal;
|
||||
var
|
||||
AVLNode: TAVLTreeNode;
|
||||
i: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
|
||||
AVLNode := FCells.FindHighest;
|
||||
if Assigned(AVLNode) then
|
||||
Result := PCell(AVLNode.Data).Row;
|
||||
|
||||
// In addition, there may be row records even for empty rows.
|
||||
for i:=0 to FRows.Count-1 do
|
||||
if FRows[i] <> nil then
|
||||
Result := Math.Max(Result, PRow(FRows[i])^.Row);
|
||||
end;
|
||||
|
||||
function TsWorksheet.GetLastRowNumber: Cardinal;
|
||||
@ -2243,7 +2282,6 @@ var
|
||||
AVLNode: TAVGLVLTreeNode;
|
||||
begin
|
||||
Result := nil;
|
||||
|
||||
LElement.Row := ARow;
|
||||
AVLNode := FRows.Find(@LElement);
|
||||
if Assigned(AVLNode) then
|
||||
@ -2256,7 +2294,6 @@ var
|
||||
AVLNode: TAVGLVLTreeNode;
|
||||
begin
|
||||
Result := nil;
|
||||
|
||||
LElement.Col := ACol;
|
||||
AVLNode := FCols.Find(@LElement);
|
||||
if Assigned(AVLNode) then
|
||||
@ -2285,6 +2322,72 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Counts how many cells exist in the given column. Blank cells do contribute
|
||||
to the sum, as well as rows with a non-default style. }
|
||||
function TsWorksheet.GetCellCountInCol(ACol: Cardinal): Cardinal;
|
||||
var
|
||||
cell: PCell;
|
||||
r: Cardinal;
|
||||
row: PRow;
|
||||
begin
|
||||
Result := 0;
|
||||
for r := 0 to GetLastRowIndex do begin
|
||||
cell := FindCell(r, ACol);
|
||||
if cell <> nil then
|
||||
inc(Result)
|
||||
else begin
|
||||
row := FindRow(r);
|
||||
if row <> nil then inc(Result);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Counts how many cells exist in the given row. Blank cells do contribute
|
||||
to the sum, as well as columns with a non-default style. }
|
||||
function TsWorksheet.GetCellCountInRow(ARow: Cardinal): Cardinal;
|
||||
var
|
||||
cell: PCell;
|
||||
c: Cardinal;
|
||||
col: PCol;
|
||||
begin
|
||||
Result := 0;
|
||||
for c := 0 to GetLastColIndex do begin
|
||||
cell := FindCell(ARow, c);
|
||||
if cell <> nil then
|
||||
inc(Result)
|
||||
else begin
|
||||
col := FindCol(c);
|
||||
if col <> nil then inc(Result);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Returns the width of the given column. If there is no column record then
|
||||
the default column width is returned. }
|
||||
function TsWorksheet.GetColWidth(ACol: Cardinal): Single;
|
||||
var
|
||||
col: PCol;
|
||||
begin
|
||||
col := FindCol(ACol);
|
||||
if col <> nil then
|
||||
Result := col^.Width
|
||||
else
|
||||
Result := FWorkbook.DefaultColWidth;
|
||||
end;
|
||||
|
||||
{ Returns the height of the given row. If there is no row record then the
|
||||
default row height is returned }
|
||||
function TsWorksheet.GetRowHeight(ARow: Cardinal): Single;
|
||||
var
|
||||
row: PRow;
|
||||
begin
|
||||
row := FindRow(ARow);
|
||||
if row <> nil then
|
||||
Result := row^.Height
|
||||
else
|
||||
Result := FWorkbook.DefaultRowHeight;
|
||||
end;
|
||||
|
||||
procedure TsWorksheet.RemoveAllRows;
|
||||
var
|
||||
Node: Pointer;
|
||||
@ -2359,6 +2462,8 @@ constructor TsWorkbook.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
FWorksheets := TFPList.Create;
|
||||
FDefaultColWidth := 12;
|
||||
FDefaultRowHeight := 1;
|
||||
FormatSettings := DefaultFormatSettings;
|
||||
FFontList := TFPList.Create;
|
||||
SetDefaultFont('Arial', 10.0);
|
||||
@ -2777,7 +2882,6 @@ begin
|
||||
// FONT4 which does not exist in BIFF is added automatically with nil as place-holder
|
||||
AddFont(fntName, fntSize, [fssBold, fssItalic], scBlack); // FONT5 for uffBoldItalic
|
||||
|
||||
|
||||
FBuiltinFontCount := FFontList.Count;
|
||||
end;
|
||||
|
||||
@ -2816,6 +2920,14 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Returns the point size of the default font
|
||||
}
|
||||
function TsWorkbook.GetDefaultFontSize: Single;
|
||||
begin
|
||||
Result := GetFont(0).Size;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Returns the font with the given index.
|
||||
}
|
||||
|
@ -525,10 +525,13 @@ begin
|
||||
Result := h;
|
||||
end;
|
||||
|
||||
{ Converts the row height, given in mm, to pixels }
|
||||
{ Converts the row height (from a worksheet row), given in lines, to pixels }
|
||||
function TsCustomWorksheetGrid.CalcRowHeight(AHeight: Single): Integer;
|
||||
var
|
||||
h_pts: Single;
|
||||
begin
|
||||
Result := round(AHeight / 25.4 * Screen.PixelsPerInch) + 4;
|
||||
h_pts := AHeight * (Workbook.GetFont(0).Size + ROW_HEIGHT_CORRECTION);
|
||||
Result := PtsToPX(h_pts, Screen.PixelsPerInch) + 4;
|
||||
end;
|
||||
|
||||
procedure TsCustomWorksheetGrid.ChangedCellHandler(ASender: TObject; ARow, ACol:Cardinal);
|
||||
@ -1871,7 +1874,7 @@ end;
|
||||
procedure TsCustomWorksheetGrid.HeaderSized(IsColumn: Boolean; index: Integer);
|
||||
var
|
||||
w0: Integer;
|
||||
h: Single;
|
||||
h, h_pts: Single;
|
||||
begin
|
||||
if FWorksheet = nil then
|
||||
exit;
|
||||
@ -1884,8 +1887,9 @@ begin
|
||||
FWorksheet.WriteColWidth(GetWorksheetCol(Index), ColWidths[Index] div w0);
|
||||
end else begin
|
||||
// The grid's row heights are in "pixels", the worksheet's row heights are
|
||||
// in millimeters.
|
||||
h := (RowHeights[Index] - 4) / Screen.PixelsPerInch * 25.4;
|
||||
// in "lines"
|
||||
h_pts := PxToPts(RowHeights[Index] - 4, Screen.PixelsPerInch); // in points
|
||||
h := h_pts / (FWorkbook.GetFont(0).Size + ROW_HEIGHT_CORRECTION);
|
||||
FWorksheet.WriteRowHeight(GetWorksheetRow(Index), h);
|
||||
end;
|
||||
end;
|
||||
@ -2616,6 +2620,7 @@ end;
|
||||
|
||||
|
||||
initialization
|
||||
fpsutils.ScreenPixelsPerInch := Screen.PixelsPerInch;
|
||||
|
||||
finalization
|
||||
FreeAndNil(FillPattern_BIFF2);
|
||||
|
@ -66,9 +66,6 @@ function GetErrorValueStr(AErrorValue: TsErrorValue): String;
|
||||
|
||||
function UTF8TextToXMLText(AText: ansistring): ansistring;
|
||||
|
||||
function TwipsToMillimeters(AValue: Integer): Single;
|
||||
function MillimetersToTwips(AValue: Single): Integer;
|
||||
|
||||
function IfThen(ACondition: Boolean; AValue1,AValue2: TsNumberFormat): TsNumberFormat; overload;
|
||||
|
||||
function IsDateTimeFormat(AFormat: TsNumberFormat): Boolean;
|
||||
@ -102,12 +99,24 @@ function FormatDateTime(const FormatStr: string; DateTime: TDateTime;
|
||||
function FormatDateTime(const FormatStr: string; DateTime: TDateTime;
|
||||
const FormatSettings: TFormatSettings; Options : TFormatDateTimeOptions = []): string;
|
||||
|
||||
function TwipsToPts(AValue: Integer): Single;
|
||||
function PtsToTwips(AValue: Single): Integer;
|
||||
function cmToPts(AValue: Double): Double;
|
||||
function PtsToCm(AValue: Double): Double;
|
||||
function InToPts(AValue: Double): Double;
|
||||
function mmToPts(AValue: Double): Double;
|
||||
function PtsToMM(AValue: Double): Double;
|
||||
function pxToPts(AValue, AScreenPixelsPerInch: Integer): Double;
|
||||
function PtsToPx(AValue: Double; AScreenPixelsPerInch: Integer): Integer;
|
||||
function HTMLLengthStrToPts(AValue: String): Double;
|
||||
//function HMTLLengthStrToPts(AValue: String): Double;
|
||||
|
||||
function HTMLColorStrToColor(AValue: String): TsColorValue;
|
||||
function ColorToHTMLColorStr(AValue: TsColorValue): String;
|
||||
|
||||
var
|
||||
ScreenPixelsPerInch: Integer = 96;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -533,19 +542,6 @@ begin
|
||||
Result:=WrkStr;
|
||||
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;
|
||||
|
||||
{ Returns either AValue1 or AValue2, depending on the condition.
|
||||
For reduciton of typing... }
|
||||
function IfThen(ACondition: Boolean; AValue1, AValue2: TsNumberFormat): TsNumberFormat;
|
||||
@ -1296,16 +1292,82 @@ begin
|
||||
DateTimeToString(Result, FormatStr, DateTime, FormatSettings,Options);
|
||||
end;
|
||||
|
||||
{ Excel's unit of row heights is "twips", i.e. 1/20 point.
|
||||
Converts Twips to points. }
|
||||
function TwipsToPts(AValue: Integer): Single;
|
||||
begin
|
||||
Result := AValue / 20;
|
||||
end;
|
||||
|
||||
{ Converts points to twips (1 twip = 1/20 point) }
|
||||
function PtsToTwips(AValue: Single): Integer;
|
||||
begin
|
||||
Result := round(AValue * 20);
|
||||
end;
|
||||
|
||||
{ Converts centimeters to points (72 pts = 1 inch) }
|
||||
function cmToPts(AValue: Double): Double;
|
||||
begin
|
||||
Result := AValue/2.54*72;
|
||||
Result := AValue * 72 / 2.54;
|
||||
end;
|
||||
|
||||
{ Converts points to centimeters }
|
||||
function PtsToCm(AValue: Double): Double;
|
||||
begin
|
||||
Result := AValue / 72 * 2.54;
|
||||
end;
|
||||
|
||||
{ Converts inches to points (72 pts = 1 inch) }
|
||||
function InToPts(AValue: Double): Double;
|
||||
begin
|
||||
Result := AValue * 72;
|
||||
end;
|
||||
|
||||
{ Converts millimeters to points (72 pts = 1 inch) }
|
||||
function mmToPts(AValue: Double): Double;
|
||||
begin
|
||||
Result := AValue/25.4*72;
|
||||
Result := AValue * 72 / 25.4;
|
||||
end;
|
||||
|
||||
{ Converts points to millimeters }
|
||||
function PtsToMM(AValue: Double): Double;
|
||||
begin
|
||||
Result := AValue / 72 * 25.4;
|
||||
end;
|
||||
|
||||
{ Converts pixels to points. }
|
||||
function pxToPts(AValue, AScreenPixelsPerInch: Integer): Double;
|
||||
begin
|
||||
Result := (AValue / AScreenPixelsPerInch) * 72;
|
||||
end;
|
||||
|
||||
{ Converts points to pixels }
|
||||
function PtsToPx(AValue: Double; AScreenPixelsPerInch: Integer): Integer;
|
||||
begin
|
||||
Result := Round(AValue / 72 * AScreenPixelsPerInch);
|
||||
end;
|
||||
|
||||
{ converts a HTML length string to points. The units are assumed to be the last
|
||||
two digits of the string }
|
||||
function HTMLLengthStrToPts(AValue: String): Double;
|
||||
var
|
||||
units: String;
|
||||
x: Double;
|
||||
res: Word;
|
||||
begin
|
||||
units := lowercase(Copy(AValue, Length(AValue)-1, 2));
|
||||
val(copy(AValue, 1, Length(AValue)-2), x, res);
|
||||
// No hasseling with the decimal point...
|
||||
if units = 'in' then
|
||||
Result := InToPts(x)
|
||||
else if units = 'cm' then
|
||||
Result := cmToPts(x)
|
||||
else if units = 'mm' then
|
||||
Result := mmToPts(x)
|
||||
else if units = 'px' then
|
||||
Result := pxToPts(Round(x), ScreenPixelsPerInch)
|
||||
else
|
||||
raise Exception.Create('Unknown length units');
|
||||
end;
|
||||
|
||||
{ converts a HTML color string to a TsColorValue. For ods }
|
||||
|
@ -107,6 +107,8 @@ type
|
||||
procedure TestWriteRead_ODS_Alignment;
|
||||
procedure TestWriteRead_ODS_Border;
|
||||
procedure TestWriteRead_ODS_BorderStyles;
|
||||
procedure TestWriteRead_ODS_ColWidths;
|
||||
procedure TestWriteRead_ODS_RowHeights;
|
||||
procedure TestWriteRead_ODS_TextRotation;
|
||||
procedure TestWriteRead_ODS_WordWrap;
|
||||
end;
|
||||
@ -203,13 +205,13 @@ begin
|
||||
end;
|
||||
|
||||
// Column width
|
||||
SollColWidths[0] := 20; // characters based on width of "0"
|
||||
SollColWidths[0] := 20; // characters based on width of "0" of default font
|
||||
SollColWidths[1] := 40;
|
||||
|
||||
// Row heights
|
||||
SollRowHeights[0] := 5;
|
||||
SollRowHeights[1] := 10;
|
||||
SollRowHeights[2] := 50;
|
||||
SollRowHeights[0] := 1; // Lines of default font
|
||||
SollRowHeights[1] := 2;
|
||||
SollRowHeights[2] := 4;
|
||||
|
||||
// Cell borders
|
||||
SollBorders[0] := [];
|
||||
@ -723,6 +725,7 @@ begin
|
||||
MyWorkSheet:= MyWorkBook.AddWorksheet(ColWidthSheet);
|
||||
for Col := Low(SollColWidths) to High(SollColWidths) do begin
|
||||
lCol.Width := SollColWidths[Col];
|
||||
//MyWorksheet.WriteNumber(0, Col, 1);
|
||||
MyWorksheet.WriteColInfo(Col, lCol);
|
||||
end;
|
||||
MyWorkBook.WriteToFile(TempFile, AFormat, true);
|
||||
@ -742,8 +745,9 @@ begin
|
||||
if lpCol = nil then
|
||||
fail('Error in test code. Failed to return saved column width');
|
||||
ActualColWidth := lpCol^.Width;
|
||||
CheckEquals(SollColWidths[Col], ActualColWidth,
|
||||
'Test saved colwidth mismatch, column '+ColNotation(MyWorkSheet,Col));
|
||||
if abs(SollColWidths[Col] - ActualColWidth) > 1E-2 then // take rounding errors into account
|
||||
CheckEquals(SollColWidths[Col], ActualColWidth,
|
||||
'Test saved colwidth mismatch, column '+ColNotation(MyWorkSheet,Col));
|
||||
end;
|
||||
// Finalization
|
||||
MyWorkbook.Free;
|
||||
@ -766,6 +770,10 @@ begin
|
||||
TestWriteReadColWidths(sfExcel8);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadFormatTests.TestWriteRead_ODS_ColWidths;
|
||||
begin
|
||||
TestWriteReadColWidths(sfOpenDocument);
|
||||
end;
|
||||
|
||||
{ --- Row height tests --- }
|
||||
|
||||
@ -801,14 +809,11 @@ begin
|
||||
if MyWorksheet=nil then
|
||||
fail('Error in test code. Failed to get named worksheet');
|
||||
for Row := Low(SollRowHeights) to High(SollRowHeights) do begin
|
||||
lpRow := MyWorksheet.GetRow(Row);
|
||||
if lpRow = nil then
|
||||
fail('Error in test code. Failed to return saved row height');
|
||||
// Rounding to twips in Excel would cause severe rounding error if we'd compare millimeters
|
||||
// --> go back to twips
|
||||
ActualRowHeight := MillimetersToTwips(lpRow^.Height);
|
||||
CheckEquals(MillimetersToTwips(SollRowHeights[Row]), ActualRowHeight,
|
||||
'Test saved row height mismatch, row '+RowNotation(MyWorkSheet,Row));
|
||||
ActualRowHeight := MyWorksheet.GetRowHeight(Row);
|
||||
// Take care of rounding errors
|
||||
if abs(ActualRowHeight - SollRowHeights[Row]) > 1e-2 then
|
||||
CheckEquals(SollRowHeights[Row], ActualRowHeight,
|
||||
'Test saved row height mismatch, row '+RowNotation(MyWorkSheet,Row));
|
||||
end;
|
||||
// Finalization
|
||||
MyWorkbook.Free;
|
||||
@ -831,6 +836,11 @@ begin
|
||||
TestWriteReadRowHeights(sfExcel8);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadFormatTests.TestWriteRead_ODS_RowHeights;
|
||||
begin
|
||||
TestWriteReadRowHeights(sfOpenDocument);
|
||||
end;
|
||||
|
||||
|
||||
{ --- Text rotation tests --- }
|
||||
|
||||
|
@ -708,7 +708,12 @@ begin
|
||||
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);
|
||||
// We need it in "lines" units.
|
||||
lRow^.Height := TwipsToPts(h and $7FFF) / Workbook.GetFont(0).Size;
|
||||
if lRow^.Height > ROW_HEIGHT_CORRECTION then
|
||||
lRow^.Height := lRow^.Height - ROW_HEIGHT_CORRECTION
|
||||
else
|
||||
lRow^.Height := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1632,6 +1637,7 @@ var
|
||||
containsXF: Boolean;
|
||||
rowheight: Word;
|
||||
w: Word;
|
||||
h: Single;
|
||||
begin
|
||||
containsXF := false;
|
||||
|
||||
@ -1649,10 +1655,14 @@ begin
|
||||
AStream.WriteWord(WordToLE(Word(ALastColIndex) + 1));
|
||||
|
||||
{ Row height (in twips, 1/20 point) and info on custom row height }
|
||||
if (ARow = nil) or (ARow^.Height = 0) then
|
||||
rowheight := round(Workbook.GetFont(0).Size*20)
|
||||
h := Workbook.GetFont(0).Size;
|
||||
if (ARow = nil) or (ARow^.Height = Workbook.DefaultRowHeight) then
|
||||
rowheight := PtsToTwips((Workbook.DefaultRowHeight + ROW_HEIGHT_CORRECTION) * h)
|
||||
else
|
||||
rowheight := MillimetersToTwips(ARow^.Height);
|
||||
if (ARow^.Height = 0) then
|
||||
rowheight := 0
|
||||
else
|
||||
rowheight := PtsToTwips((ARow^.Height + ROW_HEIGHT_CORRECTION) * h);
|
||||
w := rowheight and $7FFF;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
|
||||
|
@ -1329,12 +1329,13 @@ begin
|
||||
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 else
|
||||
lRow^.Height := 0;
|
||||
//lRow^.AutoHeight := rowrec.Flags and $00000040 = 0;
|
||||
// If this bit is set row height does not change with font height, i.e. has been
|
||||
// changed manually.
|
||||
// We need it in "lines", i.e. we divide the points by the point size of the default font
|
||||
lRow^.Height := TwipsToPts(h and $7FFF) / FWorkbook.GetFont(0).Size;
|
||||
if lRow^.Height > ROW_HEIGHT_CORRECTION then
|
||||
lRow^.Height := lRow^.Height - ROW_HEIGHT_CORRECTION
|
||||
else
|
||||
lRow^.Height := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Reads the cell address used in an RPN formula element. Evaluates the corresponding
|
||||
@ -1903,6 +1904,7 @@ var
|
||||
spaceabove, spacebelow: Boolean;
|
||||
colindex: Cardinal;
|
||||
rowheight: Word;
|
||||
h: Single;
|
||||
begin
|
||||
// Check for additional space above/below row
|
||||
spaceabove := false;
|
||||
@ -1934,10 +1936,14 @@ begin
|
||||
AStream.WriteWord(WordToLE(Word(ALastColIndex) + 1));
|
||||
|
||||
{ Row height (in twips, 1/20 point) and info on custom row height }
|
||||
if (ARow = nil) or (ARow^.Height = 0) then
|
||||
rowheight := round(Workbook.GetFont(0).Size*20)
|
||||
h := Workbook.GetFont(0).Size; // Point size of default font
|
||||
if (ARow = nil) or (ARow^.Height = Workbook.DefaultRowHeight) then
|
||||
rowheight := PtsToTwips((Workbook.DefaultRowHeight + ROW_HEIGHT_CORRECTION) * h)
|
||||
else
|
||||
rowheight := MillimetersToTwips(ARow^.Height);
|
||||
if (ARow^.Height = 0) then
|
||||
rowheight := 0
|
||||
else
|
||||
rowheight := PtsToTwips((ARow^.Height + ROW_HEIGHT_CORRECTION)*h);
|
||||
w := rowheight and $7FFF;
|
||||
AStream.WriteWord(WordToLE(w));
|
||||
|
||||
|
Reference in New Issue
Block a user