fpspreadsheet: Support for column widths and row heights of xlsx reader. Extend unit tests --> passed. Add "debug with heaptrc" build mode to spreadtestgui (--> there is an unfixed memory leak in fpsfunc).

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3418 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-08-03 21:21:31 +00:00
parent f10b177f03
commit a7c1405be0
4 changed files with 185 additions and 105 deletions

View File

@ -184,7 +184,7 @@ function fpsVALUE (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
implementation implementation
uses uses
Math, lazutf8, StrUtils, DateUtils, fpsUtils; Math, lazutf8, DateUtils, fpsUtils;
{ Helpers } { Helpers }

View File

@ -122,6 +122,8 @@ type
procedure TestWriteRead_OOXML_Alignment; procedure TestWriteRead_OOXML_Alignment;
procedure TestWriteRead_OOXML_Border; procedure TestWriteRead_OOXML_Border;
procedure TestWriteRead_OOXML_BorderStyles; procedure TestWriteRead_OOXML_BorderStyles;
procedure TestWriteRead_OOXML_ColWidths;
procedure TestWriteRead_OOXML_RowHeights;
procedure TestWriteRead_OOXML_DateTimeFormats; procedure TestWriteRead_OOXML_DateTimeFormats;
procedure TestWriteRead_OOXML_NumberFormats; procedure TestWriteRead_OOXML_NumberFormats;
procedure TestWriteRead_OOXML_TextRotation; procedure TestWriteRead_OOXML_TextRotation;
@ -934,6 +936,12 @@ begin
TestWriteReadColWidths(sfOpenDocument); TestWriteReadColWidths(sfOpenDocument);
end; end;
procedure TSpreadWriteReadFormatTests.TestWriteRead_OOXML_ColWidths;
begin
TestWriteReadColWidths(sfOOXML);
end;
{ --- Row height tests --- } { --- Row height tests --- }
procedure TSpreadWriteReadFormatTests.TestWriteReadRowHeights(AFormat: TsSpreadsheetFormat); procedure TSpreadWriteReadFormatTests.TestWriteReadRowHeights(AFormat: TsSpreadsheetFormat);
@ -1005,6 +1013,11 @@ begin
TestWriteReadRowHeights(sfOpenDocument); TestWriteReadRowHeights(sfOpenDocument);
end; end;
procedure TSpreadWriteReadFormatTests.TestWriteRead_OOXML_RowHeights;
begin
TestWriteReadRowHeights(sfOOXML);
end;
{ --- Text rotation tests --- } { --- Text rotation tests --- }

View File

@ -87,16 +87,20 @@ begin
// Create test workbook // Create test workbook
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(SHEET); MyWorkSheet:= MyWorkBook.AddWorksheet(SHEET);
// Write out all test formulas // Write out all test formulas
// All formulas are in column B // All formulas are in column B
WriteRPNFormulaSamples(MyWorksheet, AFormat, true); WriteRPNFormulaSamples(MyWorksheet, AFormat, true);
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the spreadsheet // Open the spreadsheet
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFormulas := true; MyWorkbook.ReadFormulas := true;
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
@ -116,10 +120,11 @@ begin
end; end;
end; end;
// Finalization finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF2_FormulaStrings; procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF2_FormulaStrings;
begin begin
@ -174,6 +179,7 @@ begin
// Create test workbook // Create test workbook
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet:= MyWorkBook.AddWorksheet(SHEET); MyWorkSheet:= MyWorkBook.AddWorksheet(SHEET);
MyWorkSheet.Options := MyWorkSheet.Options + [soCalcBeforeSaving]; MyWorkSheet.Options := MyWorkSheet.Options + [soCalcBeforeSaving];
// Calculation of rpn formulas must be activated explicitly! // Calculation of rpn formulas must be activated explicitly!
@ -187,10 +193,13 @@ begin
{$I testcases_calcrpnformula.inc} {$I testcases_calcrpnformula.inc}
TempFile:=GetTempFileName; TempFile:=GetTempFileName;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free; MyWorkbook.Free;
end;
// Open the workbook // Open the workbook
MyWorkbook := TsWorkbook.Create; MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat); MyWorkbook.ReadFromFile(TempFile, AFormat);
if AFormat = sfExcel2 then if AFormat = sfExcel2 then
MyWorksheet := MyWorkbook.GetFirstWorksheet MyWorksheet := MyWorkbook.GetFirstWorksheet
@ -259,10 +268,11 @@ begin
end; end;
end; end;
// Finalization finally
MyWorkbook.Free; MyWorkbook.Free;
DeleteFile(TempFile); DeleteFile(TempFile);
end; end;
end;
procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF2_CalcRPNFormula; procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF2_CalcRPNFormula;
begin begin

View File

@ -68,6 +68,7 @@ type
procedure ReadBorders(ANode: TDOMNode); 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 ReadCols(ANode: TDOMNode; AWorksheet: TsWorksheet);
procedure ReadDateMode(ANode: TDOMNode); procedure ReadDateMode(ANode: TDOMNode);
procedure ReadFileVersion(ANode: TDOMNode); procedure ReadFileVersion(ANode: TDOMNode);
procedure ReadFills(ANode: TDOMNode); procedure ReadFills(ANode: TDOMNode);
@ -75,6 +76,7 @@ type
procedure ReadFonts(ANode: TDOMNode); procedure ReadFonts(ANode: TDOMNode);
procedure ReadNumFormats(ANode: TDOMNode); procedure ReadNumFormats(ANode: TDOMNode);
procedure ReadPalette(ANode: TDOMNode); procedure ReadPalette(ANode: TDOMNode);
procedure ReadRowHeight(ANode: TDOMNode; AWorksheet: TsWorksheet);
procedure ReadSharedStrings(ANode: TDOMNode); procedure ReadSharedStrings(ANode: TDOMNode);
procedure ReadSheetList(ANode: TDOMNode; AList: TStrings); procedure ReadSheetList(ANode: TDOMNode; AList: TStrings);
procedure ReadWorksheet(ANode: TDOMNode; AWorksheet: TsWorksheet); procedure ReadWorksheet(ANode: TDOMNode; AWorksheet: TsWorksheet);
@ -688,6 +690,35 @@ begin
end; end;
end; end;
procedure TsSpreadOOXMLReader.ReadCols(ANode: TDOMNode; AWorksheet: TsWorksheet);
var
colNode: TDOMNode;
col, col1, col2: Cardinal;
w: Double;
s: String;
begin
if ANode = nil then
exit;
colNode := ANode.FirstChild;
while Assigned(colNode) do begin
s := GetAttrValue(colNode, 'customWidth');
if s = '1' then begin
s := GetAttrValue(colNode, 'min');
if s <> '' then col1 := StrToInt(s)-1 else col1 := 0;
s := GetAttrValue(colNode, 'max');
if s <> '' then col2 := StrToInt(s)-1 else col2 := col1;
s := GetAttrValue(colNode, 'width');
if s <> '' then begin
w := StrToFloat(s, FPointSeparatorSettings);
for col := col1 to col2 do
FWorksheet.WriteColWidth(col, w);
end;
end;
colNode := colNode.NextSibling;
end;
end;
procedure TsSpreadOOXMLReader.ReadDateMode(ANode: TDOMNode); procedure TsSpreadOOXMLReader.ReadDateMode(ANode: TDOMNode);
var var
s: String; s: String;
@ -929,6 +960,30 @@ begin
FWorkbook.UsePalette(@pal[0], n); FWorkbook.UsePalette(@pal[0], n);
end; end;
procedure TsSpreadOOXMLReader.ReadRowHeight(ANode: TDOMNode; AWorksheet: TsWorksheet);
var
s: String;
ht: Single;
r: Cardinal;
row: PRow;
begin
if ANode = nil then
exit;
s := GetAttrValue(ANode, 'customHeight');
if s = '1' then begin
s := GetAttrValue(ANode, 'r');
r := StrToInt(s) - 1;
s := GetAttrValue(ANode, 'ht');
ht := StrToFloat(s, FPointSeparatorSettings); // seems to be in "Points"
row := FWorksheet.GetRow(r);
row^.Height := ht / FWorkbook.GetDefaultFontSize;
if row^.Height > ROW_HEIGHT_CORRECTION then
row^.Height := row^.Height - ROW_HEIGHT_CORRECTION
else
row^.Height := 0;
end;
end;
procedure TsSpreadOOXMLReader.ReadSharedStrings(ANode: TDOMNode); procedure TsSpreadOOXMLReader.ReadSharedStrings(ANode: TDOMNode);
var var
valuenode: TDOMNode; valuenode: TDOMNode;
@ -967,6 +1022,7 @@ begin
rownode := ANode.FirstChild; rownode := ANode.FirstChild;
while Assigned(rownode) do begin while Assigned(rownode) do begin
if rownode.NodeName = 'row' then begin if rownode.NodeName = 'row' then begin
ReadRowHeight(rownode, AWorksheet);
cellnode := rownode.FirstChild; cellnode := rownode.FirstChild;
while Assigned(cellnode) do begin while Assigned(cellnode) do begin
if cellnode.NodeName = 'c' then if cellnode.NodeName = 'c' then
@ -1068,6 +1124,7 @@ begin
FWorksheet := AData.AddWorksheet(SheetList[i]); FWorksheet := AData.AddWorksheet(SheetList[i]);
ReadCols(Doc.DocumentElement.FindNode('cols'), FWorksheet);
ReadWorksheet(Doc.DocumentElement.FindNode('sheetData'), FWorksheet); ReadWorksheet(Doc.DocumentElement.FindNode('sheetData'), FWorksheet);
FreeAndNil(Doc); FreeAndNil(Doc);