You've already forked lazarus-ccr
fpspreadsheet: Read ods formula and display it in TsWorksheetGrid.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3152 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -4,7 +4,7 @@ object Form1: TForm1
|
||||
Top = 248
|
||||
Width = 884
|
||||
Caption = 'fpsGrid'
|
||||
ClientHeight = 629
|
||||
ClientHeight = 624
|
||||
ClientWidth = 884
|
||||
Menu = MainMenu
|
||||
OnActivate = FormActivate
|
||||
@ -14,7 +14,7 @@ object Form1: TForm1
|
||||
object Panel1: TPanel
|
||||
Left = 0
|
||||
Height = 85
|
||||
Top = 544
|
||||
Top = 539
|
||||
Width = 884
|
||||
Align = alBottom
|
||||
BevelOuter = bvNone
|
||||
@ -23,9 +23,9 @@ object Form1: TForm1
|
||||
TabOrder = 0
|
||||
object CbShowHeaders: TCheckBox
|
||||
Left = 8
|
||||
Height = 19
|
||||
Height = 24
|
||||
Top = 8
|
||||
Width = 93
|
||||
Width = 116
|
||||
Caption = 'Show headers'
|
||||
Checked = True
|
||||
OnClick = CbShowHeadersClick
|
||||
@ -34,9 +34,9 @@ object Form1: TForm1
|
||||
end
|
||||
object CbShowGridLines: TCheckBox
|
||||
Left = 8
|
||||
Height = 19
|
||||
Height = 24
|
||||
Top = 32
|
||||
Width = 100
|
||||
Width = 125
|
||||
Caption = 'Show grid lines'
|
||||
Checked = True
|
||||
OnClick = CbShowGridLinesClick
|
||||
@ -45,7 +45,7 @@ object Form1: TForm1
|
||||
end
|
||||
object EdFrozenCols: TSpinEdit
|
||||
Left = 389
|
||||
Height = 23
|
||||
Height = 28
|
||||
Top = 8
|
||||
Width = 52
|
||||
OnChange = EdFrozenColsChange
|
||||
@ -53,7 +53,7 @@ object Form1: TForm1
|
||||
end
|
||||
object EdFrozenRows: TSpinEdit
|
||||
Left = 389
|
||||
Height = 23
|
||||
Height = 28
|
||||
Top = 39
|
||||
Width = 52
|
||||
OnChange = EdFrozenRowsChange
|
||||
@ -61,37 +61,37 @@ object Form1: TForm1
|
||||
end
|
||||
object Label1: TLabel
|
||||
Left = 304
|
||||
Height = 15
|
||||
Height = 20
|
||||
Top = 13
|
||||
Width = 62
|
||||
Width = 77
|
||||
Caption = 'Frozen cols:'
|
||||
FocusControl = EdFrozenCols
|
||||
ParentColor = False
|
||||
end
|
||||
object Label2: TLabel
|
||||
Left = 304
|
||||
Height = 15
|
||||
Height = 20
|
||||
Top = 40
|
||||
Width = 66
|
||||
Width = 82
|
||||
Caption = 'Frozen rows:'
|
||||
FocusControl = EdFrozenRows
|
||||
ParentColor = False
|
||||
end
|
||||
object CbReadFormulas: TCheckBox
|
||||
Left = 8
|
||||
Height = 19
|
||||
Height = 24
|
||||
Top = 56
|
||||
Width = 96
|
||||
Width = 120
|
||||
Caption = 'Read formulas'
|
||||
OnChange = CbReadFormulasChange
|
||||
TabOrder = 4
|
||||
end
|
||||
object CbHeaderStyle: TComboBox
|
||||
Left = 152
|
||||
Height = 23
|
||||
Height = 28
|
||||
Top = 8
|
||||
Width = 116
|
||||
ItemHeight = 15
|
||||
ItemHeight = 20
|
||||
ItemIndex = 2
|
||||
Items.Strings = (
|
||||
'Lazarus'
|
||||
@ -106,7 +106,7 @@ object Form1: TForm1
|
||||
end
|
||||
object PageControl1: TPageControl
|
||||
Left = 0
|
||||
Height = 465
|
||||
Height = 460
|
||||
Top = 79
|
||||
Width = 884
|
||||
ActivePage = TabSheet1
|
||||
@ -116,11 +116,11 @@ object Form1: TForm1
|
||||
OnChange = PageControl1Change
|
||||
object TabSheet1: TTabSheet
|
||||
Caption = 'Sheet1'
|
||||
ClientHeight = 437
|
||||
ClientHeight = 427
|
||||
ClientWidth = 876
|
||||
object WorksheetGrid: TsWorksheetGrid
|
||||
Left = 0
|
||||
Height = 437
|
||||
Height = 427
|
||||
Top = 0
|
||||
Width = 876
|
||||
FrozenCols = 0
|
||||
@ -136,7 +136,7 @@ object Form1: TForm1
|
||||
TitleStyle = tsNative
|
||||
OnSelection = WorksheetGridSelection
|
||||
ColWidths = (
|
||||
42
|
||||
56
|
||||
64
|
||||
64
|
||||
64
|
||||
@ -244,19 +244,19 @@ object Form1: TForm1
|
||||
end
|
||||
object FontComboBox: TComboBox
|
||||
Left = 52
|
||||
Height = 23
|
||||
Height = 28
|
||||
Top = 2
|
||||
Width = 127
|
||||
ItemHeight = 15
|
||||
ItemHeight = 20
|
||||
OnSelect = FontComboBoxSelect
|
||||
TabOrder = 0
|
||||
end
|
||||
object FontSizeComboBox: TComboBox
|
||||
Left = 179
|
||||
Height = 23
|
||||
Height = 28
|
||||
Top = 2
|
||||
Width = 48
|
||||
ItemHeight = 15
|
||||
ItemHeight = 20
|
||||
Items.Strings = (
|
||||
'8'
|
||||
'9'
|
||||
|
@ -753,6 +753,7 @@ procedure TForm1.WorksheetGridSelection(Sender: TObject; aCol, aRow: Integer);
|
||||
var
|
||||
r, c: Cardinal;
|
||||
cell: PCell;
|
||||
s: String;
|
||||
begin
|
||||
if WorksheetGrid.Workbook = nil then
|
||||
exit;
|
||||
@ -767,8 +768,9 @@ begin
|
||||
|
||||
cell := WorksheetGrid.Worksheet.FindCell(r, c);
|
||||
if cell <> nil then begin
|
||||
if Length(cell^.RPNFormulaValue) > 0 then
|
||||
EdFormula.Text := WorksheetGrid.Worksheet.ReadRPNFormulaAsString(cell)
|
||||
s := WorksheetGrid.Worksheet.ReadFormulaAsString(cell);
|
||||
if s <> '' then
|
||||
EdFormula.Text := s
|
||||
else
|
||||
EdFormula.Text := WorksheetGrid.Worksheet.ReadAsUTF8Text(cell);
|
||||
end else
|
||||
|
@ -884,9 +884,60 @@ begin
|
||||
end;
|
||||
|
||||
procedure TsSpreadOpenDocReader.ReadFormula(ARow: Word; ACol : Word; ACellNode : TDOMNode);
|
||||
var
|
||||
cell: PCell;
|
||||
formula: String;
|
||||
stylename: String;
|
||||
txtValue: String;
|
||||
floatValue: Double;
|
||||
fs: TFormatSettings;
|
||||
valueType: String;
|
||||
valueStr: String;
|
||||
begin
|
||||
// For now just read the number
|
||||
ReadNumber(ARow, ACol, ACellNode);
|
||||
fs := DefaultFormatSettings;
|
||||
fs.DecimalSeparator := '.';
|
||||
|
||||
// Create cell and apply format
|
||||
styleName := GetAttrValue(ACellNode, 'table:style-name');
|
||||
ApplyStyleToCell(ARow, ACol, stylename);
|
||||
cell := FWorksheet.FindCell(ARow, ACol);
|
||||
|
||||
// Read formula, store in the cell's FormulaValue.FormulaStr
|
||||
formula := GetAttrValue(ACellNode, 'table:formula');
|
||||
if formula <> '' then Delete(formula, 1, 3); // delete "of:"
|
||||
cell^.FormulaValue.FormulaStr := formula;
|
||||
|
||||
// Read formula results
|
||||
// ... number value
|
||||
valueType := GetAttrValue(ACellNode, 'office:value-type');
|
||||
valueStr := GetAttrValue(ACellNode, 'office:value');
|
||||
if (valueType = 'float') then begin
|
||||
if UpperCase(valueStr) = '1.#INF' then
|
||||
FWorksheet.WriteNumber(cell, 1.0/0.0)
|
||||
else begin
|
||||
floatValue := StrToFloat(valueStr, fs);
|
||||
FWorksheet.WriteNumber(cell, floatValue);
|
||||
end;
|
||||
if IsDateTimeFormat(cell^.NumberFormat) then begin
|
||||
cell^.ContentType := cctDateTime;
|
||||
// No datemode correction for intervals and for time-only values
|
||||
if (cell^.NumberFormat = nfTimeInterval) or (cell^.NumberValue < 1) then
|
||||
cell^.DateTimeValue := cell^.NumberValue
|
||||
else
|
||||
case FDateMode of
|
||||
dm1899: cell^.DateTimeValue := cell^.NumberValue + DATEMODE_1899_BASE;
|
||||
dm1900: cell^.DateTimeValue := cell^.NumberValue + DATEMODE_1900_BASE;
|
||||
dm1904: cell^.DateTimeValue := cell^.NumberValue + DATEMODE_1904_BASE;
|
||||
end;
|
||||
end;
|
||||
end else
|
||||
// Date/time value
|
||||
if (valueType = 'date') or (valueType = 'time') then begin
|
||||
floatValue := ExtractDateTimeFromNode(ACellNode, cell^.NumberFormat, cell^.NumberFormatStr);
|
||||
FWorkSheet.WriteDateTime(cell, floatValue);
|
||||
end else
|
||||
// Text
|
||||
FWorksheet.WriteUTF8Text(cell, valueStr);
|
||||
end;
|
||||
|
||||
procedure TsSpreadOpenDocReader.ReadLabel(ARow: Word; ACol: Word; ACellNode: TDOMNode);
|
||||
@ -1336,9 +1387,11 @@ begin
|
||||
else if (paramValueType = 'date') or (paramValueType = 'time') then
|
||||
ReadDateTime(row, col, cellNode)
|
||||
else if (paramValueType = '') and (tableStyleName <> '') then
|
||||
ReadBlank(row, col, cellNode)
|
||||
else if ParamFormula <> '' then
|
||||
ReadLabel(row, col, cellNode);
|
||||
ReadBlank(row, col, cellNode);
|
||||
|
||||
if ParamFormula <> '' then
|
||||
ReadFormula(row, col, cellNode);
|
||||
// ReadLabel(row, col, cellNode);
|
||||
|
||||
paramColsRepeated := GetAttrValue(cellNode, 'table:number-columns-repeated');
|
||||
if paramColsRepeated = '' then paramColsRepeated := '1';
|
||||
|
@ -416,6 +416,7 @@ type
|
||||
function ReadAsUTF8Text(ACell: PCell): ansistring; overload;
|
||||
function ReadAsNumber(ARow, ACol: Cardinal): Double;
|
||||
function ReadAsDateTime(ARow, ACol: Cardinal; out AResult: TDateTime): Boolean;
|
||||
function ReadFormulaAsString(ACell: PCell): String;
|
||||
function ReadRPNFormulaAsString(ACell: PCell): String;
|
||||
function ReadUsedFormatting(ARow, ACol: Cardinal): TsUsedFormattingFields;
|
||||
function ReadBackgroundColor(ARow, ACol: Cardinal): TsColor;
|
||||
@ -440,7 +441,8 @@ type
|
||||
procedure WriteNumber(ARow, ACol: Cardinal; ANumber: double;
|
||||
AFormatString: String); overload;
|
||||
procedure WriteRPNFormula(ARow, ACol: Cardinal; AFormula: TsRPNFormula);
|
||||
procedure WriteUTF8Text(ARow, ACol: Cardinal; AText: ansistring);
|
||||
procedure WriteUTF8Text(ARow, ACol: Cardinal; AText: ansistring); overload;
|
||||
procedure WriteUTF8Text(ACell: PCell; AText: ansistring); overload;
|
||||
|
||||
{ Writing of cell attributes }
|
||||
procedure WriteBackgroundColor(ARow, ACol: Cardinal; AColor: TsColor);
|
||||
@ -1628,6 +1630,17 @@ begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TsWorksheet.ReadFormulaAsString(ACell: PCell): String;
|
||||
begin
|
||||
Result := '';
|
||||
if ACell = nil then
|
||||
exit;
|
||||
if Length(ACell^.RPNFormulaValue) > 0 then
|
||||
Result := ReadRPNFormulaAsString(ACell)
|
||||
else
|
||||
Result := ACell^.FormulaValue.FormulaStr;
|
||||
end;
|
||||
|
||||
function TsWorksheet.ReadRPNFormulaAsString(ACell: PCell): String;
|
||||
var
|
||||
fs: TFormatSettings;
|
||||
@ -1803,9 +1816,16 @@ var
|
||||
ACell: PCell;
|
||||
begin
|
||||
ACell := GetCell(ARow, ACol);
|
||||
WriteUTF8Text(ACell, AText);
|
||||
end;
|
||||
|
||||
procedure TsWorksheet.WriteUTF8Text(ACell: PCell; AText: ansistring);
|
||||
begin
|
||||
if ACell = nil then
|
||||
exit;
|
||||
ACell^.ContentType := cctUTF8String;
|
||||
ACell^.UTF8StringValue := AText;
|
||||
ChangedCell(ARow, ACol);
|
||||
ChangedCell(ACell^.Row, ACell^.Col);
|
||||
end;
|
||||
|
||||
{@@
|
||||
|
@ -340,7 +340,6 @@ begin
|
||||
TestWriteReadFont(sfExcel8, 'Courier New');
|
||||
end;
|
||||
|
||||
|
||||
{ ODS }
|
||||
procedure TSpreadWriteReadFontTests.TestWriteRead_ODS_Font_Arial;
|
||||
begin
|
||||
|
Reference in New Issue
Block a user