Sign in Join
Wiki copytemporary

FPSpreadsheet

Deutsch · English · Español · Français · Polski · Русский

The fpSpreadsheet library offers a convenient way to generate and read spreadsheet documents in various formats. The library is written in a very flexible manner, capable of being extended to support any number of formats easily.

Screenshot of spready demo program provided with fpspreadsheet showing an XLS file:

fpsgrid.png

Documentation

This wiki page covers the latest development/trunk version of FPSpreadsheet available via subversion. Please see section Stable releases for documentation on the stable version that you can download.

API Documentation

API Reference

A help file in CHM format can be found in the FPSpreadsheet installation folder docs. If you did not yet install the package follow http://lazarus-ccr.svn.sourceforge.net/viewvc/lazarus-ccr/components/fpspreadsheet/docs/fpspreadsheet-api.chm to fpspreadsheet-api.chm.

The second CHM file available in the folder docs , fpspreadsheet-wiki.chm , is a snapshot of the FPSpreadsheet-related wiki pages bundled into a single help file.

Basics

The smallest entities in a spreadsheet are the cells which contain the data. Cells can hold various data types, like strings, numbers, dates, times, boolean values, or formulas. In addition, cells can contain information on formatting, i.e. font style, background color, text alignment etc.

The cells are arranged in a grid-like structure, called worksheet , or spreadsheet , consisting of rows and columns. Each cell has a unique address given by the row and column index.

Worksheets are bound together to form a workbook which represents the document of the spreadsheet application. The workbook also stores information that is needed from all worksheets, i.e. font list, cell and number format lists, etc.

FPSpreadsheet follows this same structure - there is a TCell, a TsWorksheet, and a TsWorkbook.

Workbook

The class TsWorkbook is the main class visible to the user. It provides methods for reading data from and writing to files. The versatile structure of the library provides access to various popular file formats, like Excel .xls or .xlsx , or OpenOffice/LibreOffice .ods.

The file format is specified by the type TsSpreadsheetFormat defined in the unit fpstypes

pascal
type
      TsSpreadsheetFormat = (sfExcel2, sfExcel5, sfExcel8, sfExcelXML, sfOOXML, 
        sfOpenDocument, sfCSV, sfHTML, sfWikiTable_Pipes, sfWikiTable_WikiMedia, sfUser);

where

When applying fpspreadsheet the first task is to create an instance of the workbook:

pascal
var
      MyWorkbook: TsWorkbook;
    begin
      MyWorkbook := TsWorkbook.Create;
      ...

Reading of spreadsheet files is accomplished (among others) by the workbook methods

Reads the file with the given name and automatically determines the correct file format.

Reads the file, but assumes that the file format is as specified by AFormat.

The following workbook methods can be used for saving to file:

Writes the workbook to the given file using the given spreadsheet format. If the file already exists it is automatically overwritten if AOverwriteExisting is true:

ditto, but the file format is determined from the file extension provided (in case of Excel's xls the most recent version, sfExcel8, is used).

After calling these methods it is advantageous to look at the workbook's property ErrorMsg in which messages due to errors or warnings are collected that might have occured during reading/writing. This property returns a multi-lined string which is displayed best in a memo component; if everything was fine it is an empty string.

Note: FPSpreadsheets provides specialized units for reading from and writing to each file format. These units are not available automatically, you have to add them to the uses clause explicitly. FPSpreadsheet will complain about "unsupported file format" if the requested reader/writer is not found. Here is a list of the unit names:

Worksheet

The workbook contains a list of TsWorksheet instances. They correspond to the tabs that you see in Excel or Open/LibreOffice. When reading a spreadsheet file the worksheets are created automatically according to the file contents. When a spreadsheet is created manually to be stored on file a worksheet has to be created by adding it to the workbook:

pascal
var
      MyWorkbook: TsWorkbook;
      MyWorksheet: TsWorksheet;
    begin
      MyWorkbook := TsWorkbook.Create;
      MyWorksheet := MyWorkbook.AddWorksheet('My_Table');  
        // 'My_Table' is the "name" of the worksheet
      ...

Already existing worksheets can be accessed by using the TsWorkbook methods

The count of already existing worksheets can be queried by calling GetWorksheetCount.

Cell

The worksheet, finally, gives access to the cells. A newly created worksheet, as in above example, is empty and does not contain any cells. Cells are added by assigning data or attributes to them by one of the WriteXXXX methods of the worksheet. As already mentioned, a cell is addressed by the index of the row and column to which it belongs. As usual, row and column indexes start at 0. Therefore, cell "A1" belongs to row 0 and column 0. It should be noted that row and column index are always specified in this order, this is different from the convention ofTStringGrid. The following example creates a cell at address A1 and puts the number 1.0 in it.

pascal
var
      MyWorkbook: TsWorkbook;
      MyWorksheet: TsWorksheet;
    begin
      MyWorkbook := TsWorkbook.Create;
      MyWorksheet := MyWorkbook.AddWorksheet('My_Table');
      MyWorksheet.WriteNumber(0, 0, 1.0);  // "A1" has row=0 and col=0
      ...

It is also possible to access cells directly by means of the methods FindCell(ARow, ACol) or GetCell(ARow, ACol) of the workbook. Both funtions exist also in an overloaded version to which the cell address can be passed in Excel notation: FindCell(ACellStr: String) or GetCell(ACellStr: String). Please be aware that these functions return a pointer to the cell data (type PCell). Don't forget to dereference the pointers! The difference between FindCell and GetCell is that the former one returns nil, if a cell does not yet exist, while the latter one creates an empty cell in this case.

pascal
if MyWorksheet.FindCell('A1') = nil then
      WriteLn('Cell A1 does not exist.');
The basic TCell record

This is the declaration of the cell's data type:

pascal
type
      TCell = record
        { Location of the cell }
        Worksheet: TsWorksheet;
        Col: Cardinal; // zero-based
        Row: Cardinal; // zero-based
    
        { Index of format record }
        FormatIndex: Integer;
    
        { Status flags }
        Flags: TsCellFlags;        // (cfHasComment, cfMerged, cfHyperlink, ...)
    
        { Cell content }
        UTF8StringValue: String;   // strings cannot be part of a variant record
        case ContentType: TCellContentType of  // must be at the end of the declaration
          cctEmpty      : ();      // has no data at all
          cctFormula    : ();      // UTF8StringValue is outside the variant record
          cctNumber     : (Numbervalue: Double);
          cctUTF8String : ();      // FormulaValue is outside the variant record
          cctDateTime   : (DateTimevalue: TDateTime);
          cctBool       : (BoolValue: boolean);
          cctError      : (ErrorValue: TsErrorValue);
      end;
      PCell = ^TCell;

The field ContentType indicates which data type is stored in the cell:

pascal
type
      TCellContentType = (cctEmpty, cctFormula, cctNumber, cctUTF8String, cctDateTime, cctBool, cctError);

According to this field the corresponding data can be found in the fields

Due to usage of a variant record most of these values are overlapping, i.e. modification of NumberValue affects also the other values. Therefore, always respect the ContentType when accessing the TCell record directly (the worksheet methods discussed below consider this automatically).

The field Flags tells whether additional data are associated with the cell which are not included in the cell record usually to save memory:

pascal
type 
      TsCellFlag = (cfHasComment, cfHyperlink, cfMerged, cfHasFormula, cf3dFormula);
      TsCellFlags = set of TsCellFlag;

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Note: After calculation of a formula or after reading of a file, the ContentType of the formula cell is converted to that of the result. Then the presence of a formula can only be detetected by calling the function HasFormula(cell) for the cell to be queried (cell: PCell) in unit fpsUtils ; this function checks the presence of the element cfHasFormula in the cell flags.

How to add and read data to/from a cell

Adding values to a cell is most easily accompished by using one of the WriteXXXX methods of the worksheet. The most important ones are:

pascal
type
      TsWorksheet = class
        ...
        { Writing of currency values }
        function WriteCurrency(ARow, ACol: Cardinal; AValue: Double;
          ANumFormat: TsNumberFormat = nfCurrency; ADecimals: Integer = 2;
          ACurrencySymbol: String = '?'; APosCurrFormat: Integer = -1;
          ANegCurrFormat: Integer = -1): PCell; overload;
        procedure WriteCurrency(ACell: PCell; AValue: Double;
          ANumFormat: TsNumberFormat = nfCurrency; ADecimals: Integer = -1;
          ACurrencySymbol: String = '?'; APosCurrFormat: Integer = -1;
          ANegCurrFormat: Integer = -1); overload;
        function WriteCurrency(ARow, ACol: Cardinal; AValue: Double;
          ANumFormat: TsNumberFormat; ANumFormatString: String): PCell; overload;
        procedure WriteCurrency(ACell: PCell; AValue: Double;
          ANumFormat: TsNumberFormat; ANumFormatString: String); overload;
    
        { Writing of date/time values }
        function WriteDateTime(ARow, ACol: Cardinal; AValue: TDateTime): PCell; overload;
        procedure WriteDateTime(ACell: PCell; AValue: TDateTime); overload;
        function WriteDateTime(ARow, ACol: Cardinal; AValue: TDateTime;
          ANumFormat: TsNumberFormat; ANumFormatStr: String = ''): PCell; overload;
        procedure WriteDateTime(ACell: PCell; AValue: TDateTime;
          ANumFormat: TsNumberFormat; ANumFormatStr: String = ''); overload;
        function WriteDateTime(ARow, ACol: Cardinal; AValue: TDateTime;
          ANumFormatStr: String): PCell; overload;
        procedure WriteDateTime(ACell: PCell; AValue: TDateTime;
          ANumFormatStr: String); overload;
    
        { Writing of number values } 
        function WriteNumber(ARow, ACol: Cardinal; ANumber: double): PCell; overload;
        procedure WriteNumber(ACell: PCell; ANumber: Double); overload;
        function WriteNumber(ARow, ACol: Cardinal; ANumber: double;
          ANumFormat: TsNumberFormat; ADecimals: Byte = 2): PCell; overload;
        procedure WriteNumber(ACell: PCell; ANumber: Double;
          ANumFormat: TsNumberFormat; ADecimals: Byte = 2); overload;
        function WriteNumber(ARow, ACol: Cardinal; ANumber: double;
          ANumFormat: TsNumberFormat; ANumFormatString: String): PCell; overload;
        procedure WriteNumber(ACell: PCell; ANumber: Double;
          ANumFormat: TsNumberFormat; ANumFormatString: String); overload;
    
        { Writing of string values }
        function WriteText(ARow, ACol: Cardinal; AText: ansistring;
          ARichTextParams: TsRichTextParams = nil): PCell; overload;
        procedure WriteText(ACell: PCell; AText: String;
          ARichTextparams: TsRichTextParams = nil); overload;
    
        // the old string methods "WriteUTF8Text" are deprecated now
        ...

Some of these methods exist in overloaded versions in which cell formatting parameters can be added together with the cell value. Correspondingly to writing, there is also a number of worksheet methods for reading the cell values:

pascal
type
      TsWorksheet = class
        ...
        { Reading cell content as a string }
        function  ReadAsText(ARow, ACol: Cardinal): string; overload;
        function  ReadAsText(ACell: PCell): string; overload;
        function  ReadAsText(ACell: PCell; AFormatSettings: TFormatSettings): string; overload;
    
        { Reading cell content as a number }
        function  ReadAsNumber(ARow, ACol: Cardinal): Double; overload;
        function  ReadAsNumber(ACell: PCell): Double; overload;
        function  ReadNumericValue(ACell: PCell; out AValue: Double): Boolean;
    
        { Reading cell content as a date/time value }
        function  ReadAsDateTime(ARow, ACol: Cardinal; out AResult: TDateTime): Boolean; overload;
        function  ReadAsDateTime(ACell: PCell; out AResult: TDateTime): Boolean; overload;
        ...
Index to Cell format

FormatIndex is the index of the cell format record. It describes the formatting attributes of a cell. These records are collected by an internal list of the workbook and are defined like this:

pascal
type
      TsCellFormat = record
        FontIndex: Integer;
        TextRotation: TsTextRotation;
        HorAlignment: TsHorAlignment;
        VertAlignment: TsVertAlignment;
        Border: TsCellBorders;
        BorderStyles: TsCellBorderStyles;
        Background: TsFillPattern;
        NumberFormatIndex: Integer;
        NumberFormat: TsNumberFormat;
        NumberFormatStr: String;
        BiDiMode: TsBiDiMode;           // bdDefault, bdLTR {left-to-right}, bdRTL {right-to-left)
        Protection: TsCellProtection;   // cpLockCell, cpHideFormulas
        UsedFormattingFields: TsUsedFormattingFields;
          //uffTextRotation, uffFont, uffBold, uffBorder, uffBackground, uffNumberFormat, uffWordWrap, uffHorAlign, uffVertAlign, uffBiDi, uffProtection, uffDoNotPrint
      end;

For specifying a format for a given cell call the corresponding the worksheet method WriteXXXX, for retrieving a format call ReadXXXX. These methods usually get a pointer to the cell as a parameter, but there are also overloaded versions which accept the row and column index. Moreover, formatting styles can also be applied directly to the cell by using a record helper implemented in unit fpsCell.

See cell formatting below for a more detailed description.

Columns and rows

Column and row records are added for each column and row having a non-default properties:

pascal
type
      TCol = record
        Col: Cardinal;
        Width: Single;
        ColWidthType: TsColWidthType;     // = (cwtDefault, cwtCustom)
        FormatIndex: Integer;
        Options: TsColRowOptions;         // set of [croHidden, croPageBreak]
      end;
      PCol = ^TCol;
    
      TRow = record
        Row: Cardinal;
        Height: Single;
        RowHeightType: TsRowHeightType;   // = (rhtDefault, rhtCustom, rhtAuto)
        FormatIndex: Integer;
        Options: TsColRowOptions;         // set of [croHidden, croPageBreak]
        Hidden: Boolean;
        PageBreak: Boolean;
      end;
      PRow = ^TRow;
Column width / row height

Column widths and row heights can be specified in a variety of units defined by the type TsSizeUnits = (suChars, suLines, suMillimeters, suCentimeters, suPoints, suInches). suChars refers to the count of 0 characters fitting into the column width - this is the way how Excel defines column widths. suLines is the number of lines fitting into the row height. Both units are based on the character size of the workbook's default font. The other units are conventional physical length units (1 cm = 10 mm, 1 inch = 25.4 mm = 72 pt). Fractional values are accepted. The workbook and worksheets store lengths internally in millimeters (MyWorkbook.Units).

The Office applications usually adjust the row heights automatically according to the font or text rotation of the cell content. This case is identified by RowHeightType having the value rhtAuto. Since the worksheet cannot calculate text size very accurately automatic row heights are not written by FPSpreadsheet; they are replaced by the default row height. The default row height is also used if a row is empty, i.e. does not contain any data cells. Its value can be changed by calling the worksheet's WriteDefaultRowHeight() or by using the worksheet property DefaultRowHeight. In WriteDefaultRowHeight, the units must be specified while in DefaultRowHeight they are assumed to be lines. Similarly, the default column width can be specified by WriteDefaultColWidth() or the property DefaultColWidth (in characters).

In order to overrun automatic and default row heights call the worksheet method WriteRowHeight(). These row records are identified by RowHeightType having the value rhtCustom. In the same way the width of columns can be set to a specific value by calling WriteColWidth(). ColWidthType of these columns is cwtCustom.

The height/width of a particular row/column can be retrieved by means of the methods GetRowHeight or GetColWidth. Note that these methods return the default row heights/column widths if there are no TRow/TCol records.

pascal
type TsWorksheet = class
      ...
      { Set row height }
      procedure WriteRowHeight(ARowIndex: Cardinal; AHeight: Single; AUnits: TsSizeUnits);
      { Set column width }
      procedure WriteColWidth(AColIndex: Cardinal; AWidth: Single; AUnits: TsSizeUnits);
      { Set default row height }
      procedure WriteDefaultRowHeight(AHeight: Single; AUnits: TsSizeUnits);
      {Set default cokumn width }
      procedure WriteDefaultColWidth(AWidth: Single; AUnits: TsSizeUnits);
    
      { Return row height }
      function GetRowHeight(ARowIndex: Cardinal; AUnits: TsSizeUnits): Single;
      { Return column width }
      function GetColWidth(AColIndex: Cardinal; AUnits: TsSizeUnits): Single;
      { Return default row height }
      function ReadDefaultRowHeight(AUnits: TsSizeUnits): Single;
      { Return default column width }
      function ReadDefaultColWidth(AUnits: TsSizeUnits): Single;
    
      property DefaultRowHeight: Single;  // in lines
      property DefaultColWidht: Single;   // in characters

There are also overloaded versions of these methods which do not require the AUnits parameter. In this case, row heights are defined in terms of line count, and column widths are defined in terms of character count. Note that these variants are from previos versions and are deprecated now.

Column and row formats

The FormatIndex element of the row and column records format applied to the entire row or column. Together with cells, these formats are stored as TsCellFormat records in an internal workbook list, FormatIndex is the index of the format properties into this list. See details in section Cell formatting. Row and column formats are primarily applied to empty cells, but if a new cell is added it will automatically get the format of the row or column. (If both row and column have different formats then the row format will be used).

Here is a listing of the worksheet methods available for column and row formatting:

pascal
type TsWorksheet = class
      // Assign a format to a column or row
      procedure WriteColFormatIndex(ACol: Cardinal; AFormatIndex: Integer);
      procedure WriteRowFormatIndex(ARow: Cardinal; AFormatIndex: Integer);
    
      // Query the format of a column or row
      function  GetColFormatIndex(ACol: Cardinal): Integer;
      function  GetRowFormatIndex(ARow: Cardinal): Integer;
    
      // Returns the font assigned to a column or row
      function  ReadColFont(ACol: PCol): TsFont;
      function  ReadRowFont(ARow: PRow): TsFont; 
    
      // Check whether any column or row uses a special format
      function  HasRowFormats: Boolean; 
      function  HasColFormats: Boolean;
Hidden columns / rows

Adding the flag croHidden to the row's or column's Options hides the row or column in the Office application (or in TsWorksheetGrid). The following worksheet methods are helpers to handle row/column visibility :

pascal
type TsWorksheet = class
      ...
      { Hide column/row }
      procedure HideCol(ACol: Cardinal);
      procedure HideRow(ARow: Cardinal);
    
      { Show a previously hidden column/row }
      procedure ShowCol(ACol: Cardinal);
      procedure ShowRow(ARow: Cardinal);
    
      { Check whether column/row is hidden }
      function  ColHidden(ACol: Cardinal): Boolean;
      function  RowHidden(ARow: Cardinal): Boolean;
Page breaks

The flag croPageBreak can be added to the row's or column's Options in order to force a page break before the corresponding row or column when the worksheet is printed by the Office applications. Note that FPSpreadsheet itself does not support printing. The following worksheet methods help with page breaks:

pascal
type TsWorksheet = class
      ...
      { Enforce a page break before the specified column/row }
      procedure AddPageBreakToCol(ACol: Cardinal);
      procedure AddPageBreakToRow(ARow: Cardinal);
    
      { Removes a page break previously added to a column/row }
      procedure RemovePageBreakFromCol(ACol: Cardinal);
      procedure RemovePageBreakFromRow(ARow: Cardinal);
    
      { Checks whether a page break is forced before the specified column/row }
      function IsPageBreakCol(ACol: Cardinal): Boolean;
      function IsPageBreakRow(ARow: Cardinal): Boolean;

Events

Worksheets and workbooks fire a series of events such as OnChangeCell, OnChangeFont, etc. The events usually are intended for interaction with the visual spreadsheet controls. If you need to attach your own handlers you should make sure that the original handler is called, at least in a gui program using the spreadsheet controls. Or you use the events provided by the visual controls themselves, e.g. [[TsWorksheetGrid|WorksheetGrid]].OnEditingDone instead of WorksheetGrid.Worksheet.OnChangeCell.

Formulas

Two kinds of formulas are supported by FPSpreadsheet:

FPSpreadsheet can convert between string and rpn formulas. Formulas in both types can be calculated.

In older versions of FPSpreadsheet, formulas were stored directly in the cell record. This was given up to have parsed formulas available for faster calculation. The formulas are stored in the tree Formulas of the worksheet. The formula record contains the row and column index of the cell to which the formula belongs, the string representation of the formula, as well as the parser tree for quick evaluation.

FPSpreadsheet supports the majority of the formulas provided by the common spreadsheet applications. However, when reading a file created by these applications, there is always a chance that an unsupported formula is contained. To avoid crashing of fpspreadsheet, reading of formulas is disabled by default; the cell displays only the result of the formula written by the Office application. To activate reading of formulas add the element boReadformulas to the workbook's Options before opening the file. If an error occurs in this case the reader normally catches the exception, writes the exception message into the workbook's errorlog and continues reading. If you want reading to stop you must add the boAbortReadingOnFormulaError to the workbook Options.

Formulas can link to data in other sheets of the same workbook ("3d formulas") by applying the Excel syntax (see below). External links to spreadsheets in other files are not supported.

Calculation of formulas is normally not needed when a file is written by FPSpreadsheet for opening in an Office application because that automatically calculates the formula results. If the same file, however, is openend by an application based on FPSpreadsheet the calculated cells would be empty because the formulas are not automatically calculated by default. To activate calculation of formulas before writing a spreadsheet to file you have to add the option boCalcBeforeSaving to the workbook's Options.

If FPSpreadshet is used in an interactive application (such as the spready demo found in the examples folder of the FPSpreadsheet installation) it is desirable to calculate formulas automatically whenever formula strings or cell values are changed by the user. This can be achieved by the option boAutoCalc in the workbook's Options.

The most general setting regarding formulas, therefore, is

pascal
MyWorkbook.Options := MyWorkbook.Options + [boReadFormulas, boCalcBeforeSaving, boAutoCalc];

Calculation of formulas can be triggered manually by calling the method CalcFormulas of the worksheet or workbook. The latter is absolutely required when the workbook contains 3d formulas where the result of one cell can affect cells in other sheets. If there are only within-sheet formulas then the worksheet's CalcFormulas is sufficient.

String formulas

String formulas are written in the same way as in the Office applications. The worksheet method for creating a string formula is WriteFormula:

pascal
var
      MyWorksheet: TsWorksheet;
    //...
      MyWorksheet.WriteFormula(0, 1, '=ROUND(A1+B2+1.215,0)');
      // By default, use dot as decimal and comma as list separator!

A few notes on syntax :

pascal
var
      MyWorksheet: TsWorksheet;
    //...
      MyWorksheet.WriteFormula(0, 1, '=ROUND(A1+B2+1,215;0)', true);
      // Because of the "true" the formula parser accepts the comma as decimal and the
      // semicolon as list separator if the workbook's FormatSettings are set up like this.

Use the worksheet methods ReadFormula or ReadFormulaAsString to retrieve the string formula assigned to the cell. The pointer to the cell must be given as a parameter. The latter function accepts an additional (boolean) parameter ALocalized to use the decimal and list separators of the workbook's FormatSettings for creation of the formula string.

pascal
var
      MyWorksheet: TsWorksheet;
      cell: PCell;
    //...
      cell := MyWorksheet.FindCell(0, 1);
      WriteLn('The formula in internal format is ', MyworkSheet.ReadFormula(cell));
      WriteLn('The localized formula is ', MyWorksheet.ReadFormulaAsString(cell, true));
    //-------------------------------------------------------------------
    // For the previous example, this will result in the following output
    The formula in internal format is ROUND(A1+B2+1.215,0)
    The localized formula is ROUND(A1+B2+1,215;0)

RPN formulas

At application level, string formulas are mainly used, and RPN formulas are of little practical importance. Therefore, documentation of RPN formulas has been removed from this main FPSpreadsheet wiki and can be found in the article "RPN Formulas in FPSpreadsheet".

Shared formulas and array formulas

List of built-in formulas

FPSpreadsheet supports more than 80 built-in formulas. In order not to blow up this wiki page too much documentation of these formulas has been moved to the separate document "List of formulas".

To learn more about the functions available, look at file testcases_calcrpnformula.inc in the tests folder of the FPSpreadsheet installation where every function is included with at least one sample.

Extending FPSpreadsheet by user-defined formulas

Although the built-in formulas cover most of the applications there may be a need to access a formula which is available in the Office application, but not in FPSpreadsheet. For this reason, the library supports a registration mechanism which allows to add user-defined functions to the spreadsheets. This can be done by calling the procedure RegisterFunction from the unit fpsExprParser :

pascal
procedure RegisterFunction(const AName: ShortString; const AResultType: Char;
      const AParamTypes: String; const AExcelCode: Integer; ACallBack: TsExprFunctionCallBack); overload;
    
    procedure RegisterFunction(const AName: ShortString; const AResultType: Char;
      const AParamTypes: String; const AExcelCode: Integer; ACallBack: TsExprEventCallBack); overload;
pascal
type
      TsExprFunctionCallBack = procedure (var Result: TsExpressionResult; const Args: TsExprParameterArray);
      TsExprFunctionEvent = procedure (var Result: TsExpressionResult; const Args: TsExprParameterArray) of object;

The TsExpressionResult is a variant record containing result or argument data of several types:

pascal
type
      TsResultType = (rtEmpty, rtBoolean, rtInteger, rtFloat, rtDateTime, rtString,
        rtCell, rtCellRange, rtError, rtAny);
    
      TsExpressionResult = record
        Worksheet       : TsWorksheet;
        ResString       : String;
        case ResultType : TsResultType of
          rtEmpty       : ();
          rtError       : (ResError       : TsErrorValue);
          rtBoolean     : (ResBoolean     : Boolean);
          rtInteger     : (ResInteger     : Int64);
          rtFloat       : (ResFloat       : TsExprFloat);
          rtDateTime    : (ResDateTime    : TDatetime);
          rtCell        : (ResRow, ResCol : Cardinal);
          rtCellRange   : (ResCellRange   : TsCellRange);
          rtString      : ();
      end;
    
      TsExprParameterArray = array of TsExpressionResult;

As an example we show here the code for the CONCATENATE() formula which joins two or more strings:

pascal
const
      INT_EXCEL_SHEET_FUNC_CONCATENATE = 336;  
    ...
      RegisterFunction('CONCATENATE', 'S', 'S+', INT_EXCEL_SHEET_FUNC_CONCATENATE, @fpsCONCATENATE);
    
    procedure fpsCONCATENATE(var Result: TsExpressionResult; const Args: TsExprParameterArray);
    // CONCATENATE( text1, text2, ... text_n )
    var
      s: String;
      i: Integer;
    begin
      s := '';
      for i:=0 to Length(Args)-1 do
      begin
        if Args[i].ResultType = rtError then
        begin
          Result := ErrorResult(Args[i].ResError);
          exit;
        end;
        s := s + ArgToString(Args[i]);
        // "ArgToString" simplifies getting the string from a TsExpressionResult as 
        // a string may be contained in the ResString and in the ResCell fields.
        // There is such a function for each basic data type.
      end;
      Result := StringResult(s);
      // "StringResult" stores the string s in the ResString field of the
      // TsExpressionResult and sets the ResultType to rtString.
      // There is such a function for each basic data type.
    end;

There is a worked-out example (demo_formula_func.pas) in the folder examples/other of the FPSpreadsheet installation. In this demo, four financial functions (FV(), PV(), PMT(), RATE()) are added to FPSpreadsheet.

Unsupported formulas

Sometimes it is required to create files for the Office applications with formulas not supported by fpspreadsheet. This is possible to some extent when the workbook option boIgnoreFormulas is active. Then any arbitrary formula can be written to a cell, and the formula is not checked and not evaluated. The workbook can be written to an .ods or .xlsx file. The old xls file format cannot be used because the formula would have to be parsed to create the rpn formula needed.

In folder examples/other you can find the sample project demo_ignore_formula which creates an ods file with references to another data file - external references normally are not supported by fpspreadsheet, and thus the ignore-formulas workaround must be used. Note that this example does not work with xlsx because Excel writes information on the external links to separate xml files within the xlsx container.

Cell formatting

Number and date/time formats

Numbers and date/time values can be displayed in a variety of formats. In FPSpreadsheet this can be achieved in two ways:

Number formats can be specified by these worksheet methods:

pascal
type
      TsWorksheet = class
      public
        // Set number formats alone
        function WriteNumberFormat(ARow, ACol: Cardinal; ANumberFormat: TsNumberFormat;
          const AFormatString: String = ''): PCell; overload;
        procedure WriteNumberFormat(ACell: PCell; ANumberFormat: TsNumberFormat;
          const AFormatString: String = ''); overload;  
    
        function WriteNumberFormat(ARow, ACol: Cardinal; ANumFormat: TsNumberFormat;
          ADecimals: Integer; ACurrencySymbol: String = ''; APosCurrFormat: Integer = -1;
          ANegCurrFormat: Integer = -1): PCell; overload;
        procedure WriteNumberFormat(ACell: PCell; ANumFormat: TsNumberFormat;
          ADecimals: Integer; ACurrencySymbol: String = '';
          APosCurrFormat: Integer = -1; ANegCurrFormat: Integer = -1); overload;
    
        function WriteFractionFormat(ARow, ACol: Cardinal; AMixedFraction: Boolean;
          ANumeratorDigits, ADenominatorDigits: Integer): PCell; overload;
        procedure WriteFractionFormat(ACell: PCell; AMixedFraction: Boolean;
          ANumeratorDigits, ADenominatorDigits: Integer); overload;
    
        // Set date/time formats alone  
        function WriteDateTimeFormat(ARow, ACol: Cardinal; ANumberFormat: TsNumberFormat;
          const AFormatString: String = ''): PCell; overload;
        procedure WriteDateTimeFormat(ACell: PCell; ANumberFormat: TsNumberFormat;
          const AFormatString: String = ''); overload;
    
    
        // Set cell values and number formats in one call
    
        // number values
        function WriteNumber(ARow, ACol: Cardinal; ANumber: double;
          AFormat: TsNumberFormat = nfGeneral; ADecimals: Byte = 2;
          ACurrencySymbol: String = ''): PCell; overload;
        procedure WriteNumber(ACell: PCell; ANumber: Double; AFormat: TsNumberFormat = nfGeneral;
          ADecimals: Byte = 2; ACurrencySymbol: String = ''); overload;
        function WriteNumber(ARow, ACol: Cardinal; ANumber: double;
          AFormat: TsNumberFormat; AFormatString: String): PCell; overload;
        procedure WriteNumber(ACell: PCell; ANumber: Double;
          AFormat: TsNumberFormat; AFormatString: String); overload;   
    
        // date/time values
        function WriteDateTime(ARow, ACol: Cardinal; AValue: TDateTime;
          AFormat: TsNumberFormat = nfShortDateTime; AFormatStr: String = ''): PCell; overload;
        procedure WriteDateTime(ACell: PCell; AValue: TDateTime;
          AFormat: TsNumberFormat = nfShortDateTime; AFormatStr: String = ''); overload;
        function WriteDateTime(ARow, ACol: Cardinal; AValue: TDateTime;
          AFormatStr: String): PCell; overload;
        procedure WriteDateTime(ACell: PCell; AValue: TDateTime;
          AFormatStr: String); overload;  
    
        // currency values
        function WriteCurrency(ARow, ACol: Cardinal; AValue: Double;
          AFormat: TsNumberFormat = nfCurrency; ADecimals: Integer = 2;
          ACurrencySymbol: String = '?'; APosCurrFormat: Integer = -1;
          ANegCurrFormat: Integer = -1): PCell; overload;
        procedure WriteCurrency(ACell: PCell; AValue: Double;
          AFormat: TsNumberFormat = nfCurrency; ADecimals: Integer = -1;
          ACurrencySymbol: String = '?'; APosCurrFormat: Integer = -1;
          ANegCurrFormat: Integer = -1); overload;
        function WriteCurrency(ARow, ACol: Cardinal; AValue: Double;
          AFormat: TsNumberFormat; AFormatString: String): PCell; overload;
        procedure WriteCurrency(ACell: PCell; AValue: Double;
          AFormat: TsNumberFormat; AFormatString: String); overload;     
      ...
Built-in number formats

The built-in formats are defined by the enumeration TsNumberFormat. In spite of its name, the elements cover both number and date/time values:

pascal
type
      TsNumberFormat = (
        // general-purpose for all numbers
        nfGeneral,
        // numbers
        nfFixed, nfFixedTh, nfExp, nfPercentage, nfFraction,
        // currency
        nfCurrency, nfCurrencyRed, 
        // dates and times
        nfShortDateTime, nfShortDate, nfLongDate, nfShortTime, nfLongTime,
        nfShortTimeAM, nfLongTimeAM, nfDayMonth, nfMonthYear, nfTimeInterval,
        // other (using format string)
        nfCustom);

As already noted the workbook has a property FormatSettings which provides additional information to control the resulting formatting. This is essentially a copy of the DefaultFormatSettings declared in the sysutils unit (the elements LongDateFormat and ShortDateFormat are slightly modified to better match the default settings in the main spreadsheet applications). The main purpose of the FormatSettings is to add a simple way of localization to the number formats.

Number format strings

In addition to these pre-defined formats, more specialized formatting can be achieved by using the format constant nfCustom along with a dedicated format string. The format string is constructed according to Excel syntax which is close to the syntax of fpc's FormatFloat and FormatDateTime commands (accepted as well, see the online-help for these functions).

Here is a basic list of the symbols used:

Symbol Meaning Format string: Number --> Output string
General Displays all decimal places of the number 'General': · 1.2345678 --> '1.2345678'
0 Displays insignificant zeros if a number has less digits than there are zeros in the format. If used for decimal places then the number is rounded to as many decimal places as 0s are found. '000': 1 --> '001' · '0.0': 1 --> '1.0' · '0.0': 1.2345678 --> '1.2'
* Like "0" above, but does not display insignificant zeros. '0.*': 1 --> '1.' · '0.*': 1.2345678 --> '1.2'
? Like "0" above, but insignificant zeros are replaced by space characters. Good for aligning decimal points and fractions '??0': 1 --> ' 1' · '0.0??': 1 --> '1.0 '
. Decimal separator; will be replaced by the value used in the DecimalSeparator of the workbook's FormatSettings '0.00': 8.9 --> '8.90'
, Thousand separator; will be replaced by the value used in the ThousandSeparator of the workbook's FormatSettings. If at the end of a number formatting sequence the displayed value is divided by 1000. '#,##0.00': 1200 --> '1,200.00' · '0.00,': 1200 --> '1.20'
E+, e+ Displays a number in exponential format. The digits used for the exponent are defined by the number of zeros added the this symbol. The sign of the exponent is shown for positive and negative exponents. '0.00E+00': 1200 --> 1.20E+03
E-, e- Displays a number in exponential format. The digits used for the exponent are defined by the number of zeros added the this symbol. The sign of the exponent is shown only for negative exponents. '0.00e-000': 1200 --> 1.20e003
% Displays the number as a "percentage", i.e. the number is multiplied by 100 and a % sign is added. '0.0%': 0.75 --> 75.0%
/ This symbol has two meanings: if the cell represents a "number" then the slash indicates formatting as fraction, place holders for numerator and denominator must follow. If the cell represents a "date/time" then the slash indicates the date separator which will be replaced by the DateSeparator of the workbook's FormatSettings '#/#': 1.5 --> '3/2' · '# #/#': 1.5 --> '1 1/2' · '# #/16': 1.5 --> '1 8/16' · also: see date/time examples below
: Separator between hours, minutes and seconds of a date/time value. Will be replaced by the TimeSeparator of the workbook's FormatSettings. see examples below
yyyy Place holder for the year of a date/time value. The year is displayed as a four-digit number. 'yyyy/mm/dd': · Jan 3, 2012 --> '2012-01-03' · In this example, the DateSeparator is a dash character (-).
yy Place holder for the year of a date/time value. The year is displayed as a two-digit number. 'yy/mm/dd': · Jan 3, 2012 --> '12-01-03'
m Place holder for the month of a date/time value. The month is shown as a number without extra digits. · Please note that the m code can also be interpreted as the "minutes" of a time value (see below). 'yyyy/m/dd': · Jan 3, 2012 --> '2012-1-03'
mm Place holder for the month of a date/time value. The month is shown as a two-digit number, i.e. a leading zero is added for January to September. · Please note that the mm code can also be interpreted as the "minutes" of a time value (see below). 'yyyy/mm/dd': · Jan 3, 2012 --> '2012-01-03'
mmm Place holder for the month of a date/time value. The month is displayed by its abbreviated name. 'yyyy/mmm/dd': · Jan 3, 2012 --> '2012-Jan-03'
mmmm Place holder for the month of a date/time value. The month is displayed by its full name. 'yyyy/mmm/dd': · Jan 3, 2012 --> '2012-January-03'
d Place holder for the day of a date/time value to be displayed as a number. The day is displayed as a simple number, without adding a leading zero. 'yyyy/mm/d': · Jan 3, 2012 --> '2012-01-3'
dd Place holder for the day of a date/time value to be displayed as a number. dd adds a leading zero to single-digit day numbers. 'yyyy/mm/dd': · Jan 3, 2012 --> '2012-01-03'
ddd Place holder for the day of a date/time value. The day is displayed as its abbreviated name. 'dddd, yyyy/mm/ddd': · Jan 03, 2012 --> 'Tue 2012-01-03'
dddd Place holder for the day of a date/time value. The day is displayed as its full name. 'dddd, yyyy/mmmm/dd': · Jan 03, 2012 --> 'Tuesday 2012-01-03'
h Place holder of the hour part of a date/time value. The hour is displayed as a simple number, without adding a leading zero. 'h:mm': · 0.25 --> '6:00'
hh Place holder of the hour part of a date/time value. The hour is displayed with a leading zero if the hour is less than 10. 'hh:mm': · 0.25 --> '06:00'
[hh], or [h] Displays elapsed time such that the hour part can become greater than 23 '[h]:mm': · 1.25 --> '30:00'
m Place holder of the minutes part of a date/time value. The minutes are shown as a simple number without adding a leading zero. Note that if the m codes are surrounded by date symbols (y, d) then they are interpreted as "month". 'h:m': · 0.25 --> '6:0'
mm Place holder of the minutes part of a date/time value. Single-digit minutes are displayed with a leading zero. Note that if the mm code is surrounded by date symbols (y, d) then it is interpreted as "month". 'h:mm': · 0.25 --> '6:00'
[mm], or [m] Displays elapsed time such that the minute part can become greater than 59 '[mm]:ss': · 1.25 --> '1800:00'
s Place holder of the seconds part of a date/time value. The seconds are displayed as a simple number, without adding a leading zero. 'hh:mm:s': · 0.25 --> '06:00:0'
ss Place holder of the seconds part of a date/time value. Single-digit seconds are displayed with a leading zero. 'hh:mm:ss': · 0.25 --> '06:00:00'
[ss], or [s] Displays elapsed time such that the seconds part can become greater than 59 '[ss]': · 1.25 --> '108000'
AM/PM, am/pm, A/P, or a/p Displays the time in the 12-hour format. 'hh:mm:ss AM/PM': · 0.25 --> '6:00:00 AM'
" The text enclosed by quotation marks is inserted into the formatted strings literally. 'yyyy"/"mm"/"dd': · Jan 3, 2012 --> '2012/01/03' (i.e. the / is not replaced by the DateSeparator of the workbook).
\ The next character of the format string appears in the result string literally. The \ itself does not show up. 'yyyy\/mm\/dd': · Jan 3, 2012 --> '2012/01/03'
; A format string can contain up to three sections separated by the semicolon. The first section is used for positive numbers, the second section for negative numbers, and the third section for zero numbers. If the third section is missing then a zero value is formatted as specified in the first section. If the second section is missing as well then all values are formatted according to the first section. '"#,##0"$"';-#,##0"$";"-"': · 1200 --> '1,200$' · -1200 --> '1,200$' · 0 --> '-'
(, and ) Sometimes used for currency values to indicate negative numbers, instead of minus sign '#,##0"$";(#,##0)"$"': · -1200 --> '(1200)$'
[red] The formatted string is displayed in the specified color. Instead of [red], you can use accordingly [black], [white], [green], [blue], [magenta], [yellow], or [cyan]. Often used to highlight negative currency values. '"$" #,##0.00;[red]("$" #,##0.00)': · -1200 --> '($ 1200.00)'
A note on Excel dates

There is a discrepancy between FPSpreadsheet and Excel presentation of dates: Excel incorrectly assumes that the year 1900 was a leap year and thus allows for the date Febr 29 1900. FPSpreadsheet does the date calculation correctly. As consequence, dates before March 1 1900 are off by one! BTW, FPSpreadsheet handles this issue in the same way as LibreOffice Calc.

Colors

FPSpreadsheet supports colors for text, cell background, and cell borders. The basic EGA colors are declared in unit fpstypes as constants:

Predefined colors

pascal
type
      TsColor = DWORD;
    
    const
      scBlack       = $00000000;
      scWhite       = $00FFFFFF;
      scRed         = $000000FF;
      scGreen       = $0000FF00;
      scBlue        = $00FF0000;
      scYellow      = $0000FFFF;
      scMagenta     = $00FF00FF;
      scCyan        = $00FFFF00;
      scDarkRed     = $00000080;
      scDarkGreen   = $00008000;
      scDarkBlue    = $00800000;
      scOlive       = $00008080;
      scPurple      = $00800080;
      scTeal        = $00808000;
      scSilver      = $00C0C0C0;
      scGray        = $00808080;
      scGrey        = scGray; // redefine to allow different spelling
    
      // Identifier for undefined color 
      scNotDefined  = $40000000;
    
      // Identifier for transparent color 
      scTransparent = $20000000;

The TsColor represents the rgb value of a color, a single byte being used for the red, green, and blue components. The resulting number is in little endian notation, i.e. the red value comes first in memory: $00BBGGRR. (This is directly compatible with the color values as defined in the graphics unit.)

The high order byte is usually zero but is used internally to identify special color values, such as for undefined or transparent colors.

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Note: In older versions of the library colors were defined as indexes into a color palette. THIS IS NO LONGER WORKING.

Unit fpsutils contains some useful functions for modification of colors :

returns the name of the colors defined above, or a string showing the rgb components for other colors.

returns scBlack for a "bright", scWhite for a "dark" input color.

brightens or darkens a color by applying a factor tint = -1..+1, where -1 means "100% darken", +1 means "100% brighten", and 0 means "no change". The hue of the color is preserved.

Cell background

The cell background can be filled by predefined patterns which are identified by the record TsFillPattern:

pascal
type
      TsFillPattern = record
        Style: TsFillStyle;   // fill style pattern as defined below
        FgColor: TsColor;     // forground color of the fill pattern
        BgColor: TsColor;     // background color of the fill pattern
      end;
    
      TsFillStyle = (fsNoFill, fsSolidFill, fsGray75, fsGray50, fsGray25, fsGray12, fsGray6,
        fsStripeHor, fsStripeVert, fsStripeDiagUp, fsStripeDiagDown,
        fsThinStripeHor, fsThinStripeVert, fsThinStripeDiagUp, fsThinStripeDiagDown,
        fsHatchDiag, fsThinHatchDiag, fsThickHatchDiag, fsThinHatchHor);
pascal
type
      TsWorksheet = class
      public
        function WriteBackground(ARow, ACol: Cardinal; AStyle: TsFillStyle; APatternColor, ABackgroundColor: TsColor): PCell; overload;
        procedure WriteBackground(ACell: PCell; AStyle: TsFillStyle; APatternColor, ABackgroundColor: TsColor); overload;
    
        function WriteBackgroundColor(ARow, ACol: Cardinal; AColor: TsColor): PCell; overload;
        procedure WriteBackgroundColor(ACell: PCell; AColor: TsColor); overload;
    
        function ReadBackground(ACell: PCell): TsFillPattern;
        function ReadBackgroundColor(ACell: PCell): TsColor; overload;
        // ...
      end;
    
    var
      cell: PCell;
    ...
      // Example 1: Assign a pattern of thin, horizontal, yellow stripes on a blue background to empty cell A1 (row 0, column 0)
      MyWorksheet.WriteBackground(0, 0, fsThinStripeHor, scYellow, scBlue);
    
      // Example 2: Uniform gray background color of cell B1 (row 0, column 1) containing the number 3.14
      cell := MyWorksheet.WriteNumber(0, 1, 3.14);
      MyWorksheet.WriteBackgroundColor(cell, clSilver);

Cell borders

Cells can be emphasized by drawing border lines along their edges or diagonal lines. There are four borders plus two diagonals enumerated in the data type TsCellBorder:

pascal
type
      TsCellBorder = (cbNorth, cbWest, cbEast, cbSouth, cbDiagUp, cbDiagDown);
      TsCellBorders = set of TsCellBorder;

In order to show a border line add the corresponding border to the cell's set Borders (type TsCellBorders, see above). In this way, each cell edge can be handled separately. Use the worksheet method WriteBorders for this purpose. This example adds top and bottom borders to the edges A1 and B1:

pascal
MyWorksheet.WriteBorders(0, 0, [cbNorth, cbSouth]);  // A1: row 0, column 0
      MyWorksheet.WriteBorders(0, 1, [cbNorth, cbSourth]); // B1: row 0, column 1

Lines usually are drawn as thin, solid, black lines. But it is possible to modify line style and color of each line. For this purpose, the cell provides an array of TsCellBorderStyle records:

pascal
type
      TsLineStyle = (lsThin, lsMedium, lsDashed, lsDotted, lsThick, lsDouble, lsHair,
        lsMediumDash, lsDashDot, lsMediumDashDot, lsDashDotDot, lsMediumDashDotDot, lsSlantDashDot); 
    
      TsCellBorderStyle = record
        LineStyle: TsLineStyle;   
        Color: TsColor;
      end;
    
      TsCellBorderStyles = array[TsCellBorder] of TsCellBorderStyle;   
    
      TsWorksheet = class
      public
        function WriteBorderStyle(ARow, ACol: Cardinal; ABorder: TsCellBorder; AStyle: TsCellBorderStyle): PCell; overload;
        procedure WriteBorderStyle(ACell: PCell; ABorder: TsCellBorder; AStyle: TsCellBorderStyle); overload;
    
        function WriteBorderStyle(ARow, ACol: Cardinal; ABorder: TsCellBorder; ALineStyle: TsLineStyle; AColor: TsColor): PCell; overload;
        procedure WriteBorderStyle(ACell: PCell; ABorder: TsCellBorder; ALineStyle: TsLineStyle; AColor: TsColor); overload;
    
        function WriteBorderColor(ARow, ACol: Cardinal; ABorder: TsCellBorder; AColor: TsColor): PCell; overload;
        procedure WriteBorderColor(ACell: PCell; ABorder: TsCellBorder; AColor: TsColor): PCell; overload;
    
        function WriteBorderLineStyle(ARow, ACol: Cardinal; ABorder: TsCellBorder; ALineStyle: TsLineStyle): PCell; overload;
        procedure WriteBorderLineStyle(ACell: PCell; ABorder: TsCellBorder; ALineStyle: TsLineStyle): PCell; overload;
    
        function WriteBorderStyles(ARow, ACol: Cardinal; const AStyles: TsCellBorderStyles): PCell; overload;      
        procedure WriteBorderStyles(ACell: PCell; const AStyles: TsCellBorderStyles); overload;
    
        function WriteBorders(ARow, ACol: Cardinal; ABorders: TsCellBorders): PCell; overload
        procedure WriteBorders(ACell: PCell; ABorders: TsCellBorders); overload
    
        function ReadCellBorders(ACell: PCell): TsCellBorders;
        function ReadCellBorderStyle(ACell: PCell; ABorder: TsCellBorder): TsCellBorderStyle;
        function ReadCellBorderStyles(ACell: PCell): TsCellBorderStyles;
        ...
      end;

The style of a given cell border can be specified by the following methods provided by the worksheet:

This example adds a thin black border to the top, and a thick blue border to the bottom of cells A1 and B1:

pascal
var
      cellA1, cellB1: PCell;
    ...
      cellA1 := MyWorksheet.WriteBorders(0, 0, [cbNorth, cbSouth]);    // cell A1: row 0, column 0
      MyWorksheet.WriteBorderStyle(cellA1, cbNorth, lsThin, scBlack);  
      MyWorksheet.WriteBorderStyle(cellA1, cbSouth, lsThick, scBlue);
    
      cellB1 := MyWorksheet.WriteBorders(0, 1, [cbNorth, cbSouth]);    // cell B1: row 0, column 1
      MyWorksheet.WriteBorderStyles(cellB1, cellA1^.BorderStyles);     // copy all border styles from cell A1 to B1

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Note: Diagonal lines are not supported by sfExcel2 and sfExcel5 - they are just omitted. sfExcel8 and sfOOXML use the same linestyle and color for both diagonals; when writing the border style of the diagonal-up line is assumed to be valid also for the diagonal-down line. Some writers do not support all the line styles of the TsLineStyle enumeration. In this case, appropriate replacement line styles are used.

Fonts

The cell text can displayed in various fonts. For this purpose, the workbook provides a list of TsFont items:

pascal
type
      TsFont = class
        FontName: String;
        Size: Single;   
        Style: TsFontStyles;
        Color: TsColor;
        Position: TsFontPosition;
      end;

Every cell is provided with an index into the font list.

In order to assign a particular font to a cell, use one of the following methods of TsSpreadsheet:

pascal
type
      TsSpreadsheet = class
      public
        function  WriteFont(ARow, ACol: Cardinal; const AFontName: String;
          AFontSize: Single; AFontStyle: TsFontStyles; AFontColor: TsColor): Integer; overload;
        procedure WriteFont(ARow, ACol: Cardinal; AFontIndex: Integer); overload;
        function WriteFontColor(ARow, ACol: Cardinal; AFontColor: TsColor): Integer;
        function WriteFontSize(ARow, ACol: Cardinal; ASize: Integer): Integer;
        function WriteFontStyle(ARow, ACol: Cardinal; AStyle: TsFontStyles): Integer; 
        // plus: overloaded versions accepting a pointer to a cell record instead of the row and column index as parameter
        // ...
      end;

The workbook's font list contains at least one item which is the default font for cells with unmodified fonts. By default, this is 10-point "Arial". Use the workbook method SetDefaultFont to assign a different font to the first list item.

The font at a given index of the font list can be looked up by calling the workbook function GetFont. The count of available fonts is returned by GetFontCount.

Here is an example which decreases the size of all 10-point "Arial" fonts to 9-point:

pascal
var
      i: Integer;
      font: TsFont;
    begin
      for i := 0 to MyWorkbook.GetFontCount-1 do
      begin
        font := MyWorkbook.GetFont(i);
        if (font.FontName = 'Arial') and (font.Size = 10.0) then
          font.Size := 9.0;
      end;
    end;

Rich-text formatting

In addition to using a specific font for each cell it is also possible to specify particular font attributes for individual characters or groups of characters in each cell text. Following the Excel notation, we call this feature Rich-text formatting (although is has nothing in common with the "rich-text" file format).

For this purpose, unit fpstypes declares the type TsRichTextParams which is an array of TsRichTextParam records:

pascal
type
      TsRichTextParam = record
        FontIndex: Integer;
        FirstIndex: Integer;
      end;
    
      TsRichTextParams = array of TsRichTextParam;

FontIndex refers to the index of the font in the workbook's FontList to be used for formatting of the characters beginning at the index FirstIndex. Being a string character index the FirstIndex is 1-based.

There are two ways to add "rich-text" formatting to a cell text:

pascal
MyWorksheet.WriteTextAsHTML(0, 0, 'Area (m<sup>2</sup>');
pascal
var
      richTextParams: TsRichTextParams;
      fnt: TsFont;
      cell: PCell;
    begin
      SetLength(rtp, 2);
      cell := MyWorksheet.GetFont(0, 0);
      fnt := MyWorksheet.ReadCellFont(cell);
      richTextParams[0].FirstIndex := 8; // The superscript groups begins with "2" which is the (1-based) character #8 of the cell text.
      richTextParams[0].FontIndex := MyWorkbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fpSuperscript);
      richTextParams[1].FirstIndex := 9; // Normal font again beginning with character #9.
      richTextParams[1].FontIndex := MyWorksheet.ReadCellFontIndex(0, 0);
      MyWorksheet.WriteUTF8Text(cell, 'Area (m2)', richTextParams);
    end;

Use the worksheet method DeleteRichTextParams to remove rich-text formatting from a previously formatted cell.

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Note: If the cell is supposed to have a font different from the worksheet's default font then this font must be written to the cell before writing the rich-text formatted text. Otherwise the font in the unformatted regions will not be up-to-date.

Text rotation

Usually text is displayed in the cells horizontally. However, it is also possible to rotate it by 90 degrees in clockwise or counterclockwise directions. In addition, there is also an option to stack horizontal characters vertically above each other.

If you need this feature use the worksheet method WriteTextRotation and specify the text direction by an element of the enumeration type TsTextRotation:

pascal
type
      TsTextRotation = (trHorizontal, rt90DegreeClockwiseRotation,
        rt90DegreeCounterClockwiseRotation, rtStacked);
    
      TsWorksheet = class
      public
        function WriteTextRotation(ARow, ACol: Cardinal; ARotation: TsTextRotation): PCell; overload;
        procedure WriteTextRotation(ACell: PCell; ARotation: TsTextRotation); overload;
    
        function ReadTextRotation(ACell: PCell): TsTextRotation;
        // ...
      end;
    
      // example for counter-clockwise rotated text in cell A1:
      WriteTextRotation(0, 0, rt90DegreeCounterClockwiseRotation);

Warning-icon.png

Warning: Finer degrees of rotation which may be supported by some spreadsheet file formats are ignored.

Text alignment

By default, cell texts are aligned to the left and bottom edges of the cell, except for numbers which are right-aligned. This behavior can be changed by using the worksheet methods WriteHorAlignment and WriteVertAlignment:

pascal
type
      TsHorAlignment = (haDefault, haLeft, haCenter, haRight, haJustified, haDistributed, haFilled);
      TsVertAlignment = (vaDefault, vaTop, vaCenter, vaBottom);    
    
      TsWorksheet = class
      public
        function WriteHorAlignment(ARow, ACol: Cardinal; AValue: TsHorAlignment): PCell; overload;
        procedure WriteHorAlignment(ACell: PCell; AValue: TsHorAlignment); overload;
        function ReadHorAlignment(ACell: PCell): TsHorAlignment;
    
        function WriteVertAlignment(ARow, ACol: Cardinal; AValue: TsVertAlignment): PCell; overload; 
        procedure WriteVertAlignment(ACell: PCell; AValue: TsVertAlignment); overload;
        function ReadVertAlignment(ACell: PCell): TsVertAlignment;
        // ...
      end;
    
      // Example: Center the text in cell A1 both horizontally and vertically
      MyWorksheet.WriteHorAlignment(0, 0, haCenter);
      MyWorksheet.WriteVertAlignment(0, 0, vaCenter);

Explanation of special horizontal alignments:

Word wrap

Text which is longer than the width of a cell can wrap into several lines by calling the method WriteWordwrap of the spreadsheet:

pascal
type
      TsWorksheet = class
      public
        function WriteWordwrap(ARow, ACol: Cardinal; AValue: Boolean): PCell; overload;
        procedure WriteWordwrap(ACell: PCell; AValue: Boolean); overload;
        function ReadWordwrap(ACell: PCell): Boolean;
        //...
      end;
    
      // Example: activate wordwrap in cell A1
      MyWorksheet.WriteWordwrap(0, 0, true);

Merged cells

Like the Office applications, FPSpreadsheet supports also to feature of merging cells to a single large cell which is often used as a common header above simlar columns. Simply call MergeCells and pass a parameter to specify the cell range to be merged, either an Excel range string (such as A1:D5), or the first and last rows and columns:

pascal
MyWorksheet.MergeCells('A1:D5');
      // or: MyWorksheet.MergeCells(0, 0, 4, 3);  // first row, first column, last row, last column

The content and format displayed for a merged range is taken from the upper left corner of the range, cell A1 in above example. This cell is called the MergeBase in the library. Except for this corner cell, there must not be any other cells in the range. If there are their contents and format will be hidden.

In order to break up a merged range back up into individual cells, use the command Unmerge and pass any cell that is within the merged range:

pascal
MyWorksheet.UnmergeCells('B1');
      // or: MyWorksheet.UnmergeCells(0, 1);   // row, column of any cell within the range

Merged cells can be read from/written to all file formats except for sfCSV, sfExcel2 and sfExcel5 which do not support this feature natively.

The information which cells are merged is stored in an internal list. Unlike in earlier versions it is no longer possible to access the MergeBase from the cell directly. Use the following functions to extract information on merged cells:

pascal
var
      cell, base: PCell;
      r1,c1,r2,c2: Cardinal;
    ...
      cell := MyWorksheet.FindCell('B1');
      if MyWorksheet.IsMerged(cell) then
      begin
        WriteLn('Cell B1 is merged.');
    
        MyWorksheet.FindMergedRange(cell, r1, c1, r2, c2);
        WriteLn('The merged range is ' + GetCellRangeString(r1, c1, r2, c2));
    
        base := MyWorksheet.FindMergeBase(cell);
        WriteLn('The merge base is cell ' + GetCellString(base^.Row, base^.Col));
      end;

Cell protection

This is described in a separate section below.

Miscellaneous

Disable printing of specific cells

Specific cells can be disabled from printing:

pascal
type
      TsWorksheet = class
      public
        function WriteDoNotPrintCell(ARow, ACol: Cardinal; AValue: boolean): PCell; overload;
        procedure WriteDoNotPrintCell(ACell: PCell; AValue: Boolean); overload;
        function  ReadDoNotPrintCell(ACell: PCell): Boolean;

Additional data

Cell comments

Comments can be attached to any cell by calling

pascal
MyWorksheet.WriteComment(0, 0, 'This is a comment for cell A1');

They are stored in an internal list of the worksheet. Use the corresponding worksheet methods to access comments:

Hyperlinks

Hyperlinks can be attached to cells in order to link cells to other documents or other cells in the same workbook. The general syntax for creating hyperlinks is

pascal
procedure TWorksheet.WriteHyperlink(ARow, ACol: Cardinal; ATarget: String; ATooltip: String = '');

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Note: Hyperlinks can be added to empty cells or to cells with content. In the latter case, the displayed content is not changed by the hyperlink; in the former case the cell is converted to a label cell showing the hyperlink target. Be aware that OpenOffice/LibreOffice only does accept hyperlinks with non-text cells.

Examples:

pascal
// Open the web site www.google.com
      MyWorksheet.WriteText(0, 0, 'Open google');
      MyWorksheet.WriteHyperlink(0, 0, 'http://www.google.com');
    
      // Open the local file with the absolute path "C:\readme.txt" (assuming Windows)
      MyWorksheet.WriteHyperlink(1, 0, 'file:///c:\readme.txt');
    
      // Open the mail client to send a mail
      MyWorksheet.WriteText('Send mail');
      MyWorksheet.WriteHyperlink(3, 0, 'mailto:somebody@gmail.com?subject=Test');
    
      // Jump to a particular cell 
      MyWorksheet.WriteText(5, 0, 'Jump to cell A10 on sheet2');
      MyWorksheet.WriteHyperlink(5, 0, '#Sheet2!A10');
    
      // Jump to cell A10 on the current sheet and display a popup hint
      MyWorksheet.WriteHyperlink(5, 0, '#A10', 'Go to cell A10');

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Note: FPSpreadsheet does not "follow" the links, it only provides a mechanism to get access to the link data. TsWorksheetGrid from the laz_fpspreadsheet_visual package, however, fires the event OnClickHyperlink if a cell with an external hyperlink is clicked for fractions of a second. In the corresponding event handler, you can, for example, load a target spreadsheet, or open a web browser to display the linked web site. If the link is an internal link to another cell within the same workbook then the grid jumps to the related cell.

Defined Names

FPSpreadsheet allows to assign names to cells and cell ranges, simular to Excel and Calc. Since such "defined names" can be used in formulas the readability of formulas can be greatly improved.

A defined name is a simple class of type TsDefinedName with a string property Name and a record property Range of type TsCellRange3D which lists the row and column indices of the top/left and bottom/right corners of the cell range, as well as the worksheet indices of these two corner points.

pascal
type
      TsDefinedName = class
      ...
      public
        function RangeAsString(AWorkbook: TsBasicWorkbook): String;
        function RangeAsString_ODS(AWorkbook: TsBasicWorkbook): String;
        class function ValidName(AName: String): Boolean;
        property Name: String;
        property Range: TsCellRange3D;
      end;

A useful function may be the class function ValidName which checks the validity of a name:

The TsDefinedName methods RangeAsString and RangeAsString_ODS return the defined range's Range parameters as a string in Excel and ODS syntax, respectively.

The workbook and each worksheet have a list property DefinedNames which collects the defined names. The defined names stored in the workbook have global scope while those stored in worksheets are valid only locally within that sheet.

pascal
var
      idxCell, idxRange: Integer;
    ...
      // Global defined name
      idxCell := workbook.DefinedNames.Add(AName: string; ASheetIndex: Integer; ARow, ACol: Cardinal);
      idxRange := workbook.DefinedNames.Add(AName: String; ASheetIndex1, ASheetIndex2, ARow1, ACol1, ARow2, ACol2: Cardinal);
      // Local defined name
      idxCell := worksheet.DefinedNames.Add(AName: string; ASheetIndex: Integer; ARow, ACol: Cardinal);
      idxRange := worksheet.DefinedNames.Add(AName: String; ASheetIndex1, ASheetIndex2, ARow1, ACol1, ARow2, ACol2: Cardinal);
pascal
var
      defName: TsDefinedName;
      i: Integer;
    ...
      for i := 0 to workbook.DefinedNames.Count-1 do
      begin
        defName := workbook.DefinedNames[i];
        WriteLn('Index ', i, ': Name="', defName.Name, '", Range=', defName.RangeAsString(workbook));
      end;

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Note: Unlike Excel and ODS, local defined names are not allowed to have the same names as global defined names. Cross-worksheet local defined names are not allowed either.

Images

FPSpreadsheet supports embedding of images in worksheets. Use one of the worksheet methods WriteImage() to add an image to the worksheet:

pascal
MyWorksheet.WriteImage(row, col, filename, offsetX, offsetY, scaleX, scaleY);
      MyWorksheet.WriteImage(row, col, stream, offsetX, offsetY, scaleX, scaleY);
      MyWorksheet.WriteImage(row, col, imageindex, offsetX, offsetY, scaleX, scaleY);

The upper/left corner of the image is placed at the upper/left corner of the cell in the specified row and column. The floating point parameters offsetX, offsetY, scaleX and scaleY are optional: they define an offset of this image anchor point from the cell corner and a magnification factor. The path to the image file is given as parameter filename. Alternatively, overloaded versions can be used which accept a stream in place of the file name or an image index in the workbook's EmbeddedObj list - use MyWorkbook.FindEmbeddedObj(filename) to get this index for a previously loaded image file.

Note that FPSpreadsheet needs to know the image type for successfull picture import. Currently, the types png , jpg , tiff , bmp , gif , svg , wmf , emf , and pcx are supported (Excel2007 cannot read imported svg and pcx images). Other formats can be registered by writing a function which determines the image size and pixel density, and by registering the new format using the procedure RegisterImageType - see unit fpsImages for examples:

pascal
type
      TsImageType = integer;
      TGetImageSizeFunc = function (AStream: TStream; out AWidth, AHeight: DWord; out dpiX, dpiY: Double): Boolean;
    
    function RegisterImageType(AMimeType, AExtension: String; AGetImageSize: TGetImageSizeFunc): TsImageType;

Due to differences in row height and column width calculation between FPSpreadsheet and Office applications it is not possible to position images correctly. If exact image positions are important you should follow these rules:

Sorting

Cells in a worksheet can be sorted for a variety of criteria by calling the Sort method of the worksheet. This method takes a TsSortParams record and the edges of the cell rectangle to be sorted as parameters; in an overloaded version, the cell rectangle can also be specified by means of an Excel-type range string (e.g. 'A1:G10'):

pascal
type
      TsWorksheet = class
        // ...
        procedure Sort(const ASortParams: TsSortParams;
          ARowFrom, AColFrom, ARowTo, AColTo: Cardinal); overload;
        procedure Sort(ASortParams: TsSortParams; ARange: String); overload;
        // ...
      end;

The sorting criteria are defined by a record of type TsSortParams:

pascal
type
      TsSortParams = record
        SortByCols: Boolean;
        Priority: TsSortPriority;  // spNumAlpha ("Numbers first"), or spAlphaNum ("Text first")
        Keys: TsSortKeys;
      end;    
    
      TsSortKey = record
        ColRowIndex: Integer;
        Options: TsSortOptions;    // set of [spDescending, spCaseInsensitive]
      end;

InitSortParams is a handy utility to initialize the sorting parameters:

pascal
function InitSortParams(ASortByCols: Boolean = true; ANumSortKeys: Integer = 1;
      ASortPriority: TsSortPriority = spNumAlpha): TsSortParams;

The next code fragment shows a typical sorting call:

pascal
var
      sortParams: TsSortParams;
    begin
      sortParams := InitSortParams(true, 2);  // sorting along columns, 2 sorting keys
    
      // primary sorting key: column 3, ascending, case-insensitive
      sortParams.Keys[0].ColRowIndex := 3;
      sortParams.Keys[0].Options := [ssoCaseInsensitive];
    
      // secondary sorting key: colum 1, descending
      sortParams.Keys[1].ColRowIndex := 1;
      sortParams.Keys[1].Options := [ssoDescending];
    
      // The sorted block extends between cells A1 (row=0, col=0) and F10 (row=9, col=5)
      MyWorksheet.Sort(sortParams, 0, 0, 9, 5);
      // or: MyWorksheet.Sort(sortParams, 'A1:F10');
    end;

Searching and replacing

Unit fpsSearch implements a search engine which can be used to look for specific cell content within a workbook, or to replace the found cell content by some other string.

Example:

pascal
uses
      fpsTypes, fpSpreadsheet, fpsUtils, fpsSearch, fpsAllFormats;
    var
      MyWorkbook: TsWorkbook;
      foundWorksheet: TsWorksheet;
      foundRow, foundCol: Cardinal;
      MySearchParams: TsSearchParams;
    begin
      MyWorkbook := TsWorkbook.Create;
      try
        MyWorkbook.ReadFromFile(AFileName);
    
        // Specify search criteria
        MySearchParams.SearchText := 'Hallo';
        MySearchParams.Options := [soEntireDocument];
        MySearchParams.Within := swWorkbook;
    
        // or: MySearchParaams := InitSearchParams('Hallo', [soEntireDocument], swWorkbook);
    
        // Create search engine and execute search
        with TsSearchEngine.Create(MyWorkbook) do begin
          if FindFirst(MySearchParams, foundWorksheet, foundRow, foundCol) then begin
            WriteLn('First "', MySearchparams.SearchText, '" found in cell ', GetCellString(foundRow, foundCol), ' of worksheet ', foundWorksheet.Name);
            while FindNext(MySeachParams, foundWorksheet, foundRow, foundCol) do
              WriteLn('Next "', MySearchParams.SearchText, '" found in cell ', GetCellString(foundRow, foundCol), ' of worksheet ', foundWorksheet.Name);
          end;
          Free;
        end;
      finally
        MyWorkbook.Free;
      end;
    end;

The search engine provides two methods for searching : FindFirst and FindNext. They are very similar, they only differ in where the search begins. In case of FindFirst, the starting cell is determined from the Options described below. In case of FindNext the search begins at the cell adjacent to the previously found cell. Both methods return the worksheet and row and column indexes of the cell in which the search text is found. If the search is not successful then the function result is FALSE, and the foundWorksheet is nil. It is clear that the foundWorksheet cannot be used for anything else while the search is running.

The record TsSearchParams specifies the criteria used for searching:

pascal
type
      TsSearchParams = record
        SearchText: String;
        Options: TsSearchOptions;
        Within: TsSearchWithin;
      end;

Besides the text to be searched (SearchText) it provides a set of options to narrow the search:

The record field Within identifies the part of the spreadsheet to be searched:

The search params record can be initialized by calling InitSearchParams (in unit fpsutils) with the record elements as optional parameters. Use the methods Workbook.ActiveWorksheet and Worksheet.SelectCell(ARow, ACol) to define the active worksheet and the position of the active cell, respectively, if needed by the search.

In addition to searching the search engine can also be used for replacing the found text by another string. Call the functions ReplaceFirst or ReplaceNext for this purpose. They act like their FindXXXX counterparts, therefore, they require a TsSearchParams record to specify the search criteria. But in addition to searching, these functions also perform the text replacement according to the specification in a TsReplaceParams record:

pascal
type
      TsReplaceParams = record
        ReplaceText: String;
        Options: TsReplaceOptions;
      end;

The ReplaceText identifies the string which will replace the found text pattern. The Options define a set of criteria how the replacement is done:

Use the function InitReplaceParams (in unit fpsutils) to initialize the replace parameters record with the provided (but optional) values.

Column and row operations

The worksheet provides these methods for inserting, deleting, hiding or unhiding columns and rows:

pascal
type
      TsWorksheet = class
      ...
        procedure DeleteCol(ACol: Cardinal);
        procedure DeleteRow(ARow: Cardinal);
    
        procedure InsertCol(ACol: Cardinal);
        procedure InsertRow(ARow: Cardinal);
    
        procedure RemoveCol(ACol: Cardinal);
        procedure RemoveRow(ARow: Cardinal);
    
        procedure RemoveAllCols;
        procedure RemoveAllRows
    
        procedure HideCol(ACol: Cardinal);
        procedure HideRow(ARow: Cardinal);
        
        procedure ShowCol(ACol: Cardinal);
        procedure ShowRow(ARow: Cardinal);
    
        function ColHidden(ACol: Cardinal): Boolean;
        function RowHidden(ARow: Cardinal): Boolean;

Page layout

General

So far, FPSpreadsheet does not support printing of worksheets, but the Office applications do, and they provide a section of information in their files for this purpose. In FPSpreadsheets this information is available in the TsPageLayout class which belongs to the TsWorksheet data structure. Its properties and methods combine the most important features from the Excel and OpenDocument worlds.

pascal
type 
      TsPageOrientation = (spoPortrait, spoLandscape);
    
      TsPrintOption = (poPrintGridLines, poPrintHeaders, poPrintPagesByRows,
        poMonochrome, poDraftQuality, poPrintCellComments, poDefaultOrientation,
        poUseStartPageNumber, poCommentsAtEnd, poHorCentered, poVertCentered,
        poDifferentOddEven, poDifferentFirst, poFitPages);
    
      TsPrintOptions = set of TsPrintOption;  
    
      TsHeaderFooterSectionIndex = (hfsLeft, hfsCenter, hfsRight);
    
      TsCellRange = record
        Row1, Col1, Row2, Col2: Cardinal;
      end;
    
      TsPageLayout = class
      ...
      public
        ...
        { Methods }
        // embedded header/footer images
        procedure AddHeaderImage(AHeaderIndex: Integer;
          ASection: TsHeaderFooterSectionIndex; const AFilename: String);
        procedure AddFooterImage(AFooterIndex: Integer;
          ASection: TsHeaderFooterSectionIndex; const AFilename: String);
        procedure GetImageSections(out AHeaderTags, AFooterTags: String);
        function HasHeaderFooterImages: Boolean;
    
        // Repeated rows and columns 
        function HasRepeatedCols: Boolean;
        function HasRepeatedRows: Boolean;
        procedure SetRepeatedCols(AFirstCol, ALastCol: Cardinal);
        procedure SetRepeatedRows(AFirstRow, ALastRow: Cardinal);
    
        // print ranges 
        function AddPrintRange(ARow1, ACol1, ARow2, ACol2: Cardinal): Integer; overload;
        function AddPrintRange(const ARange: TsCellRange): Integer; overload;
        function GetPrintRange(AIndex: Integer): TsCellRange;
        function NumPrintRanges: Integer;
        procedure RemovePrintRange(AIndex: Integer);
    
        { Properties }
        property Orientation: TsPageOrientation read FOrientation write FOrientation;
        property PageWidth: Double read FPageWidth write FPageWidth;
        property PageHeight: Double read FPageHeight write FPageHeight;
        property LeftMargin: Double read FLeftMargin write FLeftMargin;
        property RightMargin: Double read FRightMargin write FRightMargin;
        property TopMargin: Double read FTopMargin write FTopMargin;
        property BottomMargin: Double read FBottomMargin write FBottomMargin;
        property HeaderMargin: Double read FHeaderMargin write FHeaderMargin;
        property FooterMargin: Double read FFooterMargin write FFooterMargin;
        property StartPageNumber: Integer read FStartPageNumber write SetStartPageNumber;
        property ScalingFactor: Integer read FScalingFactor write SetScalingFactor;
        property FitHeightToPages: Integer read FFitHeightToPages write SetFitHeightToPages;
        property FitWidthToPages: Integer read FFitWidthToPages write SetFitWidthToPages;
        property Copies: Integer read FCopies write FCopies;
        property Options: TsPrintOptions read FOptions write FOptions;
        property Headers[AIndex: Integer]: String read GetHeaders write SetHeaders;
        property Footers[AIndex: Integer]: String read GetFooters write SetFooters;
        property RepeatedCols: TsRowColRange read FRepeatedCols;
        property RepeatedRows: TsRowColRange read FRepeatedRows;
        property PrintRange[AIndex: Integer]: TsCellRange read GetPrintRange;
        property FooterImages[ASection: TsHeaderFooterSectionIndex]: TsHeaderFooterImage read GetFooterImages;
        property HeaderImages[ASection: TsHeaderFooterSectionIndex]: TsHeaderFooterImage read GetHeaderImages;
      end;
    
      TsWorksheet = class
      ...
      public
        property PageLayout: TsPageLayout;
        ...
      end;

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Note: The fact that the PageLayout belongs to the worksheet indicates that there can be several page layouts in the same workbook, one for each worksheet.

pascal
MyWorksheet.PageLayout.Options := MyWorksheet.PageLayout.Options + [poFitPages];
      MyWorksheet.PageLayout.FitWidthToPages := 1;     // all columns on one page width
      MyWorksheet.PageLayout.FitHeightToPages := 0;    // use as many pages as needed

Headers and footers

Header and footer texts can be composed of left-aligned, centered and right-aligned strings. Add the symbol &L to indicate that the following string is to be printed as the left-aligned part; use &C accordingly for the centered and &R for the right-aligned parts. There are other symbols which will be replaced by their counterparts during printing:

The arrays Headers[]/Footers[] provide space for usage of three different headers or footers:

Leave the strings at index 0 and 2 empty if the print-out should always have the same header/footer. You can use the constant HEADER_FOOTER_INDEX_ALL for better clarity. Example:

pascal
MyWorksheet.PageLayout.Headers[HEADER_FOOTER_INDEX_ALL] := '&C&D &T';           // centered "date time" on all pages as header
      MyWorksheet.PageLayout.Footers[HEADER_FOOTER_INDEX_ODD] := '&RPage &P of &N';   // right-aligned "Page .. of ..." on odd pages as footer
      MyWorksheet.PageLayout.Footers[HEADER_FOOTER_INDEX_EVEN] := '&LPage &P of &N';  // dto, but left-aligned on even pages

Protection

In the Office applications, workbooks can be protected from unintentional changes by the user. fpspreadsheet is able to read and write the data structures related to protection, but does not enforce them. This means, for example, that cells can be modified by the user although the worksheet is specified as being locked.

Protection is handled at three levels: workbook protection, worksheet protection and cell protection.

Workbook protection

TsWorkbook contains a set of workbook or document protection options:

In relation to workbook protection is the worksheet option soPanesProtection which prevents the panes of a worksheet from being modified if the workbook is protected.

Depending on the file format, only some of these options might be supported. In these cases, the non-supported options are commonly accepted default values.

Office applications are able to encrypt their spreadsheet files. The readers of FPSpreadsheet basically are not able to open these files. However, there exists a related package, laz_fpspreadsheet_crypto.lpk , which has access to decryption routines and is able to read xlsx and ods files. These readers are in the units xlsxOOXML_crypto and fpsOpendocument_crypto , respectively. Adding them to the uses clause of the application installs user-provided readers with FormatID sfidOOXML_crypto and sfidOpenDocument_crypto, respectively. If the password is known it can be specified as a parameter to the workbook's LoadFromFile/ReadFromStream methods. If no password is specified the workbook fires the event OnQueryPassword in which the user can provide the password, e.g. like this:

pascal
function TForm1.QueryPasswordHandler: String;
    begin
      Result := InputBox('Password required', 'Password', '');
    end;
    
    procedure TForm1.LoadWorkbook(AFileName: String);
    var 
      workbook: TsWorkbook;
    begin
      workbook := TsWorkbook.Create;
      try
        workbook.OnQueryPassword := @QueryPasswordHandler;
        workbook.ReadFromFile(AFileName);
        ...
      finally
        workbook.Free;
      end;
    end;
    
    // or
    
    procedure TForm1.LoadWorkbookWithPassword(AFileName, APassword: STring);
    var
      workbook: TsWorkbook;
    begin
      workbook := TsWorkbook.Create;
      try
        workbook.ReadFromFile(AFileName, APassword);
        ...

Worksheet protection

TsWorksheet houses a similar set of protection options. Whenever an option is included in the set Protection of the workbook the corresponding action is not allowed and locked:

These levels of protection become active if the option soProtected is added to the worksheet's Options, or by calling the worksheet method Protect(true).

Cell protection

Cell protection becomes active when the worksheet protection is enabled. It is controlled by a set of TsCellProtection elements which belong to the cell format record:

Cell protection can be changed by calling the worksheet method WriteCellProtection. Conversely, ReadCellProtection can be used to retrieve the protection state of a particular cell:

pascal
// query and modifiy the protection state of cell A1 (row=0, col=0)
    var
      cell: PCell;
      cellprot: TsCellProtections;
    ...
      // Find the cell
      cell := worksheet.FindCell(0, 0);
      // query cell protection
      cellprot := worksheet.ReadCellProtection(cell);
      // Unlock the cell for editing, don't change the visibility of formulas
      worksheet.WriteCellProtection(cell, cellprot - [cpLockCell]);
      // Hide formula of the cell and unlock the cell.
      worksheet.WriteCellProtection(cell, [cpHideFormulas]);
      // Activate protection
      worksheet.Protect(true);

Passwords

Workbook and worksheet protection can be secured by passwords. Note that these passwords do not encrypt the file (except for workbook protection in Excel 2007). In the Office applications the user must enter this password to turn off protection or to change protection items. The encrypted password is stored in the CryptoInfo record of the wordbook and the worksheets, respectively:

pascal
type
      TsCryptoInfo = record
        PasswordHash: String;
        Algorithm: TsCryptoAlgorithm;  // caExcel, caSHA1, caSHA256, etc.
        SaltValue: String;
        SpinCount: Integer;
      end;

Warning-icon.png

Warning: FPSpreadsheet does not perform any hashing calculations, the CryptoInfo record is just passed through from reading to writing. This causes problems when different file formats are involved in reading and writing. It is attempted to detect incompatible combinations. In these cases, the password protection is removed , and an error is logged by the workbook.

Loading and saving

Adding new file formats

FPSpreadsheet is open to any spreadsheet file format. In addition to the built-in file formats which are specified by one of the sfXXXX declarations, it is possible to provide dedicated reader and writer units to get access to special file formats.

pascal
function RegisterSpreadFormat(AFormat: TsSpreadsheetFormat; AReaderClass: TsSpreadReaderClass; AWriterClass: TsSpreadWriterClass;
      AFormatName, ATechnicalName: String; const AFileExtensions: array of String): TsSpreadFormatID;

Stream selection

Workbooks are loaded and saved by means of the ReadFromFile and WriteToFile methods, respectively (or by their stream counterparts, ReadFromStream and WriteToStream).

By default, the data files are accessed by means of memory streams which yields the fastest access to the files. In case of very large files (e.g. tens of thousands of rows), however, the system may run out of memory. There are two methods to defer the memory overflow by some extent.

Virtual mode

Beyond the transient memory usage during reading/writing the main memory consumptions originates in the internal structure of FPSpreadsheet which holds all data in memory. To overcome this limitation, a "virtual mode" has been introduced. In this mode, data are received from a data source (such as a database table) and are passed through to the writer without being collected in the worksheet. It is clear that data loaded in virtual mode cannot be displayed in the visual controls. Virtual mode is good for conversion between different data formats.

These are the steps required to use this mode:

Virtual mode also works for reading spreadsheet files.

The folder example/other contains a worked out sample project demonstrating virtual mode using random data. More realistic database examples are in example/db_import_export and in the chapter on converting a large database table using virtual mode.

Dataset export

FPC contains a set of units that allow you to export datasets to various formats (XML, SQL statements, DBF files,...). There is a master package that allows you to choose an export format at design time or run time (Lazarus package lazdbexport).

FPSpreadsheet has TFPSExport which plugs into this system. It allows you to export the contents of a dataset to a new spreadsheet (.xls , .xlsx , .ods , wikitable format) file into a table on the first sheet by default. In addition, if MultipleSheets is set to TRUE it is possible to combine several sheets into individual worksheets in the same file. You can optionally include the field names as header cells on the first row using the HeaderRow properties in the export settings. The export component tries to find the number format of the cells according to the dataset field types.

For more complicated exports, you need to manually code a solution (see examples below) but for simple data transfer/dynamic exports at user request, this unit will probably be sufficient.

A simple example of how this works:

pascal
uses
    ...
    fpsexport
    ...
    var
      Exp: TFPSExport;
      ExpSettings: TFPSExportFormatSettings;
      TheDate: TDateTime;
    begin
      FDataset.First; //assume we have a dataset called FDataset
      Exp := TFPSExport.Create(nil);
      ExpSettings := TFPSExportFormatSettings.Create(true);
      try
        ExpSettings.ExportFormat := efXLS; // choose file format
        ExpSettings.HeaderRow := true; // include header row with field names
        Exp.FormatSettings := ExpSettings; // apply settings to export object
        Exp.Dataset:=FDataset; // specify source
        Exp.FileName := 'c:\temp\datadump.xls';
        Exp.Execute; // run the export
      finally
        Exp.Free;
        ExpSettings.Free;
      end;

Export to DBF

You can save the information from Excel to dbf rather easily. Here is the example from forum. Please note that this example is supposed to work with Win1251 encoding by default. To get more information please refer to this thread 1(http://forum.lazarus.freepascal.org/index.php/topic,41636.0.html)

pascal
procedure TForm1.ExportToDBF(AWorksheet: TsWorksheet; AFileName: String);
    var
      i: Integer;
      f: TField;
      r, c: Cardinal;
      cell: PCell;
    begin
      DbfGlobals.DefaultCreateCodePage := 1251; //default encoding of the dbf
      DbfGlobals.DefaultOpenCodePage := 1251; //default encoding of the dbf
      if Dbf1.Active then Dbf1.Close;
      if FileExists(AFileName) then DeleteFile(AFileName);
    
      Dbf1.FilePathFull := ExtractFilePath(AFileName);
      Dbf1.TableName := ExtractFileName(AFileName);
      Dbf1.TableLevel := 25;  // DBase IV: 4 - most widely used; or 25 = FoxPro supports nfCurrency
      Dbf1.LanguageID := $C9; //russian language by default
      Dbf1.FieldDefs.Clear;
      //below are the fields in excel
      Dbf1.FieldDefs.Add('fam', ftString);
      //add other fields you want to save
    
      Dbf1.CreateTable;
      Dbf1.Open;
    
      for f in Dbf1.Fields do
        f.OnGetText := @DbfGetTextHandler;
    
      // Skip row 0 which contains the headers
      for r := 1 to AWorksheet.GetLastRowIndex do begin
        Dbf1.Append;
        for c := 0 to Dbf1.FieldDefs.Count-1 do begin
          f := Dbf1.Fields[c];
          cell := AWorksheet.FindCell(r, c);
          if cell = nil then
            f.Value := NULL
          else
            case cell^.ContentType of
              cctUTF8String: f.AsString := UTF8ToCP1251(cell^.UTF8StringValue);
              cctNumber: f.AsFloat := cell^.NumberValue;
              cctDateTime: f.AsDateTime := cell^.DateTimeValue;
              else f.AsString := UTF8ToCP1251(AWorksheet.ReadAsText(cell));
            end;
        end;
        Dbf1.Post;
      end;
    end;
    
    //This procedure is called so the text in the cells could be correctly dispayed on WorkSheetGrid on the form, otherwise '?' symbols showing
    procedure TForm1.DbfGetTextHandler(Sender: TField; var AText: string; DisplayText: Boolean);
    begin
      if DisplayText then
        AText := CP1251ToUTF8(Sender.AsString);
    end;

Visual controls for FPSpreadsheet

The package laz_fpspreadsheet_visual implements a series of controls which simiplify creation of visual GUI applications:

See the FPSpreadsheet tutorial: Writing a mini spreadsheet application for more information and a tutorial, and see demo projects for examples of the application of these components.

Examples

Please see FPSpreadsheet: Examples for a variety of code examples.

Download

Subversion

You can download FPSpreadsheet using the subversion software and the following command line:

pascal
svn checkout https://svn.code.sf.net/p/lazarus-ccr/svn/components/fpspreadsheet fpspreadsheet

Stable releases

The most current release is distributed by the Online-Package-Manger which is integrated in the Lazarus IDE (menu "Package" > "Online package manager"): Scroll down the list of available packages, check the entry "FPSpreadsheet" and click "Install". Confirm the prompt to rebuild the IDE. When the process is complete you find the new components in palette "FPSpreadsheet".

Older releases of FPSpreadsheet cann still be found on sourceforge.

Installation

Conditional defines

Here is a list of conditional defines which can be activated in order to tweak some operating modes of the packages and/or make it compilable with older Lazarus/FPC versions:

All these defines are collected in the include file fps.inc.

In the most recent test (Feb 2023), all fpspreadsheet packages compile fine with Laz 1.6+ / fpc 3.0+ (some defines in fps.inc may have to be adapted, though). With Laz 1.4 / fpc 2.6.4 or older, fpspreadsheet_dataset.lpk and fpspreadsheet_crypto.lpk cannot be used any more.

Support and Bug Reporting

The recommended place to discuss FPSpreadsheet and obtain support is asking in the Lazarus Forum.

Bug reports should be sent to the Lazarus/Free Pascal Bug Tracker; please specify the "Lazarus-CCR" project.

Current Progress

Progress by supported cell content

Format Multiple · sheets Unicode Reader · support Writer · support Text Number String · Formula RPN · Formula 3D cell · references Date/Time Comments Hyperlinks Images +++ Protection Conditional · formats
CSV files No Yes + Working ++ Working ++ Working ++ Working ++ N/A N/A N/A Working ++ N/A N/A N/A N/A N/A
Excel 2.x No No * Working ** Working Working Working Working Working *** N/A Working **** Working N/A N/A Working N/A
Excel 5.0 (Excel 5.0 and 95) Yes No * Working ** Working Working Working Working Working *** Working Working **** Working N/A N/A Working N/A
Excel 8.0 (Excel 97- 2003) Yes Yes Working ** Working Working Working Working Working *** Working Working **** Reading only Working Not working Working Not working
Excel 2003/XML Yes Yes Working ** Working Working Working Working *** Working Working Working **** Working Working N/A Working Working
Excel OOXML Yes Yes Working ** Working Working Working Working *** Working Working Working **** Working Working Working Working Working ++++
OpenDocument Yes Yes Working ** Working Working Working Working *** Working Working Working **** Working Working Working Working Working
HTML No Yes Working ++ Working ++ Working ++ Working ++ N/A N/A N/A Working ++ N/A Working Not working N/A N/A
Wikitable files (Mediawiki) No Yes planned Working ++ Working ++ Working ++ N/A N/A N/A Working ++ N/A N/A Not working N/A N/A

(+) Depends on file.
(++) No "true" number format support because the file does not containg number formatting information. But the number format currently used in the spreadsheet understood.
(+++) Only very basic image support: no transformations, no cropping, no image manipulation.
(++++) Extended OOXML formatting options not supported.
() In formats which don't support Unicode the data is stored by default as ISO 8859-1 (Latin 1). You can change the encoding in TsWorkbook.Encoding. Note that FPSpreadsheet offers UTF-8 read and write routines, but the data might be converted to ISO when reading or writing to the disk. Be careful that characters which don't fit selected encoding will be lost in those operations. The remarks here are only valid for formats which don't support Unicode.
() Some cell could be returned blank due to missing or non ready implemented number and text formats.
(
) This is the format in which the formulas are written to file (determined by design of the file format).
(****) Writing of all formats is supported. Some rare custom formats, however, may not be recognized correctly. BIFF2 supports only built-in formats by design.

Progress of the formatting options

The following formatting options are available:

Format Text · alignment Text · rotation Font Rich · text Border Color · support Back · ground Word · wrap Col&Row · size Number · format Merged · cells Page · layout Print · ranges Header/footer · images Column/row · format Hide · cols/rows Page · breaks
CSV files N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A
Excel 2.x Working * N/A Working N/A Working Working Working** N/A Working Working N/A Working N/A N/A Working N/A Working
Excel 5.0 · (Excel 5.0 and 95) Working Working Working Working Working Working Working Working Working Working N/A Working Working N/A Working Working Working
Excel 8.0 · (Excel 97 - XP) Working Working Working Working Working Working Working Working Working Working Working Working Working Not working Working Working Working
Excel 2003/XML Working Working Working Working Working Working Working Working Working Working Working Working Working N/A Working Wworking Working
Excel OOXML (xlsx) Working Working Working Working Working Working Working Working Working Working Working Working Working Working Working Working Working
OpenDocument Working Working Working Working Working Working Working*** Working Working Working Working Working Working Working Working Working
HTML (+) Working bugs Working Working bugs Working Working **** Writing only Writing only N/A Working N/A N/A Not working Writing only to be done N/A
Wikitable (Mediawiki) Writing only N/A Writing only Not working Writing only Writing only Writing only Writing only N/A Writing only N/A N/A Not working Writing only to be done N/A

(N/A) Feature is not available for this format intrinsically.
() BIFF2 supports only horizontal text alignment, vertical alignment is ignored.
() BIFF2 does not support a background color; a dotted black&white background is used instead.
(
) OpenDocument supports only uniform backgrounds; a fill color interpolated between foreground and background colors is written instead.
(****) Only uniform background color, no fill styles.
(+) HTML reader does not support styles. Since the writer does use styles these files are not read back correctly.

Progress of workbook/worksheet user-interface options

Some additional options were added to interface the file contents with the TsWorksheetGrid:

Format Hide grid lines Hide headers Frozen Panes Active sheet/cell Zooming BiDi mode Tab color
Excel 2.x Working Working not working N/A N/A N/A N/A
Excel 5.0 (Excel 5.0 and 95) Working Working Working Working Working N/A N/A
Excel 8.0 (Excel 97 - XP) Working Working Working Working Working Working Working
Excel2003/XML Working Working Working Working Working Working N/A
Excel OOXML Working Working Working Working Working Working Working
OpenDocument Working Working Working Working Working Working Working
HTML Writing only Writing only N/A N/A N/A not working N/A

To do list

Note: this list is provisional, maintained by developers and can change without notice. If you are interested in contributing, please feel free to get in touch and submit a patch - thanks!

Long-term:

Changelog

SVN

Changes with respect to current release

Incompatible changes

Version 1.16

This is the latest stable release.

Changes with respect to v1.14

Incompatible changes

Version 1.14

Changes with respect to v1.12

Incompatible changes

Version 1.12

Changes with respect to v1.10x

Version 1.10.1

Changes with respect to v1.8x

Incompatible changes

Version 1.8

Changes with respect to v1.6x

Incompatible changes

Version 1.6

Changes with respect to v1.4.x

Incompatible changes

Version 1.4

Changes with respect to v1.2.x

Incompatible changes

License

LGPL with static linking exception. This is the same license as is used in the Lazarus Component Library.

References

Documentation

FPSpreadsheet is documented in this wiki file.

Every release of FPSpreadsheet is accompanied by a snapshot of the current wiki files. There is also an api documentation created from the embedded comments in the source files. Both files are in the chm format.

This wiki page is work in progress and updated whenever a new feature is added; therefore, its state corresponds to the svn trunk version of the package. If you work with an older stable version please use these "historic" wiki versions:

Wiki links

External Links


From the Free Pascal wiki, page "FPSpreadsheet", as the Internet Archive kept it on 2025-01-24, last changed on 2024-08-28. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 4, last changed by WikiArchive .

Edited on wiki.freepascal.org by 26 people, 2005–2024

From the official wiki's backup of 26 May 2024: who edited this page there, and when. Edits made there after that date were not recorded, and the earlier versions are not shown here; the main page says why.

WhenWhoWhat changed
SekelsenmatProgress of the formatting options
SekelsenmatNew page: Because of it's very simple format, it's easy to generate Excel 2.1 files from code. New Excel versions are still capable of reading those files, so this can be enough to automate the gene...
Sekelsenmat
Sekelsenmat
SekelsenmatSubversion
SekelsenmatSubversion
Sekelsenmat
GgeldenhuysLicense
Sekelsenmat
SekelsenmatCurrent Progress
SekelsenmatExcel 5 example
Sekelsenmat
Sekelsenmat
DblaszijkCurrent Progress
SekelsenmatCurrent Progress
SekelsenmatCurrent Progress
SekelsenmatChangelog
SekelsenmatCurrent Progress
SekelsenmatChangelog
SekelsenmatChangelog
SekelsenmatExternal Links
Sekelsenmat
SekelsenmatCurrent Progress
MarcovCurrent Progress
SekelsenmatCurrent Progress
JoshyCurrent Progress
SekelsenmatCurrent Progress
Sekelsenmat
SekelsenmatCurrent Progress
SekelsenmatCurrent Progress
SajgonExcel 5 example
SekelsenmatCurrent Progress
SekelsenmatCurrent Progress
SekelsenmatCurrent Progress
SekelsenmatCurrent Progress
Sekelsenmat
SekelsenmatCurrent Progress
SekelsenmatExamples
GgeldenhuysLicense: Clearer definition of the lisence. (minor)
Sekelsenmat
SekelsenmatConverting a database to a spreadsheet
SwenConverting a database to a spreadsheet (minor)
SwenConverting a database to a spreadsheet (minor)
SwenConverting a database to a spreadsheet (minor)
4yma
4yma
4yma
SekelsenmatBuilt-in routines
SekelsenmatPackages
SekelsenmatExamples
SekelsenmatConverting between two spreadsheet formats
Chronos
SekelsenmatCurrent Progress
SekelsenmatCurrent Progress
SekelsenmatProgress of the formatting options
SekelsenmatExamples
SekelsenmatUsing formatting options
SekelsenmatSettings a Border and a Background Color
SekelsenmatSetting a Background Color
SekelsenmatProgress of the formatting options
SekelsenmatSetting a Background Color
SekelsenmatProgress of the formatting options
SekelsenmatRPN Formulas
SekelsenmatCurrent Progress
SekelsenmatFormulas
SekelsenmatUsing ranges of cells and the unary SUM operator
SekelsenmatUsing formatting options
SekelsenmatCharting and FPSpreadsheet
BoboUsing build-in routines
SekelsenmatDownload
SekelsenmatSupport and Bug Reporting
SekelsenmatSee also
GarydaleAdded my own sample code to open an arbitrary spreadsheet
GarydaleOpening an existing spreadsheet: corrected code for SXC (minor)
GarydaleOpening an existing spreadsheet: added var declarations I'd missed in cut and paste. (minor)
GarydaleOpening an existing spreadsheet: removed SXC extension after discovering that I can't open them (minor)
GarydaleOpening an existing spreadsheet: simplified code to use fpspreadsheet consts and also ExtractFileExt
GarydaleOpening an existing spreadsheet: formatting correction (minor)
GarydaleOpening an existing spreadsheet: another formatting correction (minor)
GarydaleCurrent Progress: added information about the CSV file type which is mentioned in the source but not implemented
GarydaleOpening an existing spreadsheet: added mention of the fpspreadsheet open function
GarydaleOpening an existing spreadsheet: Added a WriteToFIle procedure to complement the ReadFromFile procedure I described
GarydaleOpening an existing spreadsheet: changed to use patches to fpspreadsheet using the latest code I've submitted
GarydaleWriting a spreadsheet to file based on extension: used the latest code I submitted.
GarydaleWriting a spreadsheet to file based on extension: aded an e.g. to clarify
SekelsenmatOpening an existing spreadsheet
SekelsenmatOpening an existing spreadsheet
SekelsenmatOpening an existing spreadsheet
SekelsenmatCurrent Progress
SekelsenmatProgress of the formatting options
BigChimpConverting a database to a spreadsheet: Fields[i].FieldName instead of Field[i].FieldName
BigChimpConverting a database to a spreadsheet: it is tested now, but I didn't use fpsallofrmats, fpspreadsheet_pkg (minor)
BigChimpConverting a database to a spreadsheet: fpspreadsheet_pkg, fpsallformats units not necessary (minor)
SekelsenmatConverting a database to a spreadsheet: fpsallformats is really necessary, otherwise there is no output support
SekelsenmatDownload
SekelsenmatSubversion
SekelsenmatLatest release
SekelsenmatChangelog
SekelsenmatCurrent Progress
SekelsenmatCurrent Progress
VincentText replace - "delphi>" to "syntaxhighlight>" (minor)
Chronoswikitable
SekelsenmatProgress of the formatting options
SekelsenmatProgress of the formatting options
SekelsenmatCurrent Progress
SekelsenmatProgress of the formatting options
BigChimpUsing formatting options: typo (minor)
BigChimpExcel 5 example
BigChimpExcel 5 example: Detail Laz requirements
BigChimpExcel 5 example (minor)
SekelsenmatChangelog
BigChimpChangelog: sorted chronologically (minor)
BigChimpCurrent Progress: Clarified which formats are supported (well, you now get an entry in the table of contents, which helps, I think) (minor)
BigChimpSupported formats (minor)
BigChimpPackages (minor)
Jwdietrich
BigChimpSubversion: New sourceforge SVN address
BigChimpSupport and Bug Reporting: Add info about file size limit, useful until new release is made
BigChimpNasty wiki syntax doesn't seem to enable http links inside notes... (minor)
JwdietrichCategorized.
BigChimpSetting a Background Color: typos (minor)
BigChimpExternal Links
BigChimpSubversion: Changes since last release
BigChimp
BigChimpChangelog (minor)
BigChimpSubversion changelog (minor)
BigChimpSupport for Date/Time cells: ods support
WpFormulas (minor)
WpAdding "Understanding RPN forumulas"
BigChimpSupport and Bug Reporting (minor)
BigChimpBIFF8 additional formulas
WpExplaining the nested formula notation
WpUsing simple constant numbers (minor)
Wp (minor)
WpUsing cells in rpn formula
WpUsing cells in formulas (minor)
WpUsing ranges of cells and the unary SUM operator
WpUsing built-in operations and functions
WpAdd operations and functions
WpAdd example LOG, Remove "builtin routines"
WpUsing cells in formulas (minor)
WpUsing built-in operations and functions
WpUnderstanding RPN formulas (minor)
WpUsing simple constant numbers (minor)
WpUsing simple constant numbers (minor)
WpUsing simple constant numbers (minor)
WpUsing cells in formulas (minor)
WpUsing ranges of cells (minor)
WpUsing built-in operations and functions
WpUsing built-in operations and functions
WpUsing built-in operations and functions (minor)
WpUsing built-in operations and functions (minor)
WpRPN Formulas (minor)
WpRemarks on RPN formulas (BIFF only, writing only)
WpUsing built-in operations and functions (minor)
BigChimpAdded reference to to do items (see bug 25104)
BigChimpSubversion changelog: wiki output
WpUpdate "Proress of formatting options"
WpProgress of the formatting options (minor)
WpProgress of the formatting options (minor)
WpProgress of the formatting options: Add column "Text align"
WpProgress of the formatting options (minor)
WpProgress of the formatting options (minor)
WpProgress of the formatting options: Update "bold" for BIFF2
Wp"Progress of the formatting options": update cell border for BIFF2
WpProgress of the formatting options: Update BIFF2 text rotation and word wrap, rename "Background colors" to "Color support"
WpAdd chapter on color management
WpUpdate background color example
WpProgress of the formatting options: Update BIFF5
WpAdd code snippet to display palette colors and show corresponding screenshot
WpNote on limitations of palette size
WpProgress of the formatting options: Update text rotation status for BIFF5
WpSetting the text orientation
WpAdd "Basics" as introduction
WpUpdate status of date support
WpAdd status of user-interface options
WpUpdate svn change logs
WpMore updates on svn changelog
WpMove chapter "Basics" underneath "API Documentation"
WpAdd info on ContentType
WpDescribes methods for accessing worksheets
WpWorksheet (minor)
WpFileformats
WpSubversion changelog: Remove entries from "contents"
WpCorrect level of date/time support
WpSupport by file format (minor)
WpAdding cell formatting to section "Cells"
WpUpdate to do list
WpMore svn changelog
WpMore to do
WpTo do list
WpUsing built-in operations and functions (minor)
WpUsing built-in operations and functions (minor)
WpRemarks
WpColor management
WpColor management
WpColor management (minor)
WpCell (minor)
BigChimpTo do list: string stuff. Would be nice to have but everything works without it
BigChimpFormulas: simplify list
BigChimpUnderstanding RPN formulas: moved stack vertically. Hope you agree.
BigChimpUsing simple constant numbers
BigChimpUsing ranges of cells
BigChimpUsing built-in operations and functions (minor)
BigChimpSubversion changelog: merge color support sections
WpNew section "Cell formatting" with sub-sections "Colors" and "Fonts"
WpColors
WpAdd text rotation
WpCell borders
WpAdd skeleton for Text alignment, word wrap, and number formats
WpTo do list (minor)
WpGrid and Charting Controls with FPSpreadsheet (minor)
WpCell borders (minor)
WpCell formatting (minor)
WpFonts (minor)
WpFonts (minor)
WpAdd word wrap
WpText rotation (minor)
WpText rotation (minor)
WpWord wrap (minor)
WpImproved font sections
WpImproved section on Borders
WpImproved section on Background colors
WpAdd section on text alignment
WpAdd number formatting
WpRemove "Formatting options" in "Examples" section
WpBasics (minor)
WpCell (minor)
WpCell (minor)
WpNumber and date/time formats (minor)
WpRemove "Store row heights" from ToDo
WpProgress of the formatting options: Mark "Col/Row size" as "Working"
WpWorkbook (minor)
WpTo do list: There's write support for the spreadsheet grid now.
WpUpdate of svn changelog regarding spreadsheet grid.
WpUpdate number and date/time formats: no more restriction on decimals, new nfCustom format code.
WpUpdate svn changelog
WpUpdate of "Support by file format" for date/time format changes.
BigChimpSupport by file format: small language fixes
WpUpdate: reading of rpn formulas, showing of rpn formulas in Excel-syntax
WpCurrency formats
WpWorksheet (minor)
WpUpdate of TCell fields and hint not to manipulate the contents of TCell directly.
WpClarification of not calculating formulax
WpMentioning ReadRPNFormulaAsString
WpFormulas: : more precise formulation
WpUpdate of number formats
WpUpdate of subversion changelog
WpUpdate of progress of the formatting options
WpProgress of the formatting options: Add column "Number format"
WpSupport by file format
Wptypo (minor)
BigChimpMake breaking change warning re direct cell manipulation a bit stronger
WpProgress of the formatting options: Update status of ods number formats
WpSupport by file format: Update status of ods date/time
BigChimpProgress of the formatting options: more positive story
BigChimpclarify custom format instead of default format. Date/time etc by itself works, right?
WpProgress of workbook/worksheet user-interface options: Update ods status
WpProgress of workbook/worksheet user-interface options: Update of ods frozen panes
WpProgress of workbook/worksheet user-interface options (minor)
BigChimpadd screenshot
WpNumber and date/time formats: update identifiers of built-in formats after removal of nfSci, nfAccounting and nfAccountingRed
BigChimpspready instead of fpsgrid
WpAPI Reference: Mention to chm file in installation folder, give hint that download link does not lead to the file directly
WpDrop Excel3 and Excel4 from the list of supported file formats.
BigChimpRemembered I would like to work on this
BigChimpinstallation instructions
BigChimpSupport by file format: Remove CSV - csvdocument can be used for that
BigChimpProgress of the formatting options: remove csv
BigChimpProgress of workbook/worksheet user-interface options: remove csv
BigChimpInstallation (minor)
BigChimpversion 1.2 released based on r3241
BigChimpSupport and Bug Reporting: bug obsolete due to release 1.2
BigChimpPackages (minor)
BigChimpclarify release date, makes it easier to search for historical wiki page
BigChimpMoved packages to installation
BigChimpInstallation (minor)
WpAdd link to "historic wiki"
BigChimpWorkbook: bullets (minor)
BigChimpSubversion changelog: Wasn't used anyway
BigChimpChangelog
BigChimpmention documentation disctinction between stable & trunk
WpCalculation of rpn formulas
WpCalculation of RPN formulas (minor)
Wpsvn change log: Calculation of formulas
WpUpdate of introduction to rpn formulas
WpUsage of the fekParen token
WpRemove my link to release wiki (Reinier's text in "Documentation" is better)
WpSpeed-up of writing for ods and xlsx; font support for xlsx; mark xlsx format capabilities as "partial" because there is no reader yet.
BigChimpadd back the link to the historical wiki page for stable release
WpProgress of the formatting options: Update xlsx for text rotation
WpProgress of the formatting options: Update text alignment for OOXML
WpProgress of the formatting options: Update border and background color support for xlsx
WpProgress of the formatting options: Update writing of xlsx wordwrap
WpProgress of the formatting options: Update for writing of number format for xlsx
WpSupport by file format: Rename "reader/writer progress" to "reader/writer support" (seems to be clearer to me...)
WpAdd VirtualMode
WpConverting a large database table to a spreadsheet format using virtual mode (minor)
WpConverting a large database table to a spreadsheet using virtual mode (minor)
WpVirtual mode: Link to example
WpSVN change log: VirtualMode
WpConverting a large database table to a spreadsheet using virtual mode (minor)
WpConverting a large database table to a spreadsheet using virtual mode (minor)
WpConverting a large database table to a spreadsheet using virtual mode (minor)
WpProgress of the formatting options: Update writing of column width and row height for xlsx
WpSVN change log: : Update xlsx reader, insert row/col
WpSupport by file format: : Update basic ooxml reader
BigChimpSVN change log
WpProgress of the formatting options: : Update xlsx reading support of font, colors and number formats
WpSupport by file format: Update xlsx datetime support
WpCell borders: Update diagonal border lines
WpSVN change log
WpProgress of the formatting options: Update xlsx reading support for cell borders
WpProgress of the formatting options (minor)
WpProgress of the formatting options: Some details on biff2 limitations.
WpProgress of the formatting options: Update xlsx reading of text rotation, alignment, wordwrap
WpProgress of the formatting options: Update xlsx reading colum widths and row heights
WpProgress of the formatting options: Update xlsx reading "bold" attribute
WpSupport by file format: Update full reading support for xlsx
WpVirtual mode: Update renamed identifiers.
WpConverting a large database table to a spreadsheet using virtual mode: Update virtual writing mode example
WpProgress of workbook/worksheet user-interface options: Update xlsx support for hidden grid lines and headers
BigChimpConverting a large database table to a spreadsheet using virtual mode: Mention reason for using virtual mode
WpProgress of workbook/worksheet user-interface options: Update xlsx reading/writing of frozen panes
WpSVN change log (minor)
WpSVN change log
WpTo do list: Remove reference to Mantis issue 25104 which is finished.
WpNew chapter on the sample projects accompanying fpspreadsheet
WpTo do list: Add more to do items, delete "Calculation of RPN formulas" (done)
WpSample projects in the fpspreadsheet installation folder: : Add x-ref links to "Sample projects"
Wp (minor)
BigChimpConverting a large database table to a spreadsheet using virtual mode: mention example
WpBring back deleted ToDo list items, strike them out
WpTo do list: Update ToDo list items
WpTo do list (minor)
WpUpdate recent fixes in ToDo list
WpSVN change log: Error logging
WpWorkbook: Explain workbook's property ErrorMsg
WpWorkbook (minor)
WpTo do list: Memory leak in unit tests fixed, basic formula support for xlsx/ods
WpTo do list: TsWorksheetGrid showing wrong fonts hopefully fixed.
WpInstallation: New section "Compiler options"
WpCompiler options: Add reference to dependence on C library
WpSVN change log: Add section "Incompatible changes"
WpTo do list (minor)
WpUpdate of formulas, add shared formulas
WpShared formulas (minor)
WpShared formulas (minor)
WpShared formulas (minor)
WpShared formulas (minor)
WpAfter version 1.2
WpFormulas: Update to new formula machinery fully supporting string formulas
WpCell: Formula contentType
WpString formulas: Move formula list to separate file
WpAfter version 1.2: Update incompatible changes
WpSVN change log: Update string formula support
WpSupport by file format: Update string formulas
WpSupport by file format (minor)
WpFormulas: Separate chapter for formula list
WpSyntax of string formula
WpList of built-in formulas: User-defined formulas
WpExtending FPSpreadsheet by user-defined formulas
WpUsing built-in operations and functions (minor)
WpExtending FPSpreadsheet by user-defined formulas (minor)
WpDisplaying RPN formulas
WpString formulas (minor)
WpString formulas (minor)
WpDisplaying RPN formulas (minor)
WpList of built-in formulas (minor)
WpNumber and date/time formats (minor)
WpNumber and date/time formats: Add "WriteDateTimeFormat"
WpProgress of the formatting options (minor)
WpProgress of workbook/worksheet user-interface options (minor)
WpTo do list: Update
WpBasics (minor)
WpTo do list
WpSupport by file format: Update OpenDocument
WpSample projects in the fpspreadsheet installation folder (minor)
WpString formulas: Localized decimal and list separators
WpString formulas: Example on decimal and list separator
BigChimpUsing <syntaxhighlight> wiki notation instead of <source> as that is deprecated
BigChimpUse syntaxhighlight wiki notation instead of source as that is deprecated
BigChimpadded category
BigChimpSample projects in the fpspreadsheet installation folder: db demo also imports now
BigChimpLatest release
BigChimp1.2.1 bugfix release
WpShared formulas: Update shared formulas
WpList of built-in formulas (minor)
WpWorkbook: Hint on reader/writer units
WpWord wrap: Merged cells
WpSVN change log: Update merged cells
WpTo do list: Update merged cells
WpProgress of the formatting options: Add merged cells
WpTo do list: Update overflow cells
WpTo do list: Update shared formulas
WpSVN change log: Update overflow cells
WpSVN change log: Update on delete rows/column
BigChimpCompiler options (minor)
BigChimpAfter version 1.2: small language fixes
Wp (minor)
WpShared formulas: Hint on splitting of shared formulas in case of added/deleted rows/columns.
BigChimpVirtual mode: simplify language; some small language fixes
BigChimpVirtual mode (minor)
WpSVN change log: Update wikitables writer
WpSVN change log (minor)
WpSVN change log: Update
WpAfter version 1.2: Update
WpSample projects in the fpspreadsheet installation folder: Add info on demo "wikitablemaker"
WpSVN change log: Add wikitablemaker to SVN change log
BigChimpWriting a spreadsheet to file based on extension: indentation (minor)
WpOpening an existing spreadsheet: Hint on exceptions during format detection
WpOpening an existing spreadsheet (minor)
WpConverting a large database table to a spreadsheet using virtual mode: Add proper try-finally blocks
BigChimpAdded fpsexport unit to export datasets
BigChimpfpsexport
BigChimpConverting a database to a spreadsheet
BigChimpTo do list: fpsexport
BigChimpVirtual mode: also works for reading files
BigChimpSVN change log (minor)
BigChimpDownload: graphical component added
WpAfter version 1.2 (minor)
WpSVN change log: CSV reader/writer
WpSupport by file format: Update for CSV and wikitables
WpProgress of the formatting options: Update for CSV and Wikitables
WpSupport by file format: Rearrange items
WpTo do list: ToDo: wikitable reading
WpSample projects in the fpspreadsheet installation folder: CSV demos
WpWorkbook: Add CSV and wikitables
BigChimpInstallation: export
BigChimpTo do list (minor)
WpTo do list
WpVirtual mode: Sorting
WpSVN change log: Sorting
WpSVN change log (minor)
WpTo do list
WpWorkbook: csv file format
WpSVN change log: Currency registration, visual controls
BigChimpSample projects in the fpspreadsheet installation folder (minor)
BigChimpSVN change log
BigChimpTo do list: fpsexport demo done
WpSorting (minor)
WpSorting
WpSVN change log (minor)
WpSample projects in the fpspreadsheet installation folder (minor)
WpSample projects in the fpspreadsheet installation folder: Update some sections for new FPSpreadsheet controls.
WpGrid and Charting Controls with FPSpreadsheet: Short description of the fpspreadsheet controls
WpLink chapter on visual controls to demos chapter
WpVisual controls for FPSpreadsheet
WpSVN change log (minor)
WpDataset export: FPSExport: multiple sheets, number format from fieldtype
WpDataset export (minor)
WpVisual controls for FPSpreadsheet: Remove TsFontNameCombobox and TsFontSizeCombobox, and replace by TsCellCombobox
WpSVN change log (minor)
WpConverting between two spreadsheet formats: CSV params record
WpSample projects in the fpspreadsheet installation folder
WpLatest release: Historic wiki versions as separate chapter
WpWiki of old releases (minor)
WpLink to icon collections used in demo programs
WpStable releases: Move "SVN changes" to "stable releases"
WpStable releases
WpSVN change log
WpAfter version 1.2
WpStable releases
WpStable releases
WpChanges (with respect to v1.2/1.2.1) (minor)
WpTo do list: Remove completed todo items.
WpAfter version 1.4
WpChange log (with respect to v1.2/1.2.1) (minor)
WpDocumentation
WpAdd wiki revision for release 1.4
WpWiki documentation of old releases
WpChangelog: ChangeLog V1.4
WpReading and writing of CSV files: Fix typos
WpAdd TsWorkbookChartSource
WpInstallation: Hint on fpc version required
WpCompiler options: Conditional defines
WpInstallation: Usable Laz and FPC versions
WpVisual controls for FPSpreadsheet: Add TsWorkbookChartSource
WpOpening an existing spreadsheet: Exceptions when reading incorrect file type
WpOpening an existing spreadsheet
WpOpening an existing spreadsheet (minor)
WpOpening an existing spreadsheet (minor)
WpDataset export (minor)
BartDataset export: typo
WpIncompatible changes: Move type declarations to new unit
WpDisplaying RPN formulas (minor)
WpExcel 5 example: uses fpstypes!
WpConverting a database to a spreadsheet: uses "fpstypes"
WpConverting between two spreadsheet formats: uses "fpstypes"
WpReading and writing of CSV files: uses fpstypes
WpCell: Needed units
WpUnits: Undo previous change
WpExamples: Re-add section on needed units, now in the Examples section.
WpSVN change log: Memory reduction, cell record helper
WpExcel 5 example: Replace rpn formula in Excel5 example by string formula
WpUnits: Add unit fpscell
WpWorkbook (minor)
WpCell: New TCell and TsCellFormat records
WpCell: Rearrange text
WpCell background color: Update example on backgroundcolor
WpCell background color: show backgroundcolor reading functions
WpCell borders: Update Borders and BorderStyles
WpFonts: Overloaded methods with cell pointer
WpText rotation: Overloaded method with cell pointer, reading method
WpText alignment: Overloaded methods with cell pointer, reading methods
WpWord wrap: Overloaded method with cell pointer, reading method
WpVersion 1.4: Version 1.4.1
WpChangelog: Version 1.4.1 and some reformatting
WpCell: Comments in TCell
WpMerged cells: Cell comments
WpSVN change log: Comments
WpProgress of the formatting options: Modify table for "Comments"
WpSupport by file format: Add "Comments" to "Progress by supported format"
WpProgress of the formatting options: Remove "Comments" from "Progress of the formatting options"
WpSupport by file format (minor)
WpSupport by file format: Comments for biff2 and biff5
WpVersion 1.4: Update current version 1.4.2
WpChangelog: Update version 1.4.2
WpSupport by file format: Reading support for cell comments in BIFF8 and OOXML
WpCurrent Progress: Rearrangement of chapters
WpCurrent Progress (minor)
WpProgress by supported format: Writing of comments to xlsx working
WpCell comments: Update comments
WpCell: Update comments and cell flags
WpCell background color: Background fill patterns
WpCell background
WpCell: Background fill patterns
WpCell (minor)
WpSVN change log: Background fill patterns
WpIncompatible changes: Background fill patterns
WpProgress of the formatting options: Background patterns
WpProgress by supported format (minor)
WpChangelog (minor)
WpMerged cells: Merged cells update
WpCell: Update merged cells
WpCell comments: Hyperlinks
WpSVN change log: Hyperlinks
WpProgress by supported cell content: Hyperlinks
WpProgress by supported cell content (minor)
WpProgress by supported cell content (minor)
WpHyperlinks (minor)
WpHyperlinks
WpHyperlinks
WpSubversion: for-in
WpIterating through all Worksheets: Iteration through cells
WpIncompatible changes (minor)
WpIncompatible changes (minor)
WpRPN formulas: Remove docs of RPN formulas (now in separate article)
WpRPN formulas (minor)
WpShared formulas: Reduced support for shared formulas
WpIncompatible changes: Reduced shared formula support
WpCell
WpFormulas (minor)
WpWiki links: More FPSpreadsheet wikilinks
WpIncompatible changes: uffBold no longer supported
WpIncompatible changes (minor)
WpHyperlinks: More details on hyperlinks
WpSample projects in the fpspreadsheet installation folder: Update example folders
WpSample projects in the fpspreadsheet installation folder (minor)
WpVersion 1.4: Stable version 1.4.3
WpChangelog: Update version 1.4.3
WpNumber and date/time formats: Fractions as number format
WpNumber and date/time formats: Some details on fraction format
WpSVN change log: Fractions
WpNumber and date/time formats: Add nfDayMonth, nfMonthYear
WpProgress of the formatting options: Page layout
WpSVN change log: Page layout
WpIncompatible changes
WpTo do list
WpNumber and date/time formats: Details on number format string symbols
WpNumber format strings: More details on number format codes
WpNumber format strings (minor)
WpNumber format strings: Remove old example for number format strings (not necessary any more)
WpNumber format strings: Show color of negative red number format
WpCell background
WpHyperlinks: Details on PageLayout
WpPage layout
WpPage layout: Pagelayout: some improvements plus example
WpMove PageLayout Chapter one level up
WpColors: Introduce new color system
WpColors: New palette screen shot
WpColors (minor)
WpColors (minor)
WpColors (minor)
WpCell background (minor)
WpColors: Hints on color functions in fpsutils
WpColors
WpColors (minor)
WpColors (minor)
WpNumber format strings: Improved and corrected examples for number format strings
WpNumber format strings (minor)
WpNumber format strings (minor)
WpNumber format strings: More corrections of number format examples
WpUpdate due to changes of color management
WpUnits: Add fpsnumformat to "units" section, some minor additions and re-formulations
WpExcel 5 example: Update package name
WpIncompatible changes (minor)
WpTo do list (minor)
WpTo do list (minor)
WpReplace code tags by tt tags (better for exporting)
WpCell (minor)
WpNumber format strings: More "code" tokens replaced by "tt"
WpNumber format strings: Fix %
WpCell (minor)
WpCell (minor)
WpFormulas: More replacements of "code" tag by "tt"
WpReplace "code" tokens by "tt"
WpReplace !! tags in the table header by || (better export)
WpShared formulas and array formuls (minor)
WpColors (minor)
WpColors (minor)
WpNumber format strings: Improved presentation of the date/time format symbols
WpFonts: Update Fonts chapter to current version
WpCell background: Some correction with Background patterns
WpRPN formulas (minor)
WpExternal Links: Fix syntax to be ready for export
WpImproved syntax of external links (for better exporting)
WpWiki documentation of old releases (minor)
WpNumber format strings (minor)
Wp (minor)
WpUndo revision 90460 by Wp (talk)
WpBasics: Unit names in italics (minor)
WpBuilt-in number formats (minor)
WpColors (minor)
WpCell borders (minor)
WpChangelog (minor)
WpChangelog (minor)
WpChangelog (minor)
WpExtending FPSpreadsheet by user-defined formulas (minor)
WpColors (minor)
WpColors (minor)
WpWiki links (minor)
Wp (minor)
WpCell (minor)
WpCell (minor)
WpVirtual mode (minor)
WpDocumentation (minor)
WpConverting a database to a spreadsheet (minor)
WpDocumentation (minor)
WpAPI Reference: Update path to chm help files
WpBasics (minor)
WpWorkbook (minor)
WpCell: Typo (minor)
WpFormulas (minor)
WpFormulas: Some corrections (minor)
WpNumber and date/time formats (minor)
WpColors (minor)
WpCell background (minor)
WpText rotation (minor)
WpText rotation (minor)
WpMerged cells: Some formatting (minor)
WpHyperlinks (minor)
WpPage layout (minor)
WpVirtual mode (minor)
WpDataset export (minor)
WpUnits (minor)
WpExcel 5 example (minor)
WpOpening an existing spreadsheet (minor)
WpWriting a spreadsheet to file based on extension: Some formatting (minor)
WpIteration through cells (minor)
WpConverting a large database table to a spreadsheet using virtual mode (minor)
WpConverting between two spreadsheet formats (minor)
WpReading and writing of CSV files (minor)
WpSVN change log: Hint on wiki snapshot added to the lib files.
WpDownload: Add v1.6 changes
WpVersion 1.6: Use separate chapter for Version 1.4
WpChangelog: Add v1.6 to change release list
WpChange log (with respect to v1.4.x) (minor)
WpAPI Reference (minor)
WpChangelog
FTurtle
WpFonts: Subscript and superscript
WpProgress of the formatting options: Add "Rich-text" (and remove the obsolete "bold")
WpText rotation: Rich-text formatting
WpCurrent Progress: HTML writer
WpSVN change log
WpSample projects in the fpspreadsheet installation folder
WpProgress of the formatting options
WpProgress of workbook/worksheet user-interface options
WpSVN change log: Searching
WpCell borders: More line styles
WpSVN change log
WpProgress by supported cell content
WpProgress by supported cell content: Hyperlinks in html tables
WpProgress of the formatting options
WpProgress of workbook/worksheet user-interface options: Active sheet
WpSVN change log: Active worksheet
WpSVN change log: Selected cell
WpProgress of workbook/worksheet user-interface options
WpProgress by supported cell content: Update HTML reader support
WpProgress of the formatting options: Update HTML reader support
WpSVN change log: Update HTML reader
WpRich-text formatting: Update rich-text formatting
WpCell: Add cell reading/writing methods
WpCell: WriteUTF8Text --> WriteUTF8Text, ReadAsUTF8Text --> ReadText
WpHyperlinks
WpExcel 5 example
WpIteration through cells
WpConverting a database to a spreadsheet
WpSVN change log: WriteTextAsHTML
WpIncompatible changes: WriteUTF8Text and ReadAsUTF8Text are deprecated
WpRich-text formatting: Update rich-text formatting, new HTML method
WpSorting: Searching
WpSearch and replace (minor)
WpSearching and replacing (minor)
WpVirtual mode: Stream selection, virtual mode
WpSVN change log: ExcelXML writer
WpWorkbook: User-defined file formats
WpLoading and saving: Add user-defined file formats
WpWorkbook: User-defined file-formats
WpAdding new file formats: User-defined file formats
WpSVN change log: Add user-provided reader/writer to SVN change log
WpSVN change log: Clipboard
WpSVN change log (minor)
WpVisual controls for FPSpreadsheet (minor)
WpSVN change log: RTL mode and TStringGrid compatibility of TsWorksheetGrid
WpIncompatible changes
WpSVN change log
WpProgress of workbook/worksheet user-interface options
WpSVN change log
WpPage layout: Print ranges, repeated header rows/columns
WpSVN change log
WpProgress of the formatting options: Print ranges
WpProgress of the formatting options (minor)
WpPage layout (minor)
WpRich-text formatting: DeleteRichTextFormatting
WpProgress of the formatting options: Print ranges for biff8
WpProgress of the formatting options: Print ranges for biff5
WpProgress of the formatting options
WpLoading and saving (minor)
WpProgress of the formatting options
WpProgress of the formatting options
WpBIFF Explorer in "applications" now
WpPage layout: Explanation for "Fit all columns on one page"
WpCell: Add row and column records
WpPage layout: Column and row operations
WpColumns and rows: More on rows and columns
WpPage layout: Update (embedded images, class instead of record)
WpPage layout
WpHeaders and footers
WpGeneral
WpGeneral
WpProgress by supported cell content: Embedded images
WpSVN change log: Embedded images
WpIncompatible changes: Pagelayout being a class now
WpAdditional data: Embedded images
WpSubversion
WpCurrent Progress
WpProgress by supported cell content
WpImages: WriteImage from stream
WpCurrent Progress: Update images (reading), add header/footer images to formatting options progress
WpProgress by supported cell content
WpProgress by supported cell content
WpImages: Limitations of image positioning
WpColumns and rows: Row height and column width units
WpSVN change log
WpIncompatible changes
WpVersion 1.6
WpColumns and rows
WpColumns and rows
WpIncompatible changes
WpSVN change log: Localization
WpIncompatible changes
WpColors
WpColors
WpVersion 1.6
WpChangelog
WpConverting a large database table to a spreadsheet using virtual mode: Fix typo
WpVirtual mode: Update VirtualMode
WpConverting a large database table to a spreadsheet using virtual mode: Update of virtual mode
WpIncompatible changes: Update virtual mode
KStarbeAdded name of unit where workbook types can be found (minor)
HeXorlink update (minor)
WpSVN change log: Add zoom factor
WpProgress of workbook/worksheet user-interface options: Zooming
KStarbeXLM -> XML in details about format. (minor)
WpSVN change log: Column and cell formats
WpSVN change log
WpTo do list
WpProgress of the formatting options: Column/row formats
WpWiki documentation of old releases: Update links to historic wiki versions
WpProgress of the formatting options: Update column/row format progress
WpProgress of the formatting options: Update xlsx col/row format
WpProgress of the formatting options (minor)
WpColumns and rows: Description of row and column formats
WpProgress of the formatting options
WpIncompatible changes
WpSample projects in the fpspreadsheet installation folder
WpProgress of the formatting options
WpProgress of the formatting options
WpProgress of the formatting options
WpProgress of the formatting options: Update wikitable progress (fix too optimistic "working" classifications
WpColumns and rows (minor)
WpSVN change log: Hidden worksheets
WpInstallation (minor)
WpStable releases: stable release v1.8
WpPrepare version 1.8
WpWiki documentation of old releases: Location of v1.8 wiki
WpProtection
WpCell protection
WpAdditional data
WpCell
WpCell
WpCell protection
WpWorkbook protection: Password for workbook protection
WpWorkbook protection (minor)
WpWorksheet protection: Password for worksheet protection
WpProtection
WpProtection: Add section Passwords
WpSVN change log: Protection
WpSVN change log
WpProgress by supported cell content: Protection
WpSVN change log: Display embedded images
WpChangelog: Release 1.8.2
WpChangelog
WpChangelog: Version 1.8.3
WpSVN change log
WpSearching and replacing: Initialization of search and replace params records
WpWorkbook: File extensions
WpFormulas: boAbortReadingOnFormulaError
WpSVN change log
WpExtending FPSpreadsheet by user-defined formulas: boIgnoreFormulas
WpSVN change log: boIgnoreFormulas
MathiasColors (minor)
WpSVN change log
WpProgress by supported cell content: 3D references
WpCell: Remove TCell.FormulaValue
WpCell: Again: Remove Cell.FormulaValue. Add info on TsCellFlags. Substructure of the TCell chapter.
WpFormulas: More details on the new formula structure
WpCell: Add some internal hyperlinks
WpFormulas: Manual calculation of formulas
WpString formulas: Syntax for 3d formulas
WpFormulas (minor)
WpProgress by supported cell content: Update "Progress of cell content" for 3d formulas
WpString formulas: Note on non-existing linked sheets
WpSubversion
WpStable releases: v1.10
WpDownload: v1.10
WpWiki documentation of old releases: v1.10
WpChangelog: v1.10
SeregaKRAdded an example to export into dbf
SeregaKRExport to DBF (minor)
SeregaKRExport to DBF: Added comment (minor)
WpChangelog: v1.10.1
WpChangelog (minor)
WpChangelog (minor)
WpTo do list
WpWiki documentation of old releases
WpColumn and row operations (minor)
WpColumn and row operations: Show/Hide columns/rows
WpSVN change log: Hide/show rows/cols
WpVersion 1.10.1
WpVersion 1.10
WpProgress of the formatting options: hide cols/rows
WpCurrent Progress (minor)
WpProgress of workbook/worksheet user-interface options
ZoltanleoHow to add and read data to/from a cell
ZoltanleoThe basic TCell record
Michael.vanhamcorrect typo in unit name (minor)
WpExtending FPSpreadsheet by user-defined formulas
ChronosSubversion
WpSearching and replacing: Fix typo related to searching (TsSearchEngine instead of TSearchEngine)
TrevFixed syntax highlighting in all 77 examples... I hope (minor)
WpSVN change log
WpProgress of the formatting options: Formatting options for Excel2003/XML format
WpProgress of the formatting options
WpProgress of the formatting options
WpProgress of workbook/worksheet user-interface options: Update worksheet user-interface optionf for Excel2003/XML format.
WpProgress by supported cell content: Update supported cell content for Excel2003/XML format.
WpProgress of the formatting options
WpCurrent Progress
WpSVN change log
WpSVN change log
WpColumns and rows
WpColumns and rows: Row and Column Options: hidden row/cols, pagebreaks
WpSVN change log: Page breaks
WpProgress of the formatting options: Page breaks
WpColumns and rows: Add sub-chapters to the "Columns and rows" chapter
WpColumn and row formats: More details on column / row formats
WpColumn and row formats
WpPage breaks: Spreadsheet events
WpEvents
WpEvents: Fix hierarchy in "contents"
WpEvents: Links to visual controls.
TrevReferenes: Fixed typo in heading (minor)
WpProgress of workbook/worksheet user-interface options: Worksheet.TabColor
WpSVN change log: Worksheet.TabColor
WpVisual controls for FPSpreadsheet: WorksheetIndicator
WpSVN change log: TsWorksheetIndicator
WpExamples: Export Examples section to separate article
WpDownload: ChangeLog v1.12
Wp
WpWiki links
WpExternal Links
WpExternal Links
WpSVN change log: Conditional formats
WpProgress by supported cell content: Conditional formats
WpChangelog
WpIncompatible changes: remove deprecated properties DefaultRowHeight and DefaultColWidth
WpRich-text formatting: Fix usage of outdated ReadCellFont call in sample code
TrevChangelog: Collapse log after first two entries (minor)
TrevStable releases: Collapse version listing after first entry (minor)
TrevUndo revision 137929 breaks ToC links (minor)
WpProgress by supported cell content: conditional format
WpSVN change log: meta data
WpSearching and replacing: Typo (fpsearch --> fpsSearch)
WpSearching and replacing: How to set up active worksheet and active cell for searching
WpSearching and replacing: Use separate local variable for found worksheet
WpSearching and replacing
WpSearching and replacing
SlawekWorkbook: dto. -> ditto (minor)
SlawekColumn width / row height: it was GetColHeight, shoult be GetColWidth (minor)
EChristianswrong.-> dbDiagUp, dbDiagDown correct -> cbDiagUp, cbDiagDown (Lazarus 2.0.10) (minor)
EChristianstypo: rt90DegreeCounterClockwizeRotation -> correct: rt90DegreeCounterClockwiseRotation (minor)
WpNumber format strings
WpCell borders: typo
WpSVN change log: TsWorksheetDataset
WpSVN change log
WpSVN change log
WpDownload: Prepare release v1.14
WpDownload
WpWiki documentation of old releases: Update "historic" help page of v1.14
WpDownload: Mention Online-Package-Manager
WpRearrange changelog items.
WpChangelog
WpSVN
WpCurrent Progress
WpHeaders and footers: Fix type
WpProgress of the formatting options
WpSVN
WpCompiler options: Update conditional defines list (fps.inc)
WpCompiler options
WpSVN
WpSVN
WpSVN
WpSVN
WpWorkbook protection: Update to password protection
WpWorkbook protection
WpText alignment: Fix typo
WpCell protection
WpCell protection
WpUndo revision 157206 by Wp (talk)
WpUndo revision 157205 by Wp (talk)
WpCell formatting: Do not print cells
WpIndex to Cell format
WpChangelog: Preparation for v1.16
WpDocumentation: Link to wiki snapshot of v1.16
WpCell protection: Fix cell protection sample code
WpText alignment: Add haJustify
WpText alignment: More hor justification

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.