You've already forked lazarus-ccr
Improves FPSpreadsheet examples and improves the Grid component
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1229 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
<Version Value="7"/>
|
<Version Value="7"/>
|
||||||
<General>
|
<General>
|
||||||
<Flags>
|
<Flags>
|
||||||
|
<AlwaysBuild Value="False"/>
|
||||||
<UseDefaultCompilerOptions Value="True"/>
|
<UseDefaultCompilerOptions Value="True"/>
|
||||||
</Flags>
|
</Flags>
|
||||||
<SessionStorage Value="InProjectDir"/>
|
<SessionStorage Value="InProjectDir"/>
|
||||||
@@ -72,6 +73,9 @@
|
|||||||
</SyntaxOptions>
|
</SyntaxOptions>
|
||||||
</Parsing>
|
</Parsing>
|
||||||
<Linking>
|
<Linking>
|
||||||
|
<Debugging>
|
||||||
|
<GenerateDebugInfo Value="True"/>
|
||||||
|
</Debugging>
|
||||||
<Options>
|
<Options>
|
||||||
<Win32>
|
<Win32>
|
||||||
<GraphicApplication Value="True"/>
|
<GraphicApplication Value="True"/>
|
||||||
@@ -79,6 +83,9 @@
|
|||||||
</Options>
|
</Options>
|
||||||
</Linking>
|
</Linking>
|
||||||
<Other>
|
<Other>
|
||||||
|
<CompilerMessages>
|
||||||
|
<UseMsgFile Value="True"/>
|
||||||
|
</CompilerMessages>
|
||||||
<CompilerPath Value="$(CompPath)"/>
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
</Other>
|
</Other>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
|
@@ -13,7 +13,6 @@ uses
|
|||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Application.Title:='project1';
|
|
||||||
Application.Initialize;
|
Application.Initialize;
|
||||||
Application.CreateForm(TFPSChartForm, FPSChartForm);
|
Application.CreateForm(TFPSChartForm, FPSChartForm);
|
||||||
Application.Run;
|
Application.Run;
|
||||||
|
@@ -1,16 +1,17 @@
|
|||||||
object FPSChartForm: TFPSChartForm
|
object FPSChartForm: TFPSChartForm
|
||||||
Left = 179
|
Left = 239
|
||||||
Height = 331
|
Height = 382
|
||||||
Top = 157
|
Top = 154
|
||||||
Width = 742
|
Width = 700
|
||||||
Caption = 'FPSpreadsheet Chart Example'
|
Caption = 'FPSpreadsheet Chart Example'
|
||||||
ClientHeight = 331
|
ClientHeight = 382
|
||||||
ClientWidth = 742
|
ClientWidth = 700
|
||||||
|
OnCreate = FormCreate
|
||||||
LCLVersion = '0.9.29'
|
LCLVersion = '0.9.29'
|
||||||
object MyChart: TChart
|
object MyChart: TChart
|
||||||
Left = 400
|
Left = 352
|
||||||
Height = 240
|
Height = 240
|
||||||
Top = 24
|
Top = 136
|
||||||
Width = 336
|
Width = 336
|
||||||
AxisList = <
|
AxisList = <
|
||||||
item
|
item
|
||||||
@@ -37,26 +38,106 @@ object FPSChartForm: TFPSChartForm
|
|||||||
object WorksheetGrid: TsWorksheetGrid
|
object WorksheetGrid: TsWorksheetGrid
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 240
|
Height = 240
|
||||||
Top = 24
|
Top = 136
|
||||||
Width = 360
|
Width = 328
|
||||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goEditing, goSmoothScroll]
|
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goEditing, goSmoothScroll]
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
end
|
end
|
||||||
object btnCreateGraphic: TButton
|
object btnCreateGraphic: TButton
|
||||||
Left = 104
|
Left = 464
|
||||||
Height = 25
|
Height = 25
|
||||||
Top = 280
|
Top = 56
|
||||||
Width = 128
|
Width = 128
|
||||||
Caption = 'Create Graphic'
|
Caption = 'Create Graphic'
|
||||||
OnClick = btnCreateGraphicClick
|
OnClick = btnCreateGraphicClick
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
end
|
end
|
||||||
|
object Label1: TLabel
|
||||||
|
Left = 16
|
||||||
|
Height = 34
|
||||||
|
Top = 8
|
||||||
|
Width = 676
|
||||||
|
AutoSize = False
|
||||||
|
Caption = 'Please add data to the grid or load it from a file, then choose the location of the data for the X and Y axises and click on the button "Create Graphic" to generate a chart.'
|
||||||
|
ParentColor = False
|
||||||
|
WordWrap = True
|
||||||
|
end
|
||||||
|
object editSourceFile: TFileNameEdit
|
||||||
|
Left = 152
|
||||||
|
Height = 22
|
||||||
|
Top = 48
|
||||||
|
Width = 136
|
||||||
|
DialogOptions = []
|
||||||
|
FilterIndex = 0
|
||||||
|
HideDirectories = False
|
||||||
|
ButtonWidth = 23
|
||||||
|
NumGlyphs = 0
|
||||||
|
MaxLength = 0
|
||||||
|
TabOrder = 3
|
||||||
|
end
|
||||||
|
object Label2: TLabel
|
||||||
|
Left = 14
|
||||||
|
Height = 18
|
||||||
|
Top = 51
|
||||||
|
Width = 130
|
||||||
|
Caption = 'Source Spreadsheet:'
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
object btnLoadSpreadsheet: TButton
|
||||||
|
Left = 320
|
||||||
|
Height = 25
|
||||||
|
Top = 48
|
||||||
|
Width = 75
|
||||||
|
Caption = 'Load'
|
||||||
|
OnClick = btnLoadSpreadsheetClick
|
||||||
|
TabOrder = 4
|
||||||
|
end
|
||||||
|
object editXAxis: TLabeledEdit
|
||||||
|
Left = 64
|
||||||
|
Height = 22
|
||||||
|
Top = 80
|
||||||
|
Width = 80
|
||||||
|
EditLabel.AnchorSideLeft.Control = editXAxis
|
||||||
|
EditLabel.AnchorSideTop.Control = editXAxis
|
||||||
|
EditLabel.AnchorSideTop.Side = asrCenter
|
||||||
|
EditLabel.AnchorSideRight.Control = editXAxis
|
||||||
|
EditLabel.AnchorSideBottom.Control = editXAxis
|
||||||
|
EditLabel.Left = 17
|
||||||
|
EditLabel.Height = 18
|
||||||
|
EditLabel.Top = 82
|
||||||
|
EditLabel.Width = 44
|
||||||
|
EditLabel.Caption = 'X-Axis:'
|
||||||
|
EditLabel.ParentColor = False
|
||||||
|
LabelPosition = lpLeft
|
||||||
|
TabOrder = 5
|
||||||
|
Text = 'A1:A5'
|
||||||
|
end
|
||||||
|
object EditYAxis: TLabeledEdit
|
||||||
|
Left = 208
|
||||||
|
Height = 22
|
||||||
|
Top = 80
|
||||||
|
Width = 80
|
||||||
|
EditLabel.AnchorSideLeft.Control = EditYAxis
|
||||||
|
EditLabel.AnchorSideTop.Control = EditYAxis
|
||||||
|
EditLabel.AnchorSideTop.Side = asrCenter
|
||||||
|
EditLabel.AnchorSideRight.Control = EditYAxis
|
||||||
|
EditLabel.AnchorSideBottom.Control = EditYAxis
|
||||||
|
EditLabel.Left = 161
|
||||||
|
EditLabel.Height = 18
|
||||||
|
EditLabel.Top = 82
|
||||||
|
EditLabel.Width = 44
|
||||||
|
EditLabel.Caption = 'Y-Axis:'
|
||||||
|
EditLabel.ParentColor = False
|
||||||
|
LabelPosition = lpLeft
|
||||||
|
TabOrder = 6
|
||||||
|
Text = 'B1:B5'
|
||||||
|
end
|
||||||
object FPSChartSource: TsWorksheetChartSource
|
object FPSChartSource: TsWorksheetChartSource
|
||||||
PointsNumber = 5
|
PointsNumber = 5
|
||||||
YFirstCellCol = 1
|
YFirstCellCol = 1
|
||||||
XSelectionDirection = fpsVerticalSelection
|
XSelectionDirection = fpsVerticalSelection
|
||||||
YSelectionDirection = fpsVerticalSelection
|
YSelectionDirection = fpsVerticalSelection
|
||||||
left = 376
|
left = 632
|
||||||
top = 264
|
top = 56
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@@ -6,7 +6,8 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
||||||
StdCtrls, Grids, fpspreadsheetchart, fpspreadsheetgrid, TAGraph, TASeries;
|
StdCtrls, Grids, EditBtn, ExtCtrls, fpspreadsheetchart, fpspreadsheetgrid,
|
||||||
|
TAGraph, TASeries;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@@ -14,11 +15,19 @@ type
|
|||||||
|
|
||||||
TFPSChartForm = class(TForm)
|
TFPSChartForm = class(TForm)
|
||||||
btnCreateGraphic: TButton;
|
btnCreateGraphic: TButton;
|
||||||
|
btnLoadSpreadsheet: TButton;
|
||||||
|
editSourceFile: TFileNameEdit;
|
||||||
|
Label1: TLabel;
|
||||||
|
Label2: TLabel;
|
||||||
|
editXAxis: TLabeledEdit;
|
||||||
|
EditYAxis: TLabeledEdit;
|
||||||
MyChart: TChart;
|
MyChart: TChart;
|
||||||
FPSChartSource: TsWorksheetChartSource;
|
FPSChartSource: TsWorksheetChartSource;
|
||||||
MyChartLineSeries: TLineSeries;
|
MyChartLineSeries: TLineSeries;
|
||||||
WorksheetGrid: TsWorksheetGrid;
|
WorksheetGrid: TsWorksheetGrid;
|
||||||
procedure btnCreateGraphicClick(Sender: TObject);
|
procedure btnCreateGraphicClick(Sender: TObject);
|
||||||
|
procedure btnLoadSpreadsheetClick(Sender: TObject);
|
||||||
|
procedure FormCreate(Sender: TObject);
|
||||||
private
|
private
|
||||||
{ private declarations }
|
{ private declarations }
|
||||||
public
|
public
|
||||||
@@ -30,14 +39,40 @@ var
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
// FPSpreadsheet and supported formats
|
||||||
|
fpspreadsheet, xlsbiff8, xlsbiff5, xlsbiff2, xlsxooxml, fpsopendocument;
|
||||||
|
|
||||||
{$R *.lfm}
|
{$R *.lfm}
|
||||||
|
|
||||||
{ TFPSChartForm }
|
{ TFPSChartForm }
|
||||||
|
|
||||||
procedure TFPSChartForm.btnCreateGraphicClick(Sender: TObject);
|
procedure TFPSChartForm.btnCreateGraphicClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
|
FPSChartSource.LoadPropertiesFromStrings(editXAxis.Text, editYAxis.Text, '', '', '');
|
||||||
FPSChartSource.LoadFromWorksheetGrid(WorksheetGrid);
|
FPSChartSource.LoadFromWorksheetGrid(WorksheetGrid);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TFPSChartForm.btnLoadSpreadsheetClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
Format: TsSpreadsheetFormat;
|
||||||
|
lExt: string;
|
||||||
|
begin
|
||||||
|
// First some logic to detect the format from the extension
|
||||||
|
lExt := ExtractFileExt(editSourceFile.Text);
|
||||||
|
if lExt = STR_EXCEL_EXTENSION then Format := sfExcel2
|
||||||
|
else if lExt = STR_OOXML_EXCEL_EXTENSION then Format := sfOOXML
|
||||||
|
else if lExt = STR_OPENDOCUMENT_CALC_EXTENSION then Format := sfOpenDocument
|
||||||
|
else raise Exception.Create('Invalid File Extension');
|
||||||
|
|
||||||
|
// Now the actual loading
|
||||||
|
WorksheetGrid.LoadFromSpreadsheetFile(editSourceFile.Text, Format);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPSChartForm.FormCreate(Sender: TObject);
|
||||||
|
begin
|
||||||
|
editSourceFile.InitialDir := ExtractFilePath(ParamStr(0));
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
BIN
components/fpspreadsheet/examples/fpschart/t1.xls
Normal file
BIN
components/fpspreadsheet/examples/fpschart/t1.xls
Normal file
Binary file not shown.
BIN
components/fpspreadsheet/examples/fpschart/t2.ods
Normal file
BIN
components/fpspreadsheet/examples/fpschart/t2.ods
Normal file
Binary file not shown.
@@ -189,7 +189,8 @@ begin
|
|||||||
|
|
||||||
//process each cell of the row
|
//process each cell of the row
|
||||||
CellNode:=RowNode.FindNode('table:table-cell');
|
CellNode:=RowNode.FindNode('table:table-cell');
|
||||||
while Assigned(CellNode) do begin
|
while Assigned(CellNode) do
|
||||||
|
begin
|
||||||
ParamColsRepeated:=GetAttrValue(CellNode,'table:number-columns-repeated');
|
ParamColsRepeated:=GetAttrValue(CellNode,'table:number-columns-repeated');
|
||||||
if ParamColsRepeated='' then ParamColsRepeated:='1';
|
if ParamColsRepeated='' then ParamColsRepeated:='1';
|
||||||
|
|
||||||
@@ -200,11 +201,9 @@ begin
|
|||||||
for ColsCount:=0 to StrToInt(ParamColsRepeated)-1 do begin
|
for ColsCount:=0 to StrToInt(ParamColsRepeated)-1 do begin
|
||||||
if ParamValueType='string' then
|
if ParamValueType='string' then
|
||||||
ReadLabel(Row+RowsCount,Col+ColsCount,CellNode)
|
ReadLabel(Row+RowsCount,Col+ColsCount,CellNode)
|
||||||
else
|
else if ParamFormula<>'' then
|
||||||
if ParamFormula<>'' then
|
|
||||||
ReadFormula(Row+RowsCount,Col+ColsCount,CellNode)
|
ReadFormula(Row+RowsCount,Col+ColsCount,CellNode)
|
||||||
else
|
else if ParamValueType='float' then
|
||||||
if ParamValueType='float' then
|
|
||||||
ReadNumber(Row+RowsCount,Col+ColsCount,CellNode);
|
ReadNumber(Row+RowsCount,Col+ColsCount,CellNode);
|
||||||
end; //for ColsCount
|
end; //for ColsCount
|
||||||
end; //for RowsCount
|
end; //for RowsCount
|
||||||
@@ -226,7 +225,8 @@ end;
|
|||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadFormula(ARow: Word; ACol : Word; ACellNode : TDOMNode);
|
procedure TsSpreadOpenDocReader.ReadFormula(ARow: Word; ACol : Word; ACellNode : TDOMNode);
|
||||||
begin
|
begin
|
||||||
|
// For now just read the number
|
||||||
|
ReadNumber(ARow, ACol, ACellNode);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadOpenDocReader.ReadLabel(ARow: Word; ACol : Word; ACellNode : TDOMNode);
|
procedure TsSpreadOpenDocReader.ReadLabel(ARow: Word; ACol : Word; ACellNode : TDOMNode);
|
||||||
@@ -237,14 +237,21 @@ end;
|
|||||||
procedure TsSpreadOpenDocReader.ReadNumber(ARow: Word; ACol : Word; ACellNode : TDOMNode);
|
procedure TsSpreadOpenDocReader.ReadNumber(ARow: Word; ACol : Word; ACellNode : TDOMNode);
|
||||||
var
|
var
|
||||||
FSettings: TFormatSettings;
|
FSettings: TFormatSettings;
|
||||||
Value: String;
|
Value, Str: String;
|
||||||
|
lNumber: Double;
|
||||||
begin
|
begin
|
||||||
FSettings.DecimalSeparator:='.';
|
FSettings.DecimalSeparator:='.';
|
||||||
Value:=GetAttrValue(ACellNode,'office:value');
|
Value:=GetAttrValue(ACellNode,'office:value');
|
||||||
if UpperCase(Value)='1.#INF' then begin
|
if UpperCase(Value)='1.#INF' then
|
||||||
|
begin
|
||||||
FWorkSheet.WriteNumber(Arow,ACol,1.0/0.0);
|
FWorkSheet.WriteNumber(Arow,ACol,1.0/0.0);
|
||||||
end else begin
|
end
|
||||||
FWorkSheet.WriteNumber(Arow,ACol,StrToFloat(GetAttrValue(ACellNode,'office:value'),FSettings));
|
else
|
||||||
|
begin
|
||||||
|
// Don't merge, or else we can't debug
|
||||||
|
Str := GetAttrValue(ACellNode,'office:value');
|
||||||
|
lNumber := StrToFloat(Str,FSettings);
|
||||||
|
FWorkSheet.WriteNumber(Arow,ACol,lNumber);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@@ -74,7 +74,14 @@ type
|
|||||||
|
|
||||||
TCellContentType = (cctEmpty, cctFormula, cctRPNFormula, cctNumber, cctUTF8String);
|
TCellContentType = (cctEmpty, cctFormula, cctRPNFormula, cctNumber, cctUTF8String);
|
||||||
|
|
||||||
{@@ Cell structure for TsWorksheet }
|
{@@ Cell structure for TsWorksheet
|
||||||
|
|
||||||
|
Never suppose that all *Value fields are valid,
|
||||||
|
only one of the ContentTypes is valid. For other fields
|
||||||
|
use TWorksheet.ReadAsUTF8Text and similar methods
|
||||||
|
|
||||||
|
@see TWorksheet.ReadAsUTF8Text
|
||||||
|
}
|
||||||
|
|
||||||
TCell = record
|
TCell = record
|
||||||
Col: Byte; // zero-based
|
Col: Byte; // zero-based
|
||||||
@@ -211,6 +218,8 @@ procedure RegisterSpreadFormat(
|
|||||||
AWriterClass: TsSpreadWriterClass;
|
AWriterClass: TsSpreadWriterClass;
|
||||||
AFormat: TsSpreadsheetFormat);
|
AFormat: TsSpreadsheetFormat);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
@@ -19,12 +19,10 @@ uses
|
|||||||
// FPSpreadsheet Visual
|
// FPSpreadsheet Visual
|
||||||
fpspreadsheetgrid,
|
fpspreadsheetgrid,
|
||||||
// FPSpreadsheet
|
// FPSpreadsheet
|
||||||
fpspreadsheet;
|
fpspreadsheet, fpsutils;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
TsSelectionDirection = (fpsVerticalSelection, fpsHorizontalSelection);
|
|
||||||
|
|
||||||
{@@ Chart data source designed to work together with TChart from Lazarus
|
{@@ Chart data source designed to work together with TChart from Lazarus
|
||||||
to display the data.
|
to display the data.
|
||||||
|
|
||||||
@@ -60,6 +58,7 @@ type
|
|||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure LoadFromWorksheetGrid(const AValue: TsWorksheetGrid);
|
procedure LoadFromWorksheetGrid(const AValue: TsWorksheetGrid);
|
||||||
|
procedure LoadPropertiesFromStrings(AXInterval, AYInterval, AXTitle, AYTitle, ATitle: string);
|
||||||
public
|
public
|
||||||
published
|
published
|
||||||
// property WorksheetGrid: TsWorksheetGrid read FWorksheetGrid write SetWorksheetGrid;
|
// property WorksheetGrid: TsWorksheetGrid read FWorksheetGrid write SetWorksheetGrid;
|
||||||
@@ -205,4 +204,16 @@ begin
|
|||||||
Notify;
|
Notify;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsWorksheetChartSource.LoadPropertiesFromStrings(AXInterval,
|
||||||
|
AYInterval, AXTitle, AYTitle, ATitle: string);
|
||||||
|
var
|
||||||
|
lXCount, lYCount: Integer;
|
||||||
|
begin
|
||||||
|
ParseIntervalString(AXInterval, FXFirstCellRow, FXFirstCellCol, lXCount, FXSelectionDirection);
|
||||||
|
ParseIntervalString(AYInterval, FYFirstCellRow, FYFirstCellCol, lYCount, FYSelectionDirection);
|
||||||
|
if lXCount <> lYCount then raise Exception.Create(
|
||||||
|
'TsWorksheetChartSource.LoadPropertiesFromStrings: Interval sizes don''t match');
|
||||||
|
FPointsNumber := lXCount;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@@ -31,6 +31,7 @@ type
|
|||||||
{ methods }
|
{ methods }
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
procedure LoadFromWorksheet(AWorksheet: TsWorksheet);
|
procedure LoadFromWorksheet(AWorksheet: TsWorksheet);
|
||||||
|
procedure LoadFromSpreadsheetFile(AFileName: string; AFormat: TsSpreadsheetFormat; AWorksheetIndex: Integer = 0);
|
||||||
procedure SaveToWorksheet(AWorksheet: TsWorksheet);
|
procedure SaveToWorksheet(AWorksheet: TsWorksheet);
|
||||||
property DisplayFixedColRow: Boolean read FDisplayFixedColRow write SetDisplayFixedColRow;
|
property DisplayFixedColRow: Boolean read FDisplayFixedColRow write SetDisplayFixedColRow;
|
||||||
end;
|
end;
|
||||||
@@ -210,7 +211,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
lCol := lCell^.Col;
|
lCol := lCell^.Col;
|
||||||
lRow := lCell^.Row;
|
lRow := lCell^.Row;
|
||||||
lStr := lCell^.UTF8StringValue;
|
lStr := FWorksheet.ReadAsUTF8Text(lRow, lCol);
|
||||||
|
|
||||||
if DisplayFixedColRow then
|
if DisplayFixedColRow then
|
||||||
SetCells(lCol + 1, lRow + 1, lStr)
|
SetCells(lCol + 1, lRow + 1, lStr)
|
||||||
@@ -221,6 +222,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsCustomWorksheetGrid.LoadFromSpreadsheetFile(AFileName: string;
|
||||||
|
AFormat: TsSpreadsheetFormat; AWorksheetIndex: Integer);
|
||||||
|
var
|
||||||
|
lWorkbook: TsWorkbook;
|
||||||
|
begin
|
||||||
|
lWorkbook := TsWorkbook.Create;
|
||||||
|
try
|
||||||
|
lWorkbook.ReadFromFile(AFileName, AFormat);
|
||||||
|
LoadFromWorksheet(lWorkbook.GetWorksheetByIndex(AWorksheetIndex));
|
||||||
|
finally
|
||||||
|
lWorkbook.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TsCustomWorksheetGrid.SaveToWorksheet(AWorksheet: TsWorksheet);
|
procedure TsCustomWorksheetGrid.SaveToWorksheet(AWorksheet: TsWorksheet);
|
||||||
var
|
var
|
||||||
x, y: Integer;
|
x, y: Integer;
|
||||||
|
@@ -1,3 +1,6 @@
|
|||||||
|
{
|
||||||
|
Utility functions from FPSpreadsheet
|
||||||
|
}
|
||||||
unit fpsutils;
|
unit fpsutils;
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
@@ -5,8 +8,13 @@ unit fpsutils;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils;
|
Classes, SysUtils, StrUtils;
|
||||||
|
|
||||||
|
// Exported types
|
||||||
|
type
|
||||||
|
TsSelectionDirection = (fpsVerticalSelection, fpsHorizontalSelection);
|
||||||
|
|
||||||
|
// Endianess helper functions
|
||||||
function WordToLE(AValue: Word): Word;
|
function WordToLE(AValue: Word): Word;
|
||||||
function DWordToLE(AValue: Cardinal): Cardinal;
|
function DWordToLE(AValue: Cardinal): Cardinal;
|
||||||
function IntegerToLE(AValue: Integer): Integer;
|
function IntegerToLE(AValue: Integer): Integer;
|
||||||
@@ -16,6 +24,17 @@ function WordLEtoN(AValue: Word): Word;
|
|||||||
function DWordLEtoN(AValue: Cardinal): Cardinal;
|
function DWordLEtoN(AValue: Cardinal): Cardinal;
|
||||||
function WideStringLEToN(const AValue: WideString): WideString;
|
function WideStringLEToN(const AValue: WideString): WideString;
|
||||||
|
|
||||||
|
// Other routines
|
||||||
|
function ParseIntervalString(const AStr: string;
|
||||||
|
var AFirstCellRow, AFirstCellCol, ACount: Integer;
|
||||||
|
var ADirection: TsSelectionDirection): Boolean;
|
||||||
|
function ParseCellString(const AStr: string;
|
||||||
|
var ACellRow, ACellCol: Integer): Boolean;
|
||||||
|
function ParseCellRowString(const AStr: string;
|
||||||
|
var AResult: Integer): Boolean;
|
||||||
|
function ParseCellColString(const AStr: string;
|
||||||
|
var AResult: Integer): Boolean;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -114,5 +133,136 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@
|
||||||
|
Parses strings like A5:A10 into an selection interval information
|
||||||
|
}
|
||||||
|
function ParseIntervalString(const AStr: string;
|
||||||
|
var AFirstCellRow, AFirstCellCol, ACount: Integer;
|
||||||
|
var ADirection: TsSelectionDirection): Boolean;
|
||||||
|
var
|
||||||
|
Cells: TStringList;
|
||||||
|
LastCellRow, LastCellCol: Integer;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
|
||||||
|
// First get the cells
|
||||||
|
Cells := TStringList.Create;
|
||||||
|
ExtractStrings([':'],[], PChar(AStr), Cells);
|
||||||
|
|
||||||
|
// Then parse each of them
|
||||||
|
Result := ParseCellString(Cells[0], AFirstCellRow, AFirstCellCol);
|
||||||
|
if not Result then Exit;
|
||||||
|
Result := ParseCellString(Cells[1], LastCellRow, LastCellCol);
|
||||||
|
if not Result then Exit;
|
||||||
|
|
||||||
|
if AFirstCellRow = LastCellRow then
|
||||||
|
begin
|
||||||
|
ADirection := fpsHorizontalSelection;
|
||||||
|
ACount := LastCellCol - AFirstCellCol + 1;
|
||||||
|
end
|
||||||
|
else if AFirstCellCol = LastCellCol then
|
||||||
|
begin
|
||||||
|
ADirection := fpsVerticalSelection;
|
||||||
|
ACount := LastCellRow - AFirstCellRow + 1;
|
||||||
|
end
|
||||||
|
else Exit(False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@
|
||||||
|
Parses a cell string, like 'A1' into zero-based column and row numbers
|
||||||
|
|
||||||
|
The parser is a simple state machine, with the following states:
|
||||||
|
|
||||||
|
0 - Reading Column part 1 (necesserely needs a letter)
|
||||||
|
1 - Reading Column part 2, but could be the first number as well
|
||||||
|
2 - Reading Row
|
||||||
|
}
|
||||||
|
function ParseCellString(const AStr: string; var ACellRow, ACellCol: Integer): Boolean;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
state: Integer;
|
||||||
|
Col, Row: string;
|
||||||
|
lChar: Char;
|
||||||
|
const
|
||||||
|
cLetters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
||||||
|
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'W', 'X', 'Y', 'Z'];
|
||||||
|
cDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||||
|
begin
|
||||||
|
// Starting state
|
||||||
|
Result := True;
|
||||||
|
state := 0;
|
||||||
|
Col := '';
|
||||||
|
Row := '';
|
||||||
|
|
||||||
|
// Separates the string into a row and a col
|
||||||
|
for i := 0 to Length(AStr) - 1 do
|
||||||
|
begin
|
||||||
|
lChar := AStr[i + 1];
|
||||||
|
|
||||||
|
case state of
|
||||||
|
|
||||||
|
0:
|
||||||
|
begin
|
||||||
|
if lChar in cLetters then
|
||||||
|
begin
|
||||||
|
Col := lChar;
|
||||||
|
state := 1;
|
||||||
|
end
|
||||||
|
else Exit(False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
1:
|
||||||
|
begin
|
||||||
|
if lChar in cLetters then Col := Col + lChar
|
||||||
|
else if lChar in cDigits then
|
||||||
|
begin
|
||||||
|
Row := lChar;
|
||||||
|
state := 2;
|
||||||
|
end
|
||||||
|
else Exit(False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
2:
|
||||||
|
begin
|
||||||
|
if lChar in cDigits then Row := Row + lChar
|
||||||
|
else Exit(False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Now parses each separetely
|
||||||
|
ParseCellRowString(Row, ACellRow);
|
||||||
|
ParseCellColString(Col, ACellCol);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ParseCellRowString(const AStr: string; var AResult: Integer): Boolean;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
AResult := StrToInt(AStr) - 1;
|
||||||
|
except
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ParseCellColString(const AStr: string; var AResult: Integer): Boolean;
|
||||||
|
const
|
||||||
|
INT_NUM_LETTERS = 26;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
AResult := 0;
|
||||||
|
|
||||||
|
if Length(AStr) = 1 then AResult := Ord(AStr[1]) - Ord('A')
|
||||||
|
else if Length(AStr) = 2 then
|
||||||
|
begin
|
||||||
|
AResult := (Ord(AStr[1]) - Ord('A') + 1) * INT_NUM_LETTERS
|
||||||
|
+ Ord(AStr[2]) - Ord('A');
|
||||||
|
end
|
||||||
|
else Exit(False);
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@@ -1250,9 +1250,11 @@ begin
|
|||||||
try
|
try
|
||||||
// Only one stream is necessary for any number of worksheets
|
// Only one stream is necessary for any number of worksheets
|
||||||
OLEDocument.Stream := MemStream;
|
OLEDocument.Stream := MemStream;
|
||||||
|
|
||||||
OLEStorage.ReadOLEFile(AFileName, OLEDocument);
|
OLEStorage.ReadOLEFile(AFileName, OLEDocument);
|
||||||
|
|
||||||
|
// Check if the operation succeded
|
||||||
|
if MemStream.Size = 0 then raise Exception.Create('FPSpreadsheet: Reading the OLE document failed');
|
||||||
|
|
||||||
// Rewind the stream and read from it
|
// Rewind the stream and read from it
|
||||||
MemStream.Position := 0;
|
MemStream.Position := 0;
|
||||||
ReadFromStream(MemStream, AData);
|
ReadFromStream(MemStream, AData);
|
||||||
|
@@ -1234,9 +1234,11 @@ begin
|
|||||||
try
|
try
|
||||||
// Only one stream is necessary for any number of worksheets
|
// Only one stream is necessary for any number of worksheets
|
||||||
OLEDocument.Stream := MemStream;
|
OLEDocument.Stream := MemStream;
|
||||||
|
|
||||||
OLEStorage.ReadOLEFile(AFileName, OLEDocument,'Workbook');
|
OLEStorage.ReadOLEFile(AFileName, OLEDocument,'Workbook');
|
||||||
|
|
||||||
|
// Check if the operation succeded
|
||||||
|
if MemStream.Size = 0 then raise Exception.Create('FPSpreadsheet: Reading the OLE document failed');
|
||||||
|
|
||||||
// Rewind the stream and read from it
|
// Rewind the stream and read from it
|
||||||
MemStream.Position := 0;
|
MemStream.Position := 0;
|
||||||
ReadFromStream(MemStream, AData);
|
ReadFromStream(MemStream, AData);
|
||||||
|
Reference in New Issue
Block a user