You've already forked lazarus-ccr
fpspreadsheet: Rearrange units to better avoid circular unit references. General idea: no unit of the package must "use" fpspreadsheet.pas in the interface section.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6444 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -6,7 +6,7 @@ unit fpsCell;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpstypes, fpspreadsheet;
|
Classes, SysUtils, fpstypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
TCellHelper = record helper for TCell
|
TCellHelper = record helper for TCell
|
||||||
@ -46,8 +46,7 @@ type
|
|||||||
procedure SetWordwrap(const AValue: Boolean);
|
procedure SetWordwrap(const AValue: Boolean);
|
||||||
|
|
||||||
protected
|
protected
|
||||||
function GetWorkbook: TsWorkbook; inline;
|
function GetWorkbook: TsBasicWorkbook; inline;
|
||||||
function GetWorksheet: TsWorksheet; inline;
|
|
||||||
|
|
||||||
public
|
public
|
||||||
property BackgroundColor: TsColor
|
property BackgroundColor: TsColor
|
||||||
@ -83,74 +82,77 @@ type
|
|||||||
read GetVertAlignment write SetVertAlignment;
|
read GetVertAlignment write SetVertAlignment;
|
||||||
property Wordwrap: Boolean
|
property Wordwrap: Boolean
|
||||||
read GetWordwrap write SetWordwrap;
|
read GetWordwrap write SetWordwrap;
|
||||||
property Workbook: TsWorkbook read GetWorkbook;
|
property Workbook: TsBasicWorkbook read GetWorkbook;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
fpspreadsheet;
|
||||||
|
|
||||||
function TCellHelper.GetBackgroundColor: TsColor;
|
function TCellHelper.GetBackgroundColor: TsColor;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadBackgroundColor(@self);
|
Result := (Worksheet as TsWorksheet).ReadBackgroundColor(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetBiDiMode: TsBiDiMode;
|
function TCellHelper.GetBiDiMode: TsBiDiMode;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadBiDiMode(@self);
|
Result := (Worksheet as TsWorksheet).ReadBiDiMode(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetBorder: TsCellBorders;
|
function TCellHelper.GetBorder: TsCellBorders;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadCellBorders(@self);
|
Result := (Worksheet as TsWorksheet).ReadCellBorders(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetBorderStyle(const ABorder: TsCellBorder): TsCellBorderStyle;
|
function TCellHelper.GetBorderStyle(const ABorder: TsCellBorder): TsCellBorderStyle;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadCellBorderStyle(@self, ABorder);
|
Result := (Worksheet as TsWorksheet).ReadCellBorderStyle(@self, ABorder);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetBorderStyles: TsCellBorderStyles;
|
function TCellHelper.GetBorderStyles: TsCellBorderStyles;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadCellBorderStyles(@self);
|
Result := (Worksheet as TsWorksheet).ReadCellBorderStyles(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetCellFormat: TsCellFormat;
|
function TCellHelper.GetCellFormat: TsCellFormat;
|
||||||
begin
|
begin
|
||||||
Result := GetWorkbook.GetCellFormat(FormatIndex);
|
Result := (GetWorkbook as TsWorkbook).GetCellFormat(FormatIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetComment: String;
|
function TCellHelper.GetComment: String;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadComment(@self);
|
Result := (Worksheet as TsWorksheet).ReadComment(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetFont: TsFont;
|
function TCellHelper.GetFont: TsFont;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadCellFont(@self);
|
Result := (Worksheet as TsWorksheet).ReadCellFont(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetFontIndex: Integer;
|
function TCellHelper.GetFontIndex: Integer;
|
||||||
var
|
var
|
||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
begin
|
begin
|
||||||
fmt := Workbook.GetPointerToCellFormat(FormatIndex);
|
fmt := (Workbook as TsWorkbook).GetPointerToCellFormat(FormatIndex);
|
||||||
Result := fmt^.FontIndex;
|
Result := fmt^.FontIndex;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetHorAlignment: TsHorAlignment;
|
function TCellHelper.GetHorAlignment: TsHorAlignment;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadHorAlignment(@Self);
|
Result := (Worksheet as TsWorksheet).ReadHorAlignment(@Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetHyperlink: TsHyperlink;
|
function TCellHelper.GetHyperlink: TsHyperlink;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadHyperlink(@self);
|
Result := (Worksheet as TsWorksheet).ReadHyperlink(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetNumberFormat: TsNumberFormat;
|
function TCellHelper.GetNumberFormat: TsNumberFormat;
|
||||||
var
|
var
|
||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
begin
|
begin
|
||||||
fmt := Workbook.GetPointerToCellFormat(FormatIndex);
|
fmt := (Workbook as TsWorkbook).GetPointerToCellFormat(FormatIndex);
|
||||||
Result := fmt^.NumberFormat;
|
Result := fmt^.NumberFormat;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -158,127 +160,122 @@ function TCellHelper.GetNumberFormatStr: String;
|
|||||||
var
|
var
|
||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
begin
|
begin
|
||||||
fmt := Workbook.GetPointerToCellFormat(FormatIndex);
|
fmt := (Workbook as TsWorkbook).GetPointerToCellFormat(FormatIndex);
|
||||||
Result := fmt^.NumberFormatStr;
|
Result := fmt^.NumberFormatStr;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetTextRotation: TsTextRotation;
|
function TCellHelper.GetTextRotation: TsTextRotation;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadTextRotation(@Self);
|
Result := (Worksheet as TsWorksheet).ReadTextRotation(@Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetUsedFormattingFields: TsUsedFormattingFields;
|
function TCellHelper.GetUsedFormattingFields: TsUsedFormattingFields;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadUsedFormatting(@Self);
|
Result := (Worksheet as TsWorksheet).ReadUsedFormatting(@Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetVertAlignment: TsVertAlignment;
|
function TCellHelper.GetVertAlignment: TsVertAlignment;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadVertAlignment(@self);
|
Result := (Worksheet as TsWorksheet).ReadVertAlignment(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetWordwrap: Boolean;
|
function TCellHelper.GetWordwrap: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.ReadWordwrap(@self);
|
Result := (Worksheet as TsWorksheet).ReadWordwrap(@self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCellHelper.GetWorkbook: TsWorkbook;
|
function TCellHelper.GetWorkbook: TsBasicWorkbook;
|
||||||
begin
|
begin
|
||||||
Result := GetWorksheet.Workbook;
|
Result := (Worksheet as TsWorksheet).Workbook;
|
||||||
end;
|
|
||||||
|
|
||||||
function TCellHelper.GetWorksheet: TsWorksheet;
|
|
||||||
begin
|
|
||||||
Result := TsWorksheet(Worksheet);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetBackgroundColor(const AValue: TsColor);
|
procedure TCellHelper.SetBackgroundColor(const AValue: TsColor);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteBackgroundColor(@self, AValue);
|
(Worksheet as TsWorksheet).WriteBackgroundColor(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetBiDiMode(const AValue: TsBiDiMode);
|
procedure TCellHelper.SetBiDiMode(const AValue: TsBiDiMode);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteBiDiMode(@self, AValue);
|
(Worksheet as TsWorksheet).WriteBiDiMode(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetBorder(const AValue: TsCellBorders);
|
procedure TCellHelper.SetBorder(const AValue: TsCellBorders);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteBorders(@self, AValue);
|
(Worksheet as TsWorksheet).WriteBorders(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetBorderStyle(const ABorder: TsCellBorder;
|
procedure TCellHelper.SetBorderStyle(const ABorder: TsCellBorder;
|
||||||
const AValue: TsCellBorderStyle);
|
const AValue: TsCellBorderStyle);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteBorderStyle(@self, ABorder, AValue);
|
(Worksheet as TsWorksheet).WriteBorderStyle(@self, ABorder, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetBorderStyles(const AValue: TsCellBorderStyles);
|
procedure TCellHelper.SetBorderStyles(const AValue: TsCellBorderStyles);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteBorderStyles(@self, AValue);
|
(Worksheet as TsWorksheet).WriteBorderStyles(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetCellFormat(const AValue: TsCellFormat);
|
procedure TCellHelper.SetCellFormat(const AValue: TsCellFormat);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteCellFormat(@self, AValue);
|
(Worksheet as TsWorksheet).WriteCellFormat(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetComment(const AValue: String);
|
procedure TCellHelper.SetComment(const AValue: String);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteComment(@self, AValue);
|
(Worksheet as TsWorksheet).WriteComment(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetFontIndex(const AValue: Integer);
|
procedure TCellHelper.SetFontIndex(const AValue: Integer);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteFont(@self, AValue);
|
(Worksheet as TsWorksheet).WriteFont(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetHorAlignment(const AValue: TsHorAlignment);
|
procedure TCellHelper.SetHorAlignment(const AValue: TsHorAlignment);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteHorAlignment(@self, AValue);
|
(Worksheet as TsWorksheet).WriteHorAlignment(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetHyperlink(const AValue: TsHyperlink);
|
procedure TCellHelper.SetHyperlink(const AValue: TsHyperlink);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteHyperlink(@self, AValue.Target, AValue.Tooltip);
|
(Worksheet as TsWorksheet).WriteHyperlink(@self, AValue.Target, AValue.Tooltip);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetNumberFormat(const AValue: TsNumberFormat);
|
procedure TCellHelper.SetNumberFormat(const AValue: TsNumberFormat);
|
||||||
var
|
var
|
||||||
fmt: TsCellFormat;
|
fmt: TsCellFormat;
|
||||||
begin
|
begin
|
||||||
fmt := Workbook.GetCellFormat(FormatIndex);
|
fmt := (Workbook as TsWorkbook).GetCellFormat(FormatIndex);
|
||||||
fmt.NumberFormat := AValue;
|
fmt.NumberFormat := AValue;
|
||||||
GetWorksheet.WriteCellFormat(@self, fmt);
|
(Worksheet as TsWorksheet).WriteCellFormat(@self, fmt);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetNumberFormatStr(const AValue: String);
|
procedure TCellHelper.SetNumberFormatStr(const AValue: String);
|
||||||
var
|
var
|
||||||
fmt: TsCellFormat;
|
fmt: TsCellFormat;
|
||||||
begin
|
begin
|
||||||
fmt := Workbook.GetCellFormat(FormatIndex);
|
fmt := (Workbook as TsWorkbook).GetCellFormat(FormatIndex);
|
||||||
fmt.NumberFormatStr := AValue;
|
fmt.NumberFormatStr := AValue;
|
||||||
GetWorksheet.WriteCellFormat(@self, fmt);
|
(Worksheet as TsWorksheet).WriteCellFormat(@self, fmt);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetTextRotation(const AValue: TsTextRotation);
|
procedure TCellHelper.SetTextRotation(const AValue: TsTextRotation);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteTextRotation(@self, AValue);
|
(Worksheet as TsWorksheet).WriteTextRotation(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetUsedFormattingFields(const AValue: TsUsedFormattingFields);
|
procedure TCellHelper.SetUsedFormattingFields(const AValue: TsUsedFormattingFields);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteUsedFormatting(@self, AValue);
|
(Worksheet as TsWorksheet).WriteUsedFormatting(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetVertAlignment(const AValue: TsVertAlignment);
|
procedure TCellHelper.SetVertAlignment(const AValue: TsVertAlignment);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteVertAlignment(@self, AValue);
|
(Worksheet as TsWorksheet).WriteVertAlignment(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCellHelper.SetWordwrap(const AValue: Boolean);
|
procedure TCellHelper.SetWordwrap(const AValue: Boolean);
|
||||||
begin
|
begin
|
||||||
GetWorksheet.WriteWordwrap(@self, AValue);
|
(Worksheet as TsWorksheet).WriteWordwrap(@self, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,12 +76,12 @@ type
|
|||||||
|
|
||||||
TsCells = class(TsRowColAVLTree)
|
TsCells = class(TsRowColAVLTree)
|
||||||
private
|
private
|
||||||
FWorksheet: Pointer; // Must be cast to TsWorksheet
|
FWorksheet: TsBasicWorksheet; // Must be cast to TsWorksheet
|
||||||
protected
|
protected
|
||||||
procedure DisposeData(var AData: Pointer); override;
|
procedure DisposeData(var AData: Pointer); override;
|
||||||
function NewData: Pointer; override;
|
function NewData: Pointer; override;
|
||||||
public
|
public
|
||||||
constructor Create(AWorksheet: Pointer; AOwnsData: Boolean = true);
|
constructor Create(AWorksheet: TsBasicWorksheet; AOwnsData: Boolean = true);
|
||||||
function AddCell(ARow, ACol: Cardinal): PCell;
|
function AddCell(ARow, ACol: Cardinal): PCell;
|
||||||
procedure DeleteCell(ARow, ACol: Cardinal);
|
procedure DeleteCell(ARow, ACol: Cardinal);
|
||||||
function FindCell(ARow, ACol: Cardinal): PCell;
|
function FindCell(ARow, ACol: Cardinal): PCell;
|
||||||
@ -689,7 +689,8 @@ end;
|
|||||||
{ TsCells: an AVLTree to store spreadsheet cells }
|
{ TsCells: an AVLTree to store spreadsheet cells }
|
||||||
{==============================================================================}
|
{==============================================================================}
|
||||||
|
|
||||||
constructor TsCells.Create(AWorksheet: Pointer; AOwnsData: Boolean = true);
|
constructor TsCells.Create(AWorksheet: TsBasicWorksheet;
|
||||||
|
AOwnsData: Boolean = true);
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwnsData);
|
inherited Create(AOwnsData);
|
||||||
FWorksheet := AWorksheet;
|
FWorksheet := AWorksheet;
|
||||||
|
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
fpstypes, fpspreadsheet, fpsReaderWriter, fpsCsvDocument;
|
fpstypes, fpsReaderWriter, fpsCsvDocument;
|
||||||
|
|
||||||
type
|
type
|
||||||
TsCSVReader = class(TsCustomSpreadReader)
|
TsCSVReader = class(TsCustomSpreadReader)
|
||||||
@ -21,7 +21,7 @@ type
|
|||||||
procedure ReadLabel(AStream: TStream); override;
|
procedure ReadLabel(AStream: TStream); override;
|
||||||
procedure ReadNumber(AStream: TStream); override;
|
procedure ReadNumber(AStream: TStream); override;
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
procedure ReadFromFile(AFileName: String; APassword: String = '';
|
procedure ReadFromFile(AFileName: String; APassword: String = '';
|
||||||
AParams: TsStreamParams = []); override;
|
AParams: TsStreamParams = []); override;
|
||||||
procedure ReadFromStream(AStream: TStream; APassword: String = '';
|
procedure ReadFromStream(AStream: TStream; APassword: String = '';
|
||||||
@ -48,10 +48,10 @@ type
|
|||||||
const AValue: string; ACell: PCell); override;
|
const AValue: string; ACell: PCell); override;
|
||||||
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: double; ACell: PCell); override;
|
const AValue: double; ACell: PCell); override;
|
||||||
procedure WriteSheet(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteSheet(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
|
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
|
||||||
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
|
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
|
||||||
end;
|
end;
|
||||||
@ -95,7 +95,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
DateUtils, LConvEncoding, Math,
|
DateUtils, LConvEncoding, Math,
|
||||||
fpsUtils, fpsNumFormat;
|
fpsUtils, fpspreadsheet, fpsNumFormat;
|
||||||
|
|
||||||
const
|
const
|
||||||
DEFAULT_ENCODING = 'utf8'; //'utf8bom';
|
DEFAULT_ENCODING = 'utf8'; //'utf8bom';
|
||||||
@ -115,7 +115,7 @@ end;
|
|||||||
{ TsCSVReader }
|
{ TsCSVReader }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
constructor TsCSVReader.Create(AWorkbook: TsWorkbook);
|
constructor TsCSVReader.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
FWorksheetName := 'Sheet1'; // will be replaced by filename
|
FWorksheetName := 'Sheet1'; // will be replaced by filename
|
||||||
@ -148,29 +148,32 @@ procedure TsCSVReader.ReadCellValue(ARow, ACol: Cardinal; AText: String);
|
|||||||
var
|
var
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
boolValue: Boolean;
|
boolValue: Boolean;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
// Empty strings are blank cells -- nothing to do
|
// Empty strings are blank cells -- nothing to do
|
||||||
if AText = '' then
|
if AText = '' then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
|
cell := sheet.AddCell(ARow, ACol);
|
||||||
|
|
||||||
// Do not try to interpret the strings. --> everything is a LABEL cell.
|
// Do not try to interpret the strings. --> everything is a LABEL cell.
|
||||||
if not CSVParams.DetectContentType then
|
if not CSVParams.DetectContentType then
|
||||||
begin
|
begin
|
||||||
FWorksheet.WriteText(cell, AText);
|
sheet.WriteText(cell, AText);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Check for a BOOLEAN cell
|
// Check for a BOOLEAN cell
|
||||||
if IsBoolValue(AText, CSVParams.TrueText, CSVParams.FalseText, boolValue) then
|
if IsBoolValue(AText, CSVParams.TrueText, CSVParams.FalseText, boolValue) then
|
||||||
begin
|
begin
|
||||||
FWorksheet.WriteBoolValue(cell, boolValue);
|
sheet.WriteBoolValue(cell, boolValue);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// All other cases are handled by WriteCellValusAsString
|
// All other cases are handled by WriteCellValusAsString
|
||||||
FWorksheet.WriteCellValueAsString(cell, AText, FFormatSettings);
|
sheet.WriteCellValueAsString(cell, AText, FFormatSettings);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsCSVReader.ReadFormula(AStream: TStream);
|
procedure TsCSVReader.ReadFormula(AStream: TStream);
|
||||||
@ -205,7 +208,7 @@ begin
|
|||||||
encoding := DEFAULT_ENCODING;
|
encoding := DEFAULT_ENCODING;
|
||||||
|
|
||||||
// Create worksheet
|
// Create worksheet
|
||||||
FWorksheet := FWorkbook.AddWorksheet(FWorksheetName, true);
|
FWorksheet := (FWorkbook as TsWorkbook).AddWorksheet(FWorksheetName, true);
|
||||||
|
|
||||||
// Create csv parser, read file and store in worksheet
|
// Create csv parser, read file and store in worksheet
|
||||||
Parser := TCSVParser.Create;
|
Parser := TCSVParser.Create;
|
||||||
@ -255,7 +258,7 @@ end;
|
|||||||
{ TsCSVWriter }
|
{ TsCSVWriter }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
constructor TsCSVWriter.Create(AWorkbook: TsWorkbook);
|
constructor TsCSVWriter.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
FFormatSettings := CSVParams.FormatSettings;
|
FFormatSettings := CSVParams.FormatSettings;
|
||||||
@ -298,7 +301,7 @@ var
|
|||||||
begin
|
begin
|
||||||
Unused(AStream);
|
Unused(AStream);
|
||||||
Unused(ARow, ACol, AValue);
|
Unused(ARow, ACol, AValue);
|
||||||
s := FWorksheet.ReadAsText(ACell);
|
s := (FWorksheet as TsWorksheet).ReadAsText(ACell);
|
||||||
s := ConvertEncoding(s, EncodingUTF8, FEncoding);
|
s := ConvertEncoding(s, EncodingUTF8, FEncoding);
|
||||||
FCSVBuilder.AppendCell(s);
|
FCSVBuilder.AppendCell(s);
|
||||||
end;
|
end;
|
||||||
@ -349,20 +352,22 @@ begin
|
|||||||
if CSVParams.NumberFormat <> '' then
|
if CSVParams.NumberFormat <> '' then
|
||||||
s := Format(CSVParams.NumberFormat, [AValue], FFormatSettings)
|
s := Format(CSVParams.NumberFormat, [AValue], FFormatSettings)
|
||||||
else
|
else
|
||||||
s := FWorksheet.ReadAsText(ACell, FFormatSettings);
|
s := (FWorksheet as TsWorksheet).ReadAsText(ACell, FFormatSettings);
|
||||||
s := ConvertEncoding(s, EncodingUTF8, FEncoding);
|
s := ConvertEncoding(s, EncodingUTF8, FEncoding);
|
||||||
FCSVBuilder.AppendCell(s);
|
FCSVBuilder.AppendCell(s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
r, c: Cardinal;
|
r, c: Cardinal;
|
||||||
firstRow, lastRow: Cardinal;
|
firstRow, lastRow: Cardinal;
|
||||||
firstCol, lastCol: Cardinal;
|
firstCol, lastCol: Cardinal;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
n: Integer;
|
n: Integer;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
FWorksheet := AWorksheet;
|
FWorksheet := AWorksheet;
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
FCSVBuilder := TCSVBuilder.Create;
|
FCSVBuilder := TCSVBuilder.Create;
|
||||||
try
|
try
|
||||||
@ -371,29 +376,29 @@ begin
|
|||||||
FCSVBuilder.QuoteChar := CSVParams.QuoteChar;
|
FCSVBuilder.QuoteChar := CSVParams.QuoteChar;
|
||||||
FCSVBuilder.SetOutput(AStream);
|
FCSVBuilder.SetOutput(AStream);
|
||||||
|
|
||||||
n := FWorksheet.GetCellCount;
|
n := sheet.GetCellCount;
|
||||||
if FClipboardMode and (n = 1) then
|
if FClipboardMode and (n = 1) then
|
||||||
begin
|
begin
|
||||||
cell := FWorksheet.Cells.GetFirstCell;
|
cell := sheet.Cells.GetFirstCell;
|
||||||
WriteCellToStream(AStream, cell);
|
WriteCellToStream(AStream, cell);
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
if FClipboardMode then
|
if FClipboardMode then
|
||||||
begin
|
begin
|
||||||
firstRow := FWorksheet.GetFirstRowIndex;
|
firstRow := sheet.GetFirstRowIndex;
|
||||||
firstCol := FWorksheet.GetFirstColIndex;
|
firstCol := sheet.GetFirstColIndex;
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
firstRow := 0;
|
firstRow := 0;
|
||||||
firstCol := 0;
|
firstCol := 0;
|
||||||
end;
|
end;
|
||||||
lastRow := FWorksheet.GetLastOccupiedRowIndex;
|
lastRow := sheet.GetLastOccupiedRowIndex;
|
||||||
lastCol := FWorksheet.GetLastOccupiedColIndex;
|
lastCol := sheet.GetLastOccupiedColIndex;
|
||||||
for r := firstRow to lastRow do
|
for r := firstRow to lastRow do
|
||||||
begin
|
begin
|
||||||
for c := firstCol to lastCol do
|
for c := firstCol to lastCol do
|
||||||
begin
|
begin
|
||||||
cell := FWorksheet.FindCell(r, c);
|
cell := sheet.FindCell(r, c);
|
||||||
if cell = nil then
|
if cell = nil then
|
||||||
FCSVBuilder.AppendCell('')
|
FCSVBuilder.AppendCell('')
|
||||||
else
|
else
|
||||||
@ -411,12 +416,15 @@ procedure TsCSVWriter.WriteToStream(AStream: TStream;
|
|||||||
AParams: TsStreamParams = []);
|
AParams: TsStreamParams = []);
|
||||||
var
|
var
|
||||||
n: Integer;
|
n: Integer;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
FClipboardMode := (spClipboard in AParams);
|
FClipboardMode := (spClipboard in AParams);
|
||||||
if (CSVParams.SheetIndex >= 0) and (CSVParams.SheetIndex < FWorkbook.GetWorksheetCount)
|
if (CSVParams.SheetIndex >= 0) and (CSVParams.SheetIndex < book.GetWorksheetCount)
|
||||||
then n := CSVParams.SheetIndex
|
then n := CSVParams.SheetIndex
|
||||||
else n := 0;
|
else n := 0;
|
||||||
WriteSheet(AStream, FWorkbook.GetWorksheetByIndex(n));
|
WriteSheet(AStream, book.GetWorksheetByIndex(n));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsCSVWriter.WriteToStrings(AStrings: TStrings;
|
procedure TsCSVWriter.WriteToStrings(AStrings: TStrings;
|
||||||
|
@ -51,7 +51,7 @@ unit fpsExprParser;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, contnrs, fpstypes, fpspreadsheet, fpsrpn;
|
Classes, SysUtils, contnrs, fpstypes, fpsrpn;
|
||||||
|
|
||||||
type
|
type
|
||||||
{ Tokens }
|
{ Tokens }
|
||||||
@ -86,7 +86,7 @@ type
|
|||||||
TsResultTypes = set of TsResultType;
|
TsResultTypes = set of TsResultType;
|
||||||
|
|
||||||
TsExpressionResult = record
|
TsExpressionResult = record
|
||||||
Worksheet : TsWorksheet; // Worksheet containing the calculated cell
|
Worksheet : TsBasicWorksheet; // Worksheet containing the calculated cell
|
||||||
ResString : String;
|
ResString : String;
|
||||||
case ResultType : TsResultType of
|
case ResultType : TsResultType of
|
||||||
rtEmpty : ();
|
rtEmpty : ();
|
||||||
@ -586,7 +586,7 @@ type
|
|||||||
{ TsCellExprNode }
|
{ TsCellExprNode }
|
||||||
TsCellExprNode = class(TsExprNode)
|
TsCellExprNode = class(TsExprNode)
|
||||||
private
|
private
|
||||||
FWorksheet: TsWorksheet;
|
FWorksheet: TsBasicWorksheet;
|
||||||
FRow, FCol: Cardinal;
|
FRow, FCol: Cardinal;
|
||||||
FFlags: TsRelFlags;
|
FFlags: TsRelFlags;
|
||||||
FCell: PCell;
|
FCell: PCell;
|
||||||
@ -595,20 +595,20 @@ type
|
|||||||
protected
|
protected
|
||||||
function GetCol: Cardinal;
|
function GetCol: Cardinal;
|
||||||
function GetRow: Cardinal;
|
function GetRow: Cardinal;
|
||||||
function GetSheet: TsWorksheet;
|
function GetSheet: TsBasicWorksheet;
|
||||||
function GetSheetIndex: Integer;
|
function GetSheetIndex: Integer;
|
||||||
function GetSheetName: String;
|
function GetSheetName: String;
|
||||||
function GetWorkbook: TsWorkbook;
|
function GetWorkbook: TsBasicWorkbook;
|
||||||
procedure GetNodeValue(out AResult: TsExpressionResult); override;
|
procedure GetNodeValue(out AResult: TsExpressionResult); override;
|
||||||
public
|
public
|
||||||
constructor Create(AParser: TsExpressionParser; AWorksheet: TsWorksheet;
|
constructor Create(AParser: TsExpressionParser; AWorksheet: TsBasicWorksheet;
|
||||||
ASheetName: String; ARow, ACol: Cardinal; AFlags: TsRelFlags);
|
ASheetName: String; ARow, ACol: Cardinal; AFlags: TsRelFlags);
|
||||||
function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
|
function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
|
||||||
function AsString: string; override;
|
function AsString: string; override;
|
||||||
procedure Check; override;
|
procedure Check; override;
|
||||||
function Has3DLink: Boolean; override;
|
function Has3DLink: Boolean; override;
|
||||||
function NodeType: TsResultType; override;
|
function NodeType: TsResultType; override;
|
||||||
property Worksheet: TsWorksheet read FWorksheet;
|
property Worksheet: TsBasicWorksheet read FWorksheet;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TsCellRangeExprNode }
|
{ TsCellRangeExprNode }
|
||||||
@ -616,7 +616,7 @@ type
|
|||||||
|
|
||||||
TsCellRangeExprNode = class(TsExprNode)
|
TsCellRangeExprNode = class(TsExprNode)
|
||||||
private
|
private
|
||||||
FWorksheet: TsWorksheet;
|
FWorksheet: TsBasicWorksheet;
|
||||||
FRow: array[TsCellRangeIndex] of Cardinal;
|
FRow: array[TsCellRangeIndex] of Cardinal;
|
||||||
FCol: array[TsCellRangeIndex] of Cardinal;
|
FCol: array[TsCellRangeIndex] of Cardinal;
|
||||||
FSheetIndex: array[TsCellRangeIndex] of Integer;
|
FSheetIndex: array[TsCellRangeIndex] of Integer;
|
||||||
@ -626,17 +626,17 @@ type
|
|||||||
function GetCol(AIndex: TsCellRangeIndex): Cardinal;
|
function GetCol(AIndex: TsCellRangeIndex): Cardinal;
|
||||||
function GetRow(AIndex: TsCellRangeIndex): Cardinal;
|
function GetRow(AIndex: TsCellRangeIndex): Cardinal;
|
||||||
procedure GetNodeValue(out Result: TsExpressionResult); override;
|
procedure GetNodeValue(out Result: TsExpressionResult); override;
|
||||||
function GetWorkbook: TsWorkbook;
|
function GetWorkbook: TsBasicWorkbook;
|
||||||
public
|
public
|
||||||
constructor Create(AParser: TsExpressionParser; AWorksheet: TsWorksheet;
|
constructor Create(AParser: TsExpressionParser; AWorksheet: TsBasicWorksheet;
|
||||||
ASheet1, ASheet2: String; ARange: TsCellRange; AFlags: TsRelFlags);
|
ASheet1, ASheet2: String; ARange: TsCellRange; AFlags: TsRelFlags);
|
||||||
function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
|
function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
|
||||||
function AsString: String; override;
|
function AsString: String; override;
|
||||||
procedure Check; override;
|
procedure Check; override;
|
||||||
function Has3DLink: Boolean; override;
|
function Has3DLink: Boolean; override;
|
||||||
function NodeType: TsResultType; override;
|
function NodeType: TsResultType; override;
|
||||||
property Workbook: TsWorkbook read GetWorkbook;
|
property Workbook: TsBasicWorkbook read GetWorkbook;
|
||||||
property Worksheet: TsWorksheet read FWorksheet;
|
property Worksheet: TsBasicWorksheet read FWorksheet;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TsExpressionScanner }
|
{ TsExpressionScanner }
|
||||||
@ -700,7 +700,7 @@ type
|
|||||||
FIdentifiers: TsExprIdentifierDefs;
|
FIdentifiers: TsExprIdentifierDefs;
|
||||||
FHashList: TFPHashObjectlist;
|
FHashList: TFPHashObjectlist;
|
||||||
FDirty: Boolean;
|
FDirty: Boolean;
|
||||||
FWorksheet: TsWorksheet;
|
FWorksheet: TsBasicWorksheet;
|
||||||
FDialect: TsFormulaDialect;
|
FDialect: TsFormulaDialect;
|
||||||
FSourceCell: PCell;
|
FSourceCell: PCell;
|
||||||
FDestCell: PCell;
|
FDestCell: PCell;
|
||||||
@ -748,7 +748,7 @@ type
|
|||||||
property Dirty: Boolean read FDirty;
|
property Dirty: Boolean read FDirty;
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorksheet: TsWorksheet); virtual;
|
constructor Create(AWorksheet: TsBasicWorksheet); virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function IdentifierByName(AName: ShortString): TsExprIdentifierDef; virtual;
|
function IdentifierByName(AName: ShortString): TsExprIdentifierDef; virtual;
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
@ -771,7 +771,7 @@ type
|
|||||||
property RPNFormula: TsRPNFormula read GetRPNFormula write SetRPNFormula;
|
property RPNFormula: TsRPNFormula read GetRPNFormula write SetRPNFormula;
|
||||||
property Identifiers: TsExprIdentifierDefs read FIdentifiers write SetIdentifiers;
|
property Identifiers: TsExprIdentifierDefs read FIdentifiers write SetIdentifiers;
|
||||||
property BuiltIns: TsBuiltInExprCategories read FBuiltIns write SetBuiltIns;
|
property BuiltIns: TsBuiltInExprCategories read FBuiltIns write SetBuiltIns;
|
||||||
property Worksheet: TsWorksheet read FWorksheet;
|
property Worksheet: TsBasicWorksheet read FWorksheet;
|
||||||
property Dialect: TsFormulaDialect read FDialect write SetDialect;
|
property Dialect: TsFormulaDialect read FDialect write SetDialect;
|
||||||
property Contains3DRef: boolean read FContains3DRef;
|
property Contains3DRef: boolean read FContains3DRef;
|
||||||
|
|
||||||
@ -779,7 +779,7 @@ type
|
|||||||
|
|
||||||
TsSpreadsheetParser = class(TsExpressionParser)
|
TsSpreadsheetParser = class(TsExpressionParser)
|
||||||
public
|
public
|
||||||
constructor Create(AWorksheet: TsWorksheet); override;
|
constructor Create(AWorksheet: TsBasicWorksheet); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -865,7 +865,8 @@ const
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
typinfo, math, lazutf8, dateutils, fpsutils, fpsfunc, fpsStrings;
|
typinfo, math, lazutf8, dateutils,
|
||||||
|
fpsutils, fpsfunc, fpsStrings, fpspreadsheet;
|
||||||
|
|
||||||
const
|
const
|
||||||
cNull = #0;
|
cNull = #0;
|
||||||
@ -1372,7 +1373,7 @@ end;
|
|||||||
{ TsExpressionParser }
|
{ TsExpressionParser }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
constructor TsExpressionParser.Create(AWorksheet: TsWorksheet);
|
constructor TsExpressionParser.Create(AWorksheet: TsBasicWorksheet);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FDialect := fdExcelA1;
|
FDialect := fdExcelA1;
|
||||||
@ -2038,7 +2039,7 @@ procedure TsExpressionParser.SetRPNFormula(const AFormula: TsRPNFormula);
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
flags := AFormula[AIndex].RelFlags;
|
flags := AFormula[AIndex].RelFlags;
|
||||||
sn := FWorksheet.Workbook.GetWorksheetByIndex(idx).Name;
|
sn := (FWorksheet as TsWorksheet).Workbook.GetWorksheetByIndex(idx).Name;
|
||||||
ANode := TsCellExprNode.Create(Self, FWorksheet, sn, r, c, flags);
|
ANode := TsCellExprNode.Create(Self, FWorksheet, sn, r, c, flags);
|
||||||
end;
|
end;
|
||||||
dec(AIndex);
|
dec(AIndex);
|
||||||
@ -2053,9 +2054,9 @@ procedure TsExpressionParser.SetRPNFormula(const AFormula: TsRPNFormula);
|
|||||||
if fek = fekCellRange then
|
if fek = fekCellRange then
|
||||||
ANode := TsCellRangeExprNode.Create(self, FWorksheet, '', '', rng, flags)
|
ANode := TsCellRangeExprNode.Create(self, FWorksheet, '', '', rng, flags)
|
||||||
else begin
|
else begin
|
||||||
sn := FWorksheet.Workbook.GetWorksheetByIndex(AFormula[AIndex].Sheet).Name;
|
sn := (FWorksheet as TsWorksheet).Workbook.GetWorksheetByIndex(AFormula[AIndex].Sheet).Name;
|
||||||
if AFormula[AIndex].Sheet2 <> -1 then
|
if AFormula[AIndex].Sheet2 <> -1 then
|
||||||
sn2 := FWorksheet.Workbook.GetWorksheetByIndex(AFormula[AIndex].Sheet2).Name
|
sn2 := (FWorksheet as TsWorksheet).Workbook.GetWorksheetByIndex(AFormula[AIndex].Sheet2).Name
|
||||||
else
|
else
|
||||||
sn2 := '';
|
sn2 := '';
|
||||||
ANode := TsCellRangeExprNode.Create(self, FWorksheet, sn,sn2, rng, flags);
|
ANode := TsCellRangeExprNode.Create(self, FWorksheet, sn,sn2, rng, flags);
|
||||||
@ -2185,7 +2186,7 @@ end;
|
|||||||
{ TsSpreadsheetParser }
|
{ TsSpreadsheetParser }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
constructor TsSpreadsheetParser.Create(AWorksheet: TsWorksheet);
|
constructor TsSpreadsheetParser.Create(AWorksheet: TsBasicWorksheet);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorksheet);
|
inherited Create(AWorksheet);
|
||||||
BuiltIns := AllBuiltIns;
|
BuiltIns := AllBuiltIns;
|
||||||
@ -3763,7 +3764,7 @@ end;
|
|||||||
{ TsCellExprNode }
|
{ TsCellExprNode }
|
||||||
|
|
||||||
constructor TsCellExprNode.Create(AParser: TsExpressionParser;
|
constructor TsCellExprNode.Create(AParser: TsExpressionParser;
|
||||||
AWorksheet: TsWorksheet; ASheetName: String; ARow, ACol: Cardinal;
|
AWorksheet: TsBasicWorksheet; ASheetName: String; ARow, ACol: Cardinal;
|
||||||
AFlags: TsRelFlags);
|
AFlags: TsRelFlags);
|
||||||
begin
|
begin
|
||||||
FParser := AParser;
|
FParser := AParser;
|
||||||
@ -3772,7 +3773,7 @@ begin
|
|||||||
FRow := ARow;
|
FRow := ARow;
|
||||||
FCol := ACol;
|
FCol := ACol;
|
||||||
FFlags := AFlags;
|
FFlags := AFlags;
|
||||||
FCell := GetSheet.FindCell(FRow, FCol);
|
FCell := (GetSheet as TsWorksheet).FindCell(FRow, FCol);
|
||||||
if Has3DLink then FParser.FContains3DRef := true;
|
if Has3DLink then FParser.FContains3DRef := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3847,14 +3848,14 @@ var
|
|||||||
cell: PCell;
|
cell: PCell;
|
||||||
begin
|
begin
|
||||||
if Parser.CopyMode then
|
if Parser.CopyMode then
|
||||||
cell := FWorksheet.FindCell(GetRow, GetCol)
|
cell := (FWorksheet as TsWorksheet).FindCell(GetRow, GetCol)
|
||||||
else
|
else
|
||||||
cell := FCell;
|
cell := FCell;
|
||||||
|
|
||||||
if (cell <> nil) and HasFormula(cell) then
|
if (cell <> nil) and HasFormula(cell) then
|
||||||
case FWorksheet.GetCalcState(cell) of
|
case (FWorksheet as TsWorksheet).GetCalcState(cell) of
|
||||||
csNotCalculated:
|
csNotCalculated:
|
||||||
FWorksheet.CalcFormula(cell);
|
(FWorksheet as TsWorksheet).CalcFormula(cell);
|
||||||
csCalculating:
|
csCalculating:
|
||||||
raise ECalcEngine.CreateFmt(rsCircularReference, [GetCellString(cell^.Row, cell^.Col)]);
|
raise ECalcEngine.CreateFmt(rsCircularReference, [GetCellString(cell^.Row, cell^.Col)]);
|
||||||
end;
|
end;
|
||||||
@ -3873,20 +3874,23 @@ begin
|
|||||||
Result := FRow - FParser.FSourceCell^.Row + FParser.FDestCell^.Row;
|
Result := FRow - FParser.FSourceCell^.Row + FParser.FDestCell^.Row;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCellExprNode.GetSheet: TsWorksheet;
|
function TsCellExprNode.GetSheet: TsBasicWorksheet;
|
||||||
begin
|
begin
|
||||||
if FSheetName = '' then
|
if FSheetName = '' then
|
||||||
Result := FWorksheet
|
Result := FWorksheet
|
||||||
else
|
else
|
||||||
Result := GetWorkbook.GetWorksheetByName(FSheetName);
|
Result := (GetWorkbook as TsWorkbook).GetWorksheetByName(FSheetName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCellExprNode.GetSheetIndex: Integer;
|
function TsCellExprNode.GetSheetIndex: Integer;
|
||||||
|
var
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := GetWorkbook as TsWorkbook;
|
||||||
if FSheetName = '' then
|
if FSheetName = '' then
|
||||||
Result := GetWorkbook.GetWorksheetIndex(FWorksheet)
|
Result := book.GetWorksheetIndex(FWorksheet)
|
||||||
else
|
else
|
||||||
Result := GetWorkbook.GetWorksheetIndex(FSheetName);
|
Result := book.GetWorksheetIndex(FSheetName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCellExprNode.GetSheetName: String;
|
function TsCellExprNode.GetSheetName: String;
|
||||||
@ -3897,9 +3901,9 @@ begin
|
|||||||
Result := FSheetName;
|
Result := FSheetName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCellExprNode.GetWorkbook: TsWorkbook;
|
function TsCellExprNode.GetWorkbook: TsBasicWorkbook;
|
||||||
begin
|
begin
|
||||||
Result := FWorksheet.Workbook;
|
Result := (FWorksheet as TsWorksheet).Workbook;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCellExprNode.Has3DLink: Boolean;
|
function TsCellExprNode.Has3DLink: Boolean;
|
||||||
@ -3917,8 +3921,10 @@ end;
|
|||||||
{ TsCellRangeExprNode }
|
{ TsCellRangeExprNode }
|
||||||
|
|
||||||
constructor TsCellRangeExprNode.Create(AParser: TsExpressionParser;
|
constructor TsCellRangeExprNode.Create(AParser: TsExpressionParser;
|
||||||
AWorksheet: TsWorksheet; ASheet1, ASheet2: String; ARange: TsCellRange;
|
AWorksheet: TsBasicWorksheet; ASheet1, ASheet2: String; ARange: TsCellRange;
|
||||||
AFlags: TsRelFlags);
|
AFlags: TsRelFlags);
|
||||||
|
var
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
if (ASheet1 = '') and (ASheet2 <> '') then
|
if (ASheet1 = '') and (ASheet2 <> '') then
|
||||||
raise Exception.Create('Invalid parameters in cell range');
|
raise Exception.Create('Invalid parameters in cell range');
|
||||||
@ -3926,13 +3932,14 @@ begin
|
|||||||
FParser := AParser;
|
FParser := AParser;
|
||||||
FWorksheet := AWorksheet;
|
FWorksheet := AWorksheet;
|
||||||
FFlags := [];
|
FFlags := [];
|
||||||
|
book := TsWorkbook(GetWorkbook);
|
||||||
|
|
||||||
F3dRange := ((ASheet1 <> '') and (ASheet2 <> '') { and (ASheet1 <> ASheet2)}) or
|
F3dRange := ((ASheet1 <> '') and (ASheet2 <> '') { and (ASheet1 <> ASheet2)}) or
|
||||||
((ASheet1 <> '') and (ASheet2 = ''));
|
((ASheet1 <> '') and (ASheet2 = ''));
|
||||||
|
|
||||||
FSheetIndex[1] := GetWorkbook.GetWorksheetIndex(ASheet1);
|
FSheetIndex[1] := book.GetWorksheetIndex(ASheet1);
|
||||||
if ASheet2 <> '' then
|
if ASheet2 <> '' then
|
||||||
FSheetIndex[2] := GetWorkbook.GetWorksheetIndex(ASheet2)
|
FSheetIndex[2] := book.GetWorksheetIndex(ASheet2)
|
||||||
else
|
else
|
||||||
FSheetIndex[2] := FSheetIndex[1];
|
FSheetIndex[2] := FSheetIndex[1];
|
||||||
EnsureOrder(FSheetIndex[1], FSheetIndex[2]);
|
EnsureOrder(FSheetIndex[1], FSheetIndex[2]);
|
||||||
@ -3997,11 +4004,11 @@ begin
|
|||||||
if FSheetIndex[1] = -1 then
|
if FSheetIndex[1] = -1 then
|
||||||
s1 := FWorksheet.Name
|
s1 := FWorksheet.Name
|
||||||
else
|
else
|
||||||
s1 := Workbook.GetWorksheetByIndex(FSheetIndex[1]).Name;
|
s1 := (Workbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex[1]).Name;
|
||||||
if FSheetIndex[2] = -1 then
|
if FSheetIndex[2] = -1 then
|
||||||
s2 := FWorksheet.Name
|
s2 := FWorksheet.Name
|
||||||
else
|
else
|
||||||
s2 := Workbook.GetWorksheetByIndex(FSheetIndex[2]).Name;
|
s2 := (Workbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex[2]).Name;
|
||||||
r1 := GetRow(1);
|
r1 := GetRow(1);
|
||||||
c1 := GetCol(1);
|
c1 := GetCol(1);
|
||||||
r2 := GetRow(2);
|
r2 := GetRow(2);
|
||||||
@ -4068,12 +4075,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if not F3dRange then begin
|
if not F3dRange then begin
|
||||||
s[1] := Workbook.GetWorksheetIndex(FWorksheet);
|
s[1] := (Workbook as TsWorkbook).GetWorksheetIndex(FWorksheet);
|
||||||
s[2] := s[1];
|
s[2] := s[1];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
for ss := s[1] to s[2] do begin
|
for ss := s[1] to s[2] do begin
|
||||||
sheet := Workbook.GetWorksheetByIndex(ss);
|
sheet := (Workbook as TsWorkbook).GetWorksheetByIndex(ss);
|
||||||
for rr := r[1] to r[2] do
|
for rr := r[1] to r[2] do
|
||||||
for cc := c[1] to c[2] do
|
for cc := c[1] to c[2] do
|
||||||
begin
|
begin
|
||||||
@ -4106,9 +4113,9 @@ begin
|
|||||||
Result := FRow[AIndex] - FParser.FSourceCell^.Row + FParser.FDestCell^.Row;
|
Result := FRow[AIndex] - FParser.FSourceCell^.Row + FParser.FDestCell^.Row;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCellRangeExprNode.GetWorkbook: TsWorkbook;
|
function TsCellRangeExprNode.GetWorkbook: TsBasicWorkbook;
|
||||||
begin
|
begin
|
||||||
Result := FWorksheet.Workbook;
|
Result := (FWorksheet as TsWorksheet).Workbook;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsCellRangeExprNode.Has3DLink: Boolean;
|
function TsCellRangeExprNode.Has3DLink: Boolean;
|
||||||
@ -4144,7 +4151,7 @@ end;
|
|||||||
function ArgToCell(Arg: TsExpressionResult): PCell;
|
function ArgToCell(Arg: TsExpressionResult): PCell;
|
||||||
begin
|
begin
|
||||||
if Arg.ResultType = rtCell then
|
if Arg.ResultType = rtCell then
|
||||||
Result := Arg.Worksheet.FindCell(Arg.ResRow, Arg.ResCol)
|
Result := (Arg.Worksheet as TsWorksheet).FindCell(Arg.ResRow, Arg.ResCol)
|
||||||
else
|
else
|
||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
@ -4196,14 +4203,18 @@ begin
|
|||||||
cell := ArgToCell(Arg);
|
cell := ArgToCell(Arg);
|
||||||
if Assigned(cell) then
|
if Assigned(cell) then
|
||||||
case cell^.ContentType of
|
case cell^.ContentType of
|
||||||
cctNumber : Result := cell^.NumberValue;
|
cctNumber:
|
||||||
cctDateTime : Result := cell^.DateTimeValue;
|
Result := cell^.NumberValue;
|
||||||
cctBool : if cell^.BoolValue then result := 1.0;
|
cctDateTime:
|
||||||
cctUTF8String: begin
|
Result := cell^.DateTimeValue;
|
||||||
fs := Arg.Worksheet.Workbook.FormatSettings;
|
cctBool:
|
||||||
s := cell^.UTF8StringValue;
|
if cell^.BoolValue then result := 1.0;
|
||||||
TryStrToFloat(s, result, fs);
|
cctUTF8String:
|
||||||
end;
|
begin
|
||||||
|
fs := (Arg.Worksheet as TsWorksheet).Workbook.FormatSettings;
|
||||||
|
s := cell^.UTF8StringValue;
|
||||||
|
TryStrToFloat(s, result, fs);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -4222,7 +4233,7 @@ begin
|
|||||||
rtBoolean : if Arg.ResBoolean then Result := 1.0;
|
rtBoolean : if Arg.ResBoolean then Result := 1.0;
|
||||||
rtString,
|
rtString,
|
||||||
rtHyperlink : begin
|
rtHyperlink : begin
|
||||||
fs := Arg.Worksheet.Workbook.FormatSettings;
|
fs := (Arg.Worksheet as TsWorksheet).Workbook.FormatSettings;
|
||||||
TryStrToDateTime(ArgToString(Arg), Result, fs);
|
TryStrToDateTime(ArgToString(Arg), Result, fs);
|
||||||
end;
|
end;
|
||||||
rtCell : begin
|
rtCell : begin
|
||||||
@ -4265,7 +4276,7 @@ begin
|
|||||||
cctNumber : Result := Format('%g', [cell^.NumberValue]);
|
cctNumber : Result := Format('%g', [cell^.NumberValue]);
|
||||||
cctBool : if cell^.BoolValue then Result := '1' else Result := '0';
|
cctBool : if cell^.BoolValue then Result := '1' else Result := '0';
|
||||||
cctDateTime : begin
|
cctDateTime : begin
|
||||||
fs := Arg.Worksheet.Workbook.FormatSettings;
|
fs := (Arg.Worksheet as TsWorksheet).Workbook.FormatSettings;
|
||||||
dt := cell^.DateTimeValue;
|
dt := cell^.DateTimeValue;
|
||||||
if frac(dt) = 0.0 then
|
if frac(dt) = 0.0 then
|
||||||
Result := FormatDateTime(fs.LongTimeFormat, dt, fs)
|
Result := FormatDateTime(fs.LongTimeFormat, dt, fs)
|
||||||
@ -4301,7 +4312,7 @@ begin
|
|||||||
idx2 := arg.ResCellRange.Sheet2;
|
idx2 := arg.ResCellRange.Sheet2;
|
||||||
for idx := idx1 to idx2 do
|
for idx := idx1 to idx2 do
|
||||||
begin
|
begin
|
||||||
sheet := arg.Worksheet.Workbook.GetWorksheetByIndex(idx);
|
sheet := (arg.Worksheet as TsWorksheet).Workbook.GetWorksheetByIndex(idx);
|
||||||
for r := arg.ResCellRange.Row1 to arg.ResCellRange.Row2 do
|
for r := arg.ResCellRange.Row1 to arg.ResCellRange.Row2 do
|
||||||
for c := arg.ResCellRange.Col1 to arg.ResCellRange.Col2 do
|
for c := arg.ResCellRange.Col1 to arg.ResCellRange.Col2 do
|
||||||
begin
|
begin
|
||||||
@ -4393,7 +4404,7 @@ begin
|
|||||||
rtFloat : Result := (frac(AValue.ResFloat) = 0);
|
rtFloat : Result := (frac(AValue.ResFloat) = 0);
|
||||||
rtEmpty : Result := true;
|
rtEmpty : Result := true;
|
||||||
rtCell : begin
|
rtCell : begin
|
||||||
cell := AValue.Worksheet.FindCell(AValue.ResRow, AValue.ResCol);
|
cell := (AValue.Worksheet as TsWorksheet).FindCell(AValue.ResRow, AValue.ResCol);
|
||||||
if Assigned(cell) then
|
if Assigned(cell) then
|
||||||
case cell^.ContentType of
|
case cell^.ContentType of
|
||||||
cctNumber:
|
cctNumber:
|
||||||
@ -4415,7 +4426,7 @@ begin
|
|||||||
case AValue.ResultType of
|
case AValue.ResultType of
|
||||||
rtString: Result := true;
|
rtString: Result := true;
|
||||||
rtCell : begin
|
rtCell : begin
|
||||||
cell := AValue.Worksheet.FindCell(AValue.ResRow, AValue.ResCol);
|
cell := (AValue.Worksheet as TsWorksheet).FindCell(AValue.ResRow, AValue.ResCol);
|
||||||
Result := (cell <> nil) and (cell^.ContentType = cctUTF8String);
|
Result := (cell <> nil) and (cell^.ContentType = cctUTF8String);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -9,7 +9,7 @@ unit fpsfunc;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpstypes, fpspreadsheet;
|
Classes, SysUtils, fpstypes;
|
||||||
|
|
||||||
procedure RegisterStdBuiltins(AManager: TComponent);
|
procedure RegisterStdBuiltins(AManager: TComponent);
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Math, lazutf8, StrUtils, DateUtils,
|
Math, lazutf8, StrUtils, DateUtils,
|
||||||
xlsconst, {%H-}fpsPatches, fpsUtils, fpsnumformat, fpsexprparser;
|
xlsconst, {%H-}fpsPatches, fpsUtils, fpsnumformat, fpsexprparser, fpspreadsheet;
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
@ -1035,7 +1035,7 @@ begin
|
|||||||
for r := arg.ResCellRange.Row1 to arg.ResCellRange.Row2 do
|
for r := arg.ResCellRange.Row1 to arg.ResCellRange.Row2 do
|
||||||
for c := arg.ResCellRange.Col1 to arg.ResCellRange.Col2 do
|
for c := arg.ResCellRange.Col1 to arg.ResCellRange.Col2 do
|
||||||
begin
|
begin
|
||||||
cell := arg.Worksheet.FindCell(r, c);
|
cell := (arg.Worksheet as TsWorksheet).FindCell(r, c);
|
||||||
if (cell <> nil) then
|
if (cell <> nil) then
|
||||||
case cell^.ContentType of
|
case cell^.ContentType of
|
||||||
cctNumber, cctDateTime, cctBool : inc(n);
|
cctNumber, cctDateTime, cctBool : inc(n);
|
||||||
@ -1076,7 +1076,7 @@ begin
|
|||||||
rtCellRange:
|
rtCellRange:
|
||||||
for r := Args[0].ResCellRange.Row1 to Args[0].ResCellRange.Row2 do
|
for r := Args[0].ResCellRange.Row1 to Args[0].ResCellRange.Row2 do
|
||||||
for c := Args[0].ResCellRange.Col1 to Args[0].ResCellRange.Col2 do begin
|
for c := Args[0].ResCellRange.Col1 to Args[0].ResCellRange.Col2 do begin
|
||||||
cell := Args[0].Worksheet.FindCell(r, c);
|
cell := (Args[0].Worksheet as TsWorksheet).FindCell(r, c);
|
||||||
if cell = nil then
|
if cell = nil then
|
||||||
inc(n)
|
inc(n)
|
||||||
else
|
else
|
||||||
@ -1185,7 +1185,7 @@ begin
|
|||||||
|
|
||||||
// Get format settings for string-to-float or -to-datetime conversion
|
// Get format settings for string-to-float or -to-datetime conversion
|
||||||
if (Args[0].ResultType in [rtCell, rtCellRange]) then
|
if (Args[0].ResultType in [rtCell, rtCellRange]) then
|
||||||
fs := Args[0].Worksheet.FormatSettings
|
fs := (Args[0].Worksheet as TsWorksheet).FormatSettings
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
Result := ErrorResult(errArgError);
|
Result := ErrorResult(errArgError);
|
||||||
@ -1325,8 +1325,8 @@ begin
|
|||||||
if AFlag > 0 then
|
if AFlag > 0 then
|
||||||
begin
|
begin
|
||||||
if Length(Args) = 2 then
|
if Length(Args) = 2 then
|
||||||
addcell := Args[0].Worksheet.FindCell(r + dr, c + dc) else
|
addcell := (Args[0].Worksheet as TsWorksheet).FindCell(r + dr, c + dc) else
|
||||||
addCell := Args[2].Worksheet.FindCell(r + dr, c + dc);
|
addCell := (Args[2].Worksheet as TsWorksheet).FindCell(r + dr, c + dc);
|
||||||
if addcell <> nil then
|
if addcell <> nil then
|
||||||
case addcell^.Contenttype of
|
case addcell^.Contenttype of
|
||||||
cctNumber : addnumber := addcell^.NumberValue;
|
cctNumber : addnumber := addcell^.NumberValue;
|
||||||
@ -1335,7 +1335,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
cell := Args[0].Worksheet.FindCell(r, c);
|
cell := (Args[0].Worksheet as TsWorksheet).FindCell(r, c);
|
||||||
case compareType of
|
case compareType of
|
||||||
ctNumber:
|
ctNumber:
|
||||||
if cell <> nil then
|
if cell <> nil then
|
||||||
@ -1610,7 +1610,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
r1 := Args[1].ResCellRange.Row1;
|
r1 := Args[1].ResCellRange.Row1;
|
||||||
c1 := Args[1].ResCellRange.Col1;
|
c1 := Args[1].ResCellRange.Col1;
|
||||||
cell := Args[1].Worksheet.FindCell(r1, c1);
|
cell := (Args[1].Worksheet as TsWorksheet).FindCell(r1, c1);
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
Result := ErrorResult(errWrongType);
|
Result := ErrorResult(errWrongType);
|
||||||
@ -1652,8 +1652,8 @@ begin
|
|||||||
end else
|
end else
|
||||||
if stype = 'filename' then
|
if stype = 'filename' then
|
||||||
Result := Stringresult(
|
Result := Stringresult(
|
||||||
ExtractFilePath(Args[1].Worksheet.Workbook.FileName) + '[' +
|
ExtractFilePath((Args[1].Worksheet as TsWorksheet).Workbook.FileName) + '[' +
|
||||||
ExtractFileName(Args[1].Worksheet.Workbook.FileName) + ']' +
|
ExtractFileName((Args[1].Worksheet as TsWorksheet).Workbook.FileName) + ']' +
|
||||||
Args[1].Worksheet.Name
|
Args[1].Worksheet.Name
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@ -1710,7 +1710,7 @@ begin
|
|||||||
Result := StringResult('v');
|
Result := StringResult('v');
|
||||||
end else
|
end else
|
||||||
if stype = 'width' then
|
if stype = 'width' then
|
||||||
Result := FloatResult(Args[1].Worksheet.GetColWidth(c1, suChars))
|
Result := FloatResult((Args[1].Worksheet as TsWorksheet).GetColWidth(c1, suChars))
|
||||||
else
|
else
|
||||||
Result := ErrorResult(errWrongType);
|
Result := ErrorResult(errWrongType);
|
||||||
end;
|
end;
|
||||||
|
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fasthtmlparser,
|
Classes, SysUtils, fasthtmlparser,
|
||||||
fpstypes, fpspreadsheet, fpsClasses, fpsReaderWriter, fpsHTMLUtils;
|
fpstypes, fpsClasses, fpsReaderWriter, fpsHTMLUtils;
|
||||||
|
|
||||||
type
|
type
|
||||||
TsHTMLReader = class(TsCustomSpreadReader)
|
TsHTMLReader = class(TsCustomSpreadReader)
|
||||||
@ -55,7 +55,7 @@ type
|
|||||||
procedure AddRichTextParam(AFont: TsFont; AHyperlinkIndex: Integer = -1);
|
procedure AddRichTextParam(AFont: TsFont; AHyperlinkIndex: Integer = -1);
|
||||||
procedure FixRichTextParams(var AParams: TsRichTextParams);
|
procedure FixRichTextParams(var AParams: TsRichTextParams);
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure ReadFromStream(AStream: TStream; APassword: String = '';
|
procedure ReadFromStream(AStream: TStream; APassword: String = '';
|
||||||
AParams: TsStreamParams = []); override;
|
AParams: TsStreamParams = []); override;
|
||||||
@ -86,7 +86,7 @@ type
|
|||||||
function IsHyperlinkTarget(ACell: PCell; out ABookmark: String): Boolean;
|
function IsHyperlinkTarget(ACell: PCell; out ABookmark: String): Boolean;
|
||||||
procedure WriteBody(AStream: TStream);
|
procedure WriteBody(AStream: TStream);
|
||||||
procedure WriteStyles(AStream: TStream);
|
procedure WriteStyles(AStream: TStream);
|
||||||
procedure WriteWorksheet(AStream: TStream; ASheet: TsWorksheet);
|
procedure WriteWorksheet(AStream: TStream; ASheet: TsBasicWorksheet);
|
||||||
|
|
||||||
protected
|
protected
|
||||||
procedure InternalWriteToStream(AStream: TStream);
|
procedure InternalWriteToStream(AStream: TStream);
|
||||||
@ -106,7 +106,7 @@ type
|
|||||||
const AValue: double; ACell: PCell); override;
|
const AValue: double; ACell: PCell); override;
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
|
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
|
||||||
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
|
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
|
||||||
@ -143,7 +143,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
LConvEncoding, LazUTF8, URIParser, StrUtils, Math,
|
LConvEncoding, LazUTF8, URIParser, StrUtils, Math,
|
||||||
fpsUtils, fpsXMLCommon, fpsNumFormat;
|
fpsUtils, fpspreadsheet, fpsXMLCommon, fpsNumFormat;
|
||||||
|
|
||||||
const
|
const
|
||||||
MIN_FONTSIZE = 6;
|
MIN_FONTSIZE = 6;
|
||||||
@ -162,7 +162,7 @@ const
|
|||||||
{ TsHTMLReader }
|
{ TsHTMLReader }
|
||||||
{==============================================================================}
|
{==============================================================================}
|
||||||
|
|
||||||
constructor TsHTMLReader.Create(AWorkbook: TsWorkbook);
|
constructor TsHTMLReader.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
FEncoding := EncodingUTF8;
|
FEncoding := EncodingUTF8;
|
||||||
@ -203,13 +203,16 @@ var
|
|||||||
currSym: String;
|
currSym: String;
|
||||||
warning: String;
|
warning: String;
|
||||||
fntIndex: Integer;
|
fntIndex: Integer;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
// Empty strings are blank cells -- nothing to do
|
// Empty strings are blank cells -- nothing to do
|
||||||
if (AText = '') then
|
if (AText = '') then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
// Create cell
|
// Create cell
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := sheet.AddCell(ARow, ACol);
|
||||||
|
|
||||||
// Format, rich-text formatting parameters
|
// Format, rich-text formatting parameters
|
||||||
// Reject non-used runs; adapt font index to the workbook.
|
// Reject non-used runs; adapt font index to the workbook.
|
||||||
@ -223,10 +226,10 @@ begin
|
|||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
// Get cell font and use it in the cell format
|
// Get cell font and use it in the cell format
|
||||||
fntIndex := FWorkbook.FindFont(FCellFont.FontName, FCellFont.Size,
|
fntIndex := (FWorkbook as TsWorkbook).FindFont(FCellFont.FontName, FCellFont.Size,
|
||||||
FCellFont.Style, FCellFont.Color, FCellFont.Position);
|
FCellFont.Style, FCellFont.Color, FCellFont.Position);
|
||||||
if fntIndex = -1 then
|
if fntIndex = -1 then
|
||||||
fntIndex := FWorkbook.AddFont(FCellFont.FontName, FCellFont.Size,
|
fntIndex := (FWorkbook as TsWorkbook).AddFont(FCellFont.FontName, FCellFont.Size,
|
||||||
FCellFont.Style, FCellFont.Color, FCellFont.Position);
|
FCellFont.Style, FCellFont.Color, FCellFont.Position);
|
||||||
FCurrCellFormat.FontIndex := fntIndex;
|
FCurrCellFormat.FontIndex := fntIndex;
|
||||||
end;
|
end;
|
||||||
@ -234,25 +237,25 @@ begin
|
|||||||
Include(FCurrCellFormat.UsedFormattingFields, uffFont) else
|
Include(FCurrCellFormat.UsedFormattingFields, uffFont) else
|
||||||
Exclude(FCurrCellFormat.UsedFormattingFields, uffFont);
|
Exclude(FCurrCellFormat.UsedFormattingFields, uffFont);
|
||||||
// Store the cell format in the workbook
|
// Store the cell format in the workbook
|
||||||
cell^.FormatIndex := FWorkbook.AddCellFormat(FCurrCellFormat);
|
cell^.FormatIndex := (FWorkbook as TsWorkbook).AddCellFormat(FCurrCellFormat);
|
||||||
|
|
||||||
// Merged cells
|
// Merged cells
|
||||||
if (FColSpan > 0) or (FRowSpan > 0) then begin
|
if (FColSpan > 0) or (FRowSpan > 0) then begin
|
||||||
FWorksheet.MergeCells(ARow, ACol, ARow + FRowSpan, ACol + FColSpan);
|
sheet.MergeCells(ARow, ACol, ARow + FRowSpan, ACol + FColSpan);
|
||||||
FRowSpan := 0;
|
FRowSpan := 0;
|
||||||
FColSpan := 0;
|
FColSpan := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Hyperlink
|
// Hyperlink
|
||||||
if FHRef <> '' then begin
|
if FHRef <> '' then begin
|
||||||
FWorksheet.WriteHyperlink(cell, FHRef);
|
sheet.WriteHyperlink(cell, FHRef);
|
||||||
FHRef := '';
|
FHRef := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Case: Do not try to interpret the strings. --> everything is a LABEL cell.
|
// Case: Do not try to interpret the strings. --> everything is a LABEL cell.
|
||||||
if not HTMLParams.DetectContentType then
|
if not HTMLParams.DetectContentType then
|
||||||
begin
|
begin
|
||||||
FWorksheet.WriteText(cell, AText, FCurrRichTextParams);
|
sheet.WriteText(cell, AText, FCurrRichTextParams);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -261,9 +264,9 @@ begin
|
|||||||
dblValue, nf, decs, currSym, warning) then
|
dblValue, nf, decs, currSym, warning) then
|
||||||
begin
|
begin
|
||||||
if currSym <> '' then
|
if currSym <> '' then
|
||||||
FWorksheet.WriteCurrency(cell, dblValue, nfCurrency, decs, currSym)
|
sheet.WriteCurrency(cell, dblValue, nfCurrency, decs, currSym)
|
||||||
else
|
else
|
||||||
FWorksheet.WriteNumber(cell, dblValue, nf, decs);
|
sheet.WriteNumber(cell, dblValue, nf, decs);
|
||||||
if warning <> '' then
|
if warning <> '' then
|
||||||
FWorkbook.AddErrorMsg('Cell %s: %s', [GetCellString(ARow, ACol), warning]);
|
FWorkbook.AddErrorMsg('Cell %s: %s', [GetCellString(ARow, ACol), warning]);
|
||||||
exit;
|
exit;
|
||||||
@ -273,19 +276,19 @@ begin
|
|||||||
// No idea how to apply the date/time formatsettings here...
|
// No idea how to apply the date/time formatsettings here...
|
||||||
if IsDateTimevalue(AText, FFormatSettings, dtValue, nf) then
|
if IsDateTimevalue(AText, FFormatSettings, dtValue, nf) then
|
||||||
begin
|
begin
|
||||||
FWorksheet.WriteDateTime(cell, dtValue, nf);
|
sheet.WriteDateTime(cell, dtValue, nf);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Check for a BOOLEAN cell
|
// Check for a BOOLEAN cell
|
||||||
if IsBoolValue(AText, HTMLParams.TrueText, HTMLParams.FalseText, boolValue) then
|
if IsBoolValue(AText, HTMLParams.TrueText, HTMLParams.FalseText, boolValue) then
|
||||||
begin
|
begin
|
||||||
FWorksheet.WriteBoolValue(cell, boolValue);
|
sheet.WriteBoolValue(cell, boolValue);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// What is left is handled as a TEXT cell
|
// What is left is handled as a TEXT cell
|
||||||
FWorksheet.WriteText(cell, AText, FCurrRichTextParams);
|
sheet.WriteText(cell, AText, FCurrRichTextParams);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Stores a font in the internal font list. Does not allow duplicates. }
|
{ Stores a font in the internal font list. Does not allow duplicates. }
|
||||||
@ -378,9 +381,9 @@ begin
|
|||||||
for i:=0 to High(FCurrRichTextParams) do
|
for i:=0 to High(FCurrRichTextParams) do
|
||||||
begin
|
begin
|
||||||
fnt := TsFont(FFontList[FCurrRichTextParams[i].FontIndex]);
|
fnt := TsFont(FFontList[FCurrRichTextParams[i].FontIndex]);
|
||||||
fntIndex := FWorkbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := (FWorkbook as TsWorkbook).FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
if fntIndex = -1 then
|
if fntIndex = -1 then
|
||||||
fntIndex := FWorkbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := (FWorkbook as TsWorkbook).AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
FCurrRichTextParams[i].FontIndex := fntIndex;
|
FCurrRichTextParams[i].FontIndex := fntIndex;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -485,6 +488,7 @@ end;
|
|||||||
procedure TsHTMLReader.ProcessEndTags(NoCaseTag, ActualTag: String);
|
procedure TsHTMLReader.ProcessEndTags(NoCaseTag, ActualTag: String);
|
||||||
var
|
var
|
||||||
fntIndex: Integer;
|
fntIndex: Integer;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
Unused(ActualTag);
|
Unused(ActualTag);
|
||||||
if not FInTable then exit;
|
if not FInTable then exit;
|
||||||
@ -501,9 +505,11 @@ begin
|
|||||||
|
|
||||||
if not FInCell then exit;
|
if not FInCell then exit;
|
||||||
|
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
if (NoCaseTag = '</TD>') or (NoCaseTag = '</TH>') then
|
if (NoCaseTag = '</TD>') or (NoCaseTag = '</TH>') then
|
||||||
begin
|
begin
|
||||||
while FWorksheet.IsMerged(FWorksheet.FindCell(FCurrRow, FCurrCol)) do
|
while sheet.IsMerged(sheet.FindCell(FCurrRow, FCurrCol)) do
|
||||||
inc(FCurrCol);
|
inc(FCurrCol);
|
||||||
AddCell(FCurrRow, FCurrCol, FCellText);
|
AddCell(FCurrRow, FCurrCol, FCellText);
|
||||||
FInCell := false;
|
FInCell := false;
|
||||||
@ -807,7 +813,7 @@ begin
|
|||||||
if idx = -1 then
|
if idx = -1 then
|
||||||
idx := FAttrList.IndexOfName('size');
|
idx := FAttrList.IndexOfName('size');
|
||||||
if idx > -1 then begin
|
if idx > -1 then begin
|
||||||
defFntSize := FWorkbook.GetDefaultFont.Size;
|
defFntSize := (FWorkbook as TsWorkbook).GetDefaultFont.Size;
|
||||||
s := FAttrList[idx].Value;
|
s := FAttrList[idx].Value;
|
||||||
case s of
|
case s of
|
||||||
'medium', '3' : AFont.Size := defFntSize;
|
'medium', '3' : AFont.Size := defFntSize;
|
||||||
@ -1022,7 +1028,7 @@ procedure TsHTMLReader.InitFont(AFont: TsFont);
|
|||||||
var
|
var
|
||||||
fnt: TsFont;
|
fnt: TsFont;
|
||||||
begin
|
begin
|
||||||
fnt := FWorkbook.GetDefaultFont;
|
fnt := (FWorkbook as TsWorkbook).GetDefaultFont;
|
||||||
AFont.FontName := fnt.FontName;
|
AFont.FontName := fnt.FontName;
|
||||||
AFont.Size := fnt.Size;
|
AFont.Size := fnt.Size;
|
||||||
AFont.Style := fnt.Style;
|
AFont.Style := fnt.Style;
|
||||||
@ -1056,10 +1062,10 @@ begin
|
|||||||
try
|
try
|
||||||
list.LoadFromStream(AStream);
|
list.LoadFromStream(AStream);
|
||||||
ReadFromStrings(list, AParams);
|
ReadFromStrings(list, AParams);
|
||||||
if FWorkbook.GetWorksheetCount = 0 then
|
if (FWorkbook as TsWorkbook).GetWorksheetCount = 0 then
|
||||||
begin
|
begin
|
||||||
FWorkbook.AddErrorMsg('Requested table not found, or no tables in html file');
|
FWorkbook.AddErrorMsg('Requested table not found, or no tables in html file');
|
||||||
FWorkbook.AddWorksheet('Dummy');
|
TsWorkbook(FWorkbook).AddWorksheet('Dummy');
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
list.Free;
|
list.Free;
|
||||||
@ -1106,14 +1112,14 @@ begin
|
|||||||
inc(FTableCounter);
|
inc(FTableCounter);
|
||||||
if (HTMLParams.TableIndex >= 0) and (FTableCounter <> HTMLParams.TableIndex) then
|
if (HTMLParams.TableIndex >= 0) and (FTableCounter <> HTMLParams.TableIndex) then
|
||||||
exit;
|
exit;
|
||||||
FWorksheet := FWorkbook.AddWorksheet(Format('Table #%d', [FTableCounter+1]));
|
FWorksheet := TsWorkbook(FWorkbook).AddWorksheet(Format('Table #%d', [FTableCounter+1]));
|
||||||
FInTable := true;
|
FInTable := true;
|
||||||
FCurrRow := -1;
|
FCurrRow := -1;
|
||||||
FCurrCol := -1;
|
FCurrCol := -1;
|
||||||
FFontStack.Push(AddFont(FCurrFont));
|
FFontStack.Push(AddFont(FCurrFont));
|
||||||
FAttrList.Parse(ActualTag);
|
FAttrList.Parse(ActualTag);
|
||||||
ReadFont(FCurrFont);
|
ReadFont(FCurrFont);
|
||||||
FWorkbook.ReplaceFont(DEFAULT_FONTINDEX, FCurrFont.FontName, FCurrFont.Size,
|
TsWorkbook(FWorkbook).ReplaceFont(DEFAULT_FONTINDEX, FCurrFont.FontName, FCurrFont.Size,
|
||||||
FCurrFont.Style, FCurrFont.Color, FCurrFont.Position);
|
FCurrFont.Style, FCurrFont.Color, FCurrFont.Position);
|
||||||
FCellFont.CopyOf(FCurrFont);
|
FCellFont.CopyOf(FCurrFont);
|
||||||
exit;
|
exit;
|
||||||
@ -1179,7 +1185,7 @@ end;
|
|||||||
{==============================================================================}
|
{==============================================================================}
|
||||||
{ TsHTMLWriter }
|
{ TsHTMLWriter }
|
||||||
{==============================================================================}
|
{==============================================================================}
|
||||||
constructor TsHTMLWriter.Create(AWorkbook: TsWorkbook);
|
constructor TsHTMLWriter.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
FPointSeparatorSettings := DefaultFormatSettings;
|
FPointSeparatorSettings := DefaultFormatSettings;
|
||||||
@ -1311,17 +1317,20 @@ var
|
|||||||
col: PCol;
|
col: PCol;
|
||||||
w: Single;
|
w: Single;
|
||||||
rLast: Cardinal;
|
rLast: Cardinal;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
if AColIndex < 0 then // Row header column
|
if AColIndex < 0 then // Row header column
|
||||||
begin
|
begin
|
||||||
rLast := FWorksheet.GetLastRowIndex;
|
rLast := sheet.GetLastRowIndex;
|
||||||
w := FWorkbook.ConvertUnits(Length(IntToStr(rLast)) + 2, suChars, suPoints);
|
w := (FWorkbook as TsWorkbook).ConvertUnits(Length(IntToStr(rLast)) + 2, suChars, suPoints);
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
w := FWorksheet.ReadDefaultColWidth(suPoints);
|
w := sheet.ReadDefaultColWidth(suPoints);
|
||||||
col := FWorksheet.FindCol(AColIndex);
|
col := sheet.FindCol(AColIndex);
|
||||||
if (col <> nil) and (col^.Width > 0) then
|
if (col <> nil) and (col^.Width > 0) then
|
||||||
w := FWorkbook.ConvertUnits(col^.Width, FWorkbook.Units, suPoints);
|
w := (FWorkbook as TsWorkbook).ConvertUnits(col^.Width, FWorkbook.Units, suPoints);
|
||||||
end;
|
end;
|
||||||
Result:= Format(' width="%.1fpt"', [w], FPointSeparatorSettings);
|
Result:= Format(' width="%.1fpt"', [w], FPointSeparatorSettings);
|
||||||
end;
|
end;
|
||||||
@ -1342,7 +1351,7 @@ function TsHTMLWriter.GetFontAsStyle(AFontIndex: Integer): String;
|
|||||||
var
|
var
|
||||||
font: TsFont;
|
font: TsFont;
|
||||||
begin
|
begin
|
||||||
font := FWorkbook.GetFont(AFontIndex);
|
font := (FWorkbook as TsWorkbook).GetFont(AFontIndex);
|
||||||
Result := Format('font-family:''%s'';font-size:%.1fpt;color:%s;', [
|
Result := Format('font-family:''%s'';font-size:%.1fpt;color:%s;', [
|
||||||
font.FontName, font.Size, ColorToHTMLColorStr(font.Color)], FPointSeparatorSettings);
|
font.FontName, font.Size, ColorToHTMLColorStr(font.Color)], FPointSeparatorSettings);
|
||||||
if fssBold in font.Style then
|
if fssBold in font.Style then
|
||||||
@ -1381,7 +1390,7 @@ var
|
|||||||
r1, r2, c1, c2: Cardinal;
|
r1, r2, c1, c2: Cardinal;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
FWorksheet.FindMergedRange(AMergeBase, r1, c1, r2, c2);
|
(FWorksheet as TsWorksheet).FindMergedRange(AMergeBase, r1, c1, r2, c2);
|
||||||
if c1 <> c2 then
|
if c1 <> c2 then
|
||||||
Result := Result + ' colspan="' + IntToStr(c2-c1+1) + '"';
|
Result := Result + ' colspan="' + IntToStr(c2-c1+1) + '"';
|
||||||
if r1 <> r2 then
|
if r1 <> r2 then
|
||||||
@ -1393,11 +1402,11 @@ var
|
|||||||
h: Single;
|
h: Single;
|
||||||
row: PRow;
|
row: PRow;
|
||||||
begin
|
begin
|
||||||
h := FWorksheet.ReadDefaultRowHeight(suPoints);
|
h := (FWorksheet as TsWorksheet).ReadDefaultRowHeight(suPoints);
|
||||||
row := FWorksheet.FindRow(ARowIndex);
|
row := (FWorksheet as TsWorksheet).FindRow(ARowIndex);
|
||||||
if row <> nil then begin
|
if row <> nil then begin
|
||||||
if row^.RowHeightType = rhtCustom then
|
if row^.RowHeightType = rhtCustom then
|
||||||
h := abs(FWorkbook.ConvertUnits(row^.Height, FWorkbook.Units, suPoints));
|
h := abs((FWorkbook as TsWorkbook).ConvertUnits(row^.Height, FWorkbook.Units, suPoints));
|
||||||
end;
|
end;
|
||||||
Result := Format(' height="%.1fpt"', [h], FPointSeparatorSettings);
|
Result := Format(' height="%.1fpt"', [h], FPointSeparatorSettings);
|
||||||
end;
|
end;
|
||||||
@ -1441,7 +1450,7 @@ end;
|
|||||||
|
|
||||||
procedure TsHTMLWriter.InternalWriteToStream(AStream: TStream);
|
procedure TsHTMLWriter.InternalWriteToStream(AStream: TStream);
|
||||||
begin
|
begin
|
||||||
FWorkbook.UpdateCaches;
|
(FWorkbook as TsWorkbook).UpdateCaches;
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'<!DOCTYPE html>');
|
'<!DOCTYPE html>');
|
||||||
|
|
||||||
@ -1472,9 +1481,9 @@ begin
|
|||||||
if ACell = nil then
|
if ACell = nil then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
for i:=0 to FWorkbook.GetWorksheetCount-1 do
|
for i:=0 to (FWorkbook as TsWorkbook).GetWorksheetCount-1 do
|
||||||
begin
|
begin
|
||||||
sheet := FWorkbook.GetWorksheetByIndex(i);
|
sheet := (FWorkbook as TsWorkbook).GetWorksheetByIndex(i);
|
||||||
for hyperlink in sheet.Hyperlinks do
|
for hyperlink in sheet.Hyperlinks do
|
||||||
begin
|
begin
|
||||||
SplitHyperlink(hyperlink^.Target, target, ABookmark);
|
SplitHyperlink(hyperlink^.Target, target, ABookmark);
|
||||||
@ -1503,20 +1512,23 @@ end;
|
|||||||
procedure TsHTMLWriter.WriteBody(AStream: TStream);
|
procedure TsHTMLWriter.WriteBody(AStream: TStream);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'<body>');
|
'<body>');
|
||||||
if FWindowsClipboardMode or (HTMLParams.SheetIndex < 0) then // active sheet
|
if FWindowsClipboardMode or (HTMLParams.SheetIndex < 0) then // active sheet
|
||||||
begin
|
begin
|
||||||
if FWorkbook.ActiveWorksheet = nil then
|
if book.ActiveWorksheet = nil then
|
||||||
FWorkbook.SelectWorksheet(FWorkbook.GetWorksheetByIndex(0));
|
book.SelectWorksheet(book.GetWorksheetByIndex(0));
|
||||||
WriteWorksheet(AStream, FWorkbook.ActiveWorksheet)
|
WriteWorksheet(AStream, book.ActiveWorksheet)
|
||||||
end else
|
end else
|
||||||
if HTMLParams.SheetIndex = MaxInt then // all sheets
|
if HTMLParams.SheetIndex = MaxInt then // all sheets
|
||||||
for i:=0 to FWorkbook.GetWorksheetCount-1 do
|
for i:=0 to book.GetWorksheetCount-1 do
|
||||||
WriteWorksheet(AStream, FWorkbook.GetWorksheetByIndex(i))
|
WriteWorksheet(AStream, book.GetWorksheetByIndex(i))
|
||||||
else // specific sheet
|
else // specific sheet
|
||||||
WriteWorksheet(AStream, FWorkbook.GetWorksheetbyIndex(HTMLParams.SheetIndex));
|
WriteWorksheet(AStream, book.GetWorksheetbyIndex(HTMLParams.SheetIndex));
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'</body>');
|
'</body>');
|
||||||
end;
|
end;
|
||||||
@ -1538,7 +1550,7 @@ var
|
|||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
Unused(AValue, ACol, ARow);
|
Unused(AValue, ACol, ARow);
|
||||||
s := FWorksheet.ReadAsText(ACell);
|
s := (FWorksheet as TsWorksheet).ReadAsText(ACell);
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'<div>' + s + '</div>');
|
'<div>' + s + '</div>');
|
||||||
end;
|
end;
|
||||||
@ -1549,7 +1561,7 @@ var
|
|||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
Unused(AValue, ACol, ARow);
|
Unused(AValue, ACol, ARow);
|
||||||
s := FWOrksheet.ReadAsText(ACell);
|
s := (FWorksheet as TsWorksheet).ReadAsText(ACell);
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'<div>' + s + '</div>');
|
'<div>' + s + '</div>');
|
||||||
end;
|
end;
|
||||||
@ -1593,13 +1605,13 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
|
|
||||||
style := '';
|
style := '';
|
||||||
cellfnt := FWorksheet.ReadCellFont(ACell);
|
cellfnt := (FWorksheet as TsWorksheet).ReadCellFont(ACell);
|
||||||
|
|
||||||
// Hyperlink
|
// Hyperlink
|
||||||
target := '';
|
target := '';
|
||||||
if FWorksheet.HasHyperlink(ACell) then
|
if FWorksheet.HasHyperlink(ACell) then
|
||||||
begin
|
begin
|
||||||
hyperlink := FWorksheet.FindHyperlink(ACell);
|
hyperlink := (FWorksheet as TsWorksheet).FindHyperlink(ACell);
|
||||||
SplitHyperlink(hyperlink^.Target, target, bookmark);
|
SplitHyperlink(hyperlink^.Target, target, bookmark);
|
||||||
|
|
||||||
n := Length(hyperlink^.Target);
|
n := Length(hyperlink^.Target);
|
||||||
@ -1657,7 +1669,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
// formatted section
|
// formatted section
|
||||||
rtParam := ACell^.RichTextParams[i];
|
rtParam := ACell^.RichTextParams[i];
|
||||||
fnt := FWorkbook.GetFont(rtParam.FontIndex);
|
fnt := (FWorkbook as TsWorkbook).GetFont(rtParam.FontIndex);
|
||||||
style := GetFontAsStyle(rtParam.FontIndex);
|
style := GetFontAsStyle(rtParam.FontIndex);
|
||||||
if style <> '' then
|
if style <> '' then
|
||||||
style := ' style="' + style +'"';
|
style := ' style="' + style +'"';
|
||||||
@ -1684,7 +1696,7 @@ var
|
|||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
Unused(ARow, ACol, AValue);
|
Unused(ARow, ACol, AValue);
|
||||||
s := FWorksheet.ReadAsText(ACell, FWorkbook.FormatSettings);
|
s := (FWorksheet as TsWorksheet).ReadAsText(ACell, FWorkbook.FormatSettings);
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'<div>' + s + '</div>');
|
'<div>' + s + '</div>');
|
||||||
end;
|
end;
|
||||||
@ -1697,8 +1709,8 @@ var
|
|||||||
begin
|
begin
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'<style>' + LineEnding);
|
'<style>' + LineEnding);
|
||||||
for i:=0 to FWorkbook.GetNumCellFormats-1 do begin
|
for i:=0 to (FWorkbook as TsWorkbook).GetNumCellFormats-1 do begin
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(i);
|
fmt := (FWorkbook as TsWorkbook).GetPointerToCellFormat(i);
|
||||||
fmtStr := CellFormatAsString(fmt);
|
fmtStr := CellFormatAsString(fmt);
|
||||||
if fmtStr <> '' then
|
if fmtStr <> '' then
|
||||||
fmtStr := Format(' td.style%d {%s}' + LineEnding, [i+1, fmtStr]);
|
fmtStr := Format(' td.style%d {%s}' + LineEnding, [i+1, fmtStr]);
|
||||||
@ -1741,7 +1753,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsHTMLWriter.WriteWorksheet(AStream: TStream; ASheet: TsWorksheet);
|
procedure TsHTMLWriter.WriteWorksheet(AStream: TStream; ASheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
r, rFirst, rLast: LongInt;
|
r, rFirst, rLast: LongInt;
|
||||||
c, cFirst, cLast: LongInt;
|
c, cFirst, cLast: LongInt;
|
||||||
@ -1751,18 +1763,19 @@ var
|
|||||||
style, s: String;
|
style, s: String;
|
||||||
fixedLayout: Boolean;
|
fixedLayout: Boolean;
|
||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
|
sheet: TsWorksheet absolute ASheet;
|
||||||
begin
|
begin
|
||||||
FWorksheet := ASheet;
|
FWorksheet := ASheet;
|
||||||
|
|
||||||
rFirst := FWorksheet.GetFirstRowIndex;
|
rFirst := sheet.GetFirstRowIndex;
|
||||||
cFirst := FWorksheet.GetFirstColIndex;
|
cFirst := sheet.GetFirstColIndex;
|
||||||
rLast := FWorksheet.GetLastOccupiedRowIndex;
|
rLast := sheet.GetLastOccupiedRowIndex;
|
||||||
cLast := FWorksheet.GetLastOccupiedColIndex;
|
cLast := sheet.GetLastOccupiedColIndex;
|
||||||
|
|
||||||
fixedLayout := false;
|
fixedLayout := false;
|
||||||
for c:=cFirst to cLast do
|
for c:=cFirst to cLast do
|
||||||
begin
|
begin
|
||||||
col := FWorksheet.GetCol(c);
|
col := sheet.GetCol(c);
|
||||||
if col <> nil then
|
if col <> nil then
|
||||||
begin
|
begin
|
||||||
fixedLayout := true;
|
fixedLayout := true;
|
||||||
@ -1812,7 +1825,7 @@ begin
|
|||||||
style := ' style="' + style + '"';
|
style := ' style="' + style + '"';
|
||||||
if fixedLayout then
|
if fixedLayout then
|
||||||
style := style + GetColWidthAsAttr(c);
|
style := style + GetColWidthAsAttr(c);
|
||||||
col := FWorksheet.FindCol(c);
|
col := sheet.FindCol(c);
|
||||||
if (col <> nil) and (col^.FormatIndex > 0) then
|
if (col <> nil) and (col^.FormatIndex > 0) then
|
||||||
style := style + Format(' class="style%d"', [col^.FormatIndex+1]);
|
style := style + Format(' class="style%d"', [col^.FormatIndex+1]);
|
||||||
|
|
||||||
@ -1822,7 +1835,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
for r := rFirst to rLast do begin
|
for r := rFirst to rLast do begin
|
||||||
row := FWorksheet.FindRow(r);
|
row := sheet.FindRow(r);
|
||||||
AppendToStream(AStream,
|
AppendToStream(AStream,
|
||||||
'<tr>' + LineEnding);
|
'<tr>' + LineEnding);
|
||||||
|
|
||||||
@ -1840,8 +1853,8 @@ begin
|
|||||||
|
|
||||||
for c := cFirst to cLast do begin
|
for c := cFirst to cLast do begin
|
||||||
// Pointer to current cell in loop
|
// Pointer to current cell in loop
|
||||||
cell := FWorksheet.FindCell(r, c);
|
cell := sheet.FindCell(r, c);
|
||||||
col := FWorksheet.FindCol(c);
|
col := sheet.FindCol(c);
|
||||||
|
|
||||||
// Cell formatting via predefined styles ("class")
|
// Cell formatting via predefined styles ("class")
|
||||||
style := '';
|
style := '';
|
||||||
@ -1849,17 +1862,17 @@ begin
|
|||||||
if cell <> nil then
|
if cell <> nil then
|
||||||
begin
|
begin
|
||||||
style := Format(' class="style%d"', [cell^.FormatIndex+1]);
|
style := Format(' class="style%d"', [cell^.FormatIndex+1]);
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(cell^.FormatIndex);
|
fmt := (FWorkbook as TsWorkbook).GetPointerToCellFormat(cell^.FormatIndex);
|
||||||
end else
|
end else
|
||||||
if (row <> nil) and (row^.FormatIndex > 0) then
|
if (row <> nil) and (row^.FormatIndex > 0) then
|
||||||
begin
|
begin
|
||||||
style := Format(' class="style%d"', [row^.FormatIndex+1]);
|
style := Format(' class="style%d"', [row^.FormatIndex+1]);
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(row^.FormatIndex);
|
fmt := (FWorkbook as TsWorkbook).GetPointerToCellFormat(row^.FormatIndex);
|
||||||
end else
|
end else
|
||||||
if (col <> nil) and (col^.FormatIndex > 0) then
|
if (col <> nil) and (col^.FormatIndex > 0) then
|
||||||
begin
|
begin
|
||||||
style := Format(' class="style%d"', [col^.FormatIndex+1]);
|
style := Format(' class="style%d"', [col^.FormatIndex+1]);
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(col^.FormatIndex);
|
fmt := (FWorkbook as TsWorkbook).GetPointerToCellFormat(col^.FormatIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Overriding differences between html and fps formatting
|
// Overriding differences between html and fps formatting
|
||||||
@ -1888,9 +1901,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Merged cells
|
// Merged cells
|
||||||
if FWorksheet.IsMerged(cell) then
|
if sheet.IsMerged(cell) then
|
||||||
begin
|
begin
|
||||||
if FWorksheet.IsMergeBase(cell) then
|
if sheet.IsMergeBase(cell) then
|
||||||
style := style + GetMergedRangeAsStyle(cell)
|
style := style + GetMergedRangeAsStyle(cell)
|
||||||
else
|
else
|
||||||
Continue;
|
Continue;
|
||||||
|
@ -5,7 +5,7 @@ unit fpsHTMLUtils;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, contnrs, fpstypes, fpspreadsheet;
|
Classes, SysUtils, contnrs, fpstypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
TsHTMLEntity = record
|
TsHTMLEntity = record
|
||||||
@ -39,11 +39,11 @@ type
|
|||||||
|
|
||||||
TsTagCase = (tcLowercase, tcUppercase, tcProperCase);
|
TsTagCase = (tcLowercase, tcUppercase, tcProperCase);
|
||||||
|
|
||||||
procedure HTMLToRichText(AWorkbook: TsWorkbook; AFont: TsFont;
|
procedure HTMLToRichText(AWorkbook: TsBasicWorkbook; AFont: TsFont;
|
||||||
const AHTMLText: String; out APlainText: String;
|
const AHTMLText: String; out APlainText: String;
|
||||||
out ARichTextParams: TsRichTextParams);
|
out ARichTextParams: TsRichTextParams);
|
||||||
|
|
||||||
procedure RichTextToHTML(AWorkbook: TsWorkbook; AFont: TsFont;
|
procedure RichTextToHTML(AWorkbook: TsBasicWorkbook; AFont: TsFont;
|
||||||
const APlainText: String; const ARichTextParams: TsRichTextParams;
|
const APlainText: String; const ARichTextParams: TsRichTextParams;
|
||||||
out AHTMLText: String; APrefix:String = ''; ATagCase: TsTagCase = tcLowercase);
|
out AHTMLText: String; APrefix:String = ''; ATagCase: TsTagCase = tcLowercase);
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
math, lazUtf8, fasthtmlparser,
|
math, lazUtf8, fasthtmlparser,
|
||||||
fpsUtils, fpsClasses;
|
fpsUtils, fpsClasses, fpspreadsheet;
|
||||||
|
|
||||||
const
|
const
|
||||||
// http://unicode.e-workers.de/entities.php
|
// http://unicode.e-workers.de/entities.php
|
||||||
@ -940,7 +940,7 @@ end;
|
|||||||
@@param ARichtTextParams Rich-text parameters corresponding to the embedded
|
@@param ARichtTextParams Rich-text parameters corresponding to the embedded
|
||||||
html tags
|
html tags
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure HTMLToRichText(AWorkbook: TsWorkbook; AFont: TsFont;
|
procedure HTMLToRichText(AWorkbook: TsBasicWorkbook; AFont: TsFont;
|
||||||
const AHTMLText: String; out APlainText: String;
|
const AHTMLText: String; out APlainText: String;
|
||||||
out ARichTextParams: TsRichTextParams);
|
out ARichTextParams: TsRichTextParams);
|
||||||
var
|
var
|
||||||
@ -949,7 +949,7 @@ var
|
|||||||
len: Integer;
|
len: Integer;
|
||||||
nrtp: Integer;
|
nrtp: Integer;
|
||||||
begin
|
begin
|
||||||
analyzer := TsHTMLAnalyzer.Create(AWorkbook, AFont, AHTMLText + '<end>');
|
analyzer := TsHTMLAnalyzer.Create(AWorkbook as TsWorkbook, AFont, AHTMLText + '<end>');
|
||||||
try
|
try
|
||||||
analyzer.PreserveSpaces := true;
|
analyzer.PreserveSpaces := true;
|
||||||
analyzer.Exec;
|
analyzer.Exec;
|
||||||
@ -1187,7 +1187,7 @@ end;
|
|||||||
Constructs a html-coded string from a plain text string and
|
Constructs a html-coded string from a plain text string and
|
||||||
rich-text parameters
|
rich-text parameters
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure RichTextToHTML(AWorkbook: TsWorkbook; AFont: TsFont;
|
procedure RichTextToHTML(AWorkbook: TsBasicWorkbook; AFont: TsFont;
|
||||||
const APlainText: String; const ARichTextParams: TsRichTextParams;
|
const APlainText: String; const ARichTextParams: TsRichTextParams;
|
||||||
out AHTMLText: String; APrefix: String = ''; ATagCase: TsTagCase = tcLowercase);
|
out AHTMLText: String; APrefix: String = ''; ATagCase: TsTagCase = tcLowercase);
|
||||||
var
|
var
|
||||||
@ -1197,7 +1197,7 @@ begin
|
|||||||
AHTMLText := APlainText
|
AHTMLText := APlainText
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
composer := TsHTMLComposer.Create(AWorkbook, AFont, APrefix, ATagCase);
|
composer := TsHTMLComposer.Create(AWorkbook as TsWorkbook, AFont, APrefix, ATagCase);
|
||||||
try
|
try
|
||||||
AHTMLText := composer.Exec(APlainText, ARichTextParams);
|
AHTMLText := composer.Exec(APlainText, ARichTextParams);
|
||||||
finally
|
finally
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@ unit fpsPalette;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpstypes, fpspreadsheet;
|
Classes, SysUtils, fpstypes;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ type
|
|||||||
procedure AddExcelColors;
|
procedure AddExcelColors;
|
||||||
function AddUniqueColor(AColor: TsColor; ABigEndian: Boolean = false): Integer;
|
function AddUniqueColor(AColor: TsColor; ABigEndian: Boolean = false): Integer;
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
procedure CollectFromWorkbook(AWorkbook: TsWorkbook);
|
procedure CollectFromWorkbook(AWorkbook: TsBasicWorkbook);
|
||||||
function ColorUsedInWorkbook(APaletteIndex: Integer; AWorkbook: TsWorkbook): Boolean;
|
function ColorUsedInWorkbook(APaletteIndex: Integer; AWorkbook: TsBasicWorkbook): Boolean;
|
||||||
function FindClosestColorIndex(AColor: TsColor; AMaxPaletteCount: Integer = -1): Integer;
|
function FindClosestColorIndex(AColor: TsColor; AMaxPaletteCount: Integer = -1): Integer;
|
||||||
function FindColor(AColor: TsColor; AMaxPaletteCount: Integer = -1;
|
function FindColor(AColor: TsColor; AMaxPaletteCount: Integer = -1;
|
||||||
AStartIndex: Integer = 0): Integer;
|
AStartIndex: Integer = 0): Integer;
|
||||||
@ -51,7 +51,7 @@ type
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
fpsutils;
|
fpsutils, fpspreadsheet;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
If a palette is coded as big-endian (e.g. by copying the rgb values from
|
If a palette is coded as big-endian (e.g. by copying the rgb values from
|
||||||
@ -223,18 +223,19 @@ end;
|
|||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Collects the colors used in the specified workbook
|
Collects the colors used in the specified workbook
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsPalette.CollectFromWorkbook(AWorkbook: TsWorkbook);
|
procedure TsPalette.CollectFromWorkbook(AWorkbook: TsBasicWorkbook);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
book: TsWorkbook absolute AWorkbook;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
fmt: TsCellFormat;
|
fmt: TsCellFormat;
|
||||||
fnt: TsFont;
|
fnt: TsFont;
|
||||||
cb: TsCellBorder;
|
cb: TsCellBorder;
|
||||||
begin
|
begin
|
||||||
for i:=0 to AWorkbook.GetWorksheetCount-1 do
|
for i:=0 to book.GetWorksheetCount-1 do
|
||||||
begin
|
begin
|
||||||
sheet := AWorkbook.GetWorksheetByIndex(i);
|
sheet := book.GetWorksheetByIndex(i);
|
||||||
for cell in sheet.Cells do begin
|
for cell in sheet.Cells do begin
|
||||||
fmt := sheet.ReadCellFormat(cell);
|
fmt := sheet.ReadCellFormat(cell);
|
||||||
if (uffBackground in fmt.UsedFormattingFields) then
|
if (uffBackground in fmt.UsedFormattingFields) then
|
||||||
@ -244,7 +245,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
if (uffFont in fmt.UsedFormattingFields) then
|
if (uffFont in fmt.UsedFormattingFields) then
|
||||||
begin
|
begin
|
||||||
fnt := AWorkbook.GetFont(fmt.FontIndex);
|
fnt := book.GetFont(fmt.FontIndex);
|
||||||
AddUniqueColor(fnt.Color);
|
AddUniqueColor(fnt.Color);
|
||||||
end;
|
end;
|
||||||
if (uffBorder in fmt.UsedFormattingFields) then
|
if (uffBorder in fmt.UsedFormattingFields) then
|
||||||
@ -264,8 +265,9 @@ end;
|
|||||||
@result True if the color is used by at least one cell, false if not.
|
@result True if the color is used by at least one cell, false if not.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsPalette.ColorUsedInWorkbook(APaletteIndex: Integer;
|
function TsPalette.ColorUsedInWorkbook(APaletteIndex: Integer;
|
||||||
AWorkbook: TsWorkbook): Boolean;
|
AWorkbook: TsBasicWorkbook): Boolean;
|
||||||
var
|
var
|
||||||
|
book: TsWorkbook absolute AWorkbook;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -279,12 +281,12 @@ begin
|
|||||||
exit(false);
|
exit(false);
|
||||||
|
|
||||||
Result := true;
|
Result := true;
|
||||||
for i:=0 to AWorkbook.GetWorksheetCount-1 do
|
for i:=0 to book.GetWorksheetCount-1 do
|
||||||
begin
|
begin
|
||||||
sheet := AWorkbook.GetWorksheetByIndex(i);
|
sheet := book.GetWorksheetByIndex(i);
|
||||||
for cell in sheet.Cells do
|
for cell in sheet.Cells do
|
||||||
begin
|
begin
|
||||||
fmt := AWorkbook.GetPointerToCellFormat(cell^.FormatIndex);
|
fmt := book.GetPointerToCellFormat(cell^.FormatIndex);
|
||||||
if (uffBackground in fmt^.UsedFormattingFields) then
|
if (uffBackground in fmt^.UsedFormattingFields) then
|
||||||
begin
|
begin
|
||||||
if fmt^.Background.BgColor = color then exit;
|
if fmt^.Background.BgColor = color then exit;
|
||||||
@ -296,7 +298,7 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
if (uffFont in fmt^.UsedFormattingFields) then
|
if (uffFont in fmt^.UsedFormattingFields) then
|
||||||
begin
|
begin
|
||||||
fnt := AWorkbook.GetFont(fmt^.FontIndex);
|
fnt := book.GetFont(fmt^.FontIndex);
|
||||||
if fnt.Color = color then
|
if fnt.Color = color then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
@ -30,23 +30,6 @@ type
|
|||||||
TsWorksheet = class;
|
TsWorksheet = class;
|
||||||
TsWorkbook = class;
|
TsWorkbook = class;
|
||||||
|
|
||||||
{@@ Worksheet user interface options:
|
|
||||||
@param soShowGridLines Show or hide the grid lines in the spreadsheet
|
|
||||||
@param soShowHeaders Show or hide the column or row headers of the
|
|
||||||
spreadsheet
|
|
||||||
@param soHasFrozenPanes If set a number of rows and columns of the
|
|
||||||
spreadsheet is fixed and does not scroll. The number
|
|
||||||
is defined by LeftPaneWidth and TopPaneHeight.
|
|
||||||
@param soHidden Worksheet is hidden.
|
|
||||||
@param soProtected Worksheet is protected
|
|
||||||
@param soPanesProtection Panes are locked due to workbook protection }
|
|
||||||
TsSheetOption = (soShowGridLines, soShowHeaders, soHasFrozenPanes, soHidden,
|
|
||||||
soProtected, soPanesProtection);
|
|
||||||
|
|
||||||
{@@ Set of user interface options
|
|
||||||
@ see TsSheetOption }
|
|
||||||
TsSheetOptions = set of TsSheetOption;
|
|
||||||
|
|
||||||
|
|
||||||
{ TsWorksheet }
|
{ TsWorksheet }
|
||||||
|
|
||||||
@ -77,10 +60,9 @@ type
|
|||||||
|
|
||||||
{@@ The worksheet contains a list of cells and provides a variety of methods
|
{@@ The worksheet contains a list of cells and provides a variety of methods
|
||||||
to read or write data to the cells, or to change their formatting. }
|
to read or write data to the cells, or to change their formatting. }
|
||||||
TsWorksheet = class
|
TsWorksheet = class(TsBasicWorksheet)
|
||||||
private
|
private
|
||||||
FWorkbook: TsWorkbook;
|
FWorkbook: TsWorkbook;
|
||||||
FName: String; // Name of the worksheet (displayed at the tab)
|
|
||||||
FCells: TsCells;
|
FCells: TsCells;
|
||||||
FComments: TsComments;
|
FComments: TsComments;
|
||||||
FMergedCells: TsMergedCells;
|
FMergedCells: TsMergedCells;
|
||||||
@ -94,7 +76,6 @@ type
|
|||||||
FSelection: TsCellRangeArray;
|
FSelection: TsCellRangeArray;
|
||||||
FLeftPaneWidth: Integer;
|
FLeftPaneWidth: Integer;
|
||||||
FTopPaneHeight: Integer;
|
FTopPaneHeight: Integer;
|
||||||
FOptions: TsSheetOptions;
|
|
||||||
FFirstRowIndex: Cardinal;
|
FFirstRowIndex: Cardinal;
|
||||||
FFirstColIndex: Cardinal;
|
FFirstColIndex: Cardinal;
|
||||||
FLastRowIndex: Cardinal;
|
FLastRowIndex: Cardinal;
|
||||||
@ -105,7 +86,6 @@ type
|
|||||||
FBiDiMode: TsBiDiMode;
|
FBiDiMode: TsBiDiMode;
|
||||||
FCryptoInfo: TsCryptoInfo;
|
FCryptoInfo: TsCryptoInfo;
|
||||||
FPageLayout: TsPageLayout;
|
FPageLayout: TsPageLayout;
|
||||||
FProtection: TsWorksheetProtections;
|
|
||||||
FVirtualColCount: Cardinal;
|
FVirtualColCount: Cardinal;
|
||||||
FVirtualRowCount: Cardinal;
|
FVirtualRowCount: Cardinal;
|
||||||
FZoomFactor: Double;
|
FZoomFactor: Double;
|
||||||
@ -125,7 +105,6 @@ type
|
|||||||
procedure SetBiDiMode(AValue: TsBiDiMode);
|
procedure SetBiDiMode(AValue: TsBiDiMode);
|
||||||
procedure SetDefaultColWidth(AValue: Single);
|
procedure SetDefaultColWidth(AValue: Single);
|
||||||
procedure SetDefaultRowHeight(AValue: Single);
|
procedure SetDefaultRowHeight(AValue: Single);
|
||||||
procedure SetName(const AName: String);
|
|
||||||
procedure SetVirtualColCount(AValue: Cardinal);
|
procedure SetVirtualColCount(AValue: Cardinal);
|
||||||
procedure SetVirtualRowCount(AValue: Cardinal);
|
procedure SetVirtualRowCount(AValue: Cardinal);
|
||||||
procedure SetZoomFactor(AValue: Double);
|
procedure SetZoomFactor(AValue: Double);
|
||||||
@ -152,6 +131,9 @@ type
|
|||||||
AFromIndex, AToIndex: Cardinal);
|
AFromIndex, AToIndex: Cardinal);
|
||||||
procedure ExchangeCells(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
procedure ExchangeCells(ARow1, ACol1, ARow2, ACol2: Cardinal);
|
||||||
|
|
||||||
|
// inherited setters/getters
|
||||||
|
procedure SetName(const AName: String); override;
|
||||||
|
|
||||||
public
|
public
|
||||||
{ Base methods }
|
{ Base methods }
|
||||||
constructor Create;
|
constructor Create;
|
||||||
@ -523,7 +505,6 @@ type
|
|||||||
|
|
||||||
// Hyperlinks
|
// Hyperlinks
|
||||||
function FindHyperlink(ACell: PCell): PsHyperlink;
|
function FindHyperlink(ACell: PCell): PsHyperlink;
|
||||||
function HasHyperlink(ACell: PCell): Boolean;
|
|
||||||
function ReadHyperlink(ACell: PCell): TsHyperlink;
|
function ReadHyperlink(ACell: PCell): TsHyperlink;
|
||||||
procedure RemoveHyperlink(ACell: PCell);
|
procedure RemoveHyperlink(ACell: PCell);
|
||||||
function ValidHyperlink(AValue: String; out AErrMsg: String): Boolean;
|
function ValidHyperlink(AValue: String; out AErrMsg: String): Boolean;
|
||||||
@ -567,7 +548,6 @@ type
|
|||||||
|
|
||||||
{ Protection }
|
{ Protection }
|
||||||
procedure Protect(AEnable: Boolean);
|
procedure Protect(AEnable: Boolean);
|
||||||
function IsProtected: Boolean;
|
|
||||||
|
|
||||||
{ Notification of changed cells, rows or columns }
|
{ Notification of changed cells, rows or columns }
|
||||||
procedure ChangedCell(ARow, ACol: Cardinal);
|
procedure ChangedCell(ARow, ACol: Cardinal);
|
||||||
@ -592,13 +572,8 @@ type
|
|||||||
property Hyperlinks: TsHyperlinks read FHyperlinks;
|
property Hyperlinks: TsHyperlinks read FHyperlinks;
|
||||||
{@@ FormatSettings for localization of some formatting strings }
|
{@@ FormatSettings for localization of some formatting strings }
|
||||||
property FormatSettings: TFormatSettings read GetFormatSettings;
|
property FormatSettings: TFormatSettings read GetFormatSettings;
|
||||||
{@@ Name of the sheet. In the popular spreadsheet applications this is
|
|
||||||
displayed at the tab of the sheet. }
|
|
||||||
property Name: string read FName write SetName;
|
|
||||||
{@@ Parameters to be used for printing by the Office applications }
|
{@@ Parameters to be used for printing by the Office applications }
|
||||||
property PageLayout: TsPageLayout read FPageLayout write FPageLayout;
|
property PageLayout: TsPageLayout read FPageLayout write FPageLayout;
|
||||||
{@@ Worksheet protection options }
|
|
||||||
property Protection: TsWorksheetProtections read FProtection write FProtection;
|
|
||||||
{@@ List of all row records of the worksheet having a non-standard row height }
|
{@@ List of all row records of the worksheet having a non-standard row height }
|
||||||
property Rows: TIndexedAVLTree read FRows;
|
property Rows: TIndexedAVLTree read FRows;
|
||||||
{@@ Workbook to which the worksheet belongs }
|
{@@ Workbook to which the worksheet belongs }
|
||||||
@ -619,9 +594,6 @@ type
|
|||||||
|
|
||||||
// These are properties to interface to TsWorksheetGrid
|
// These are properties to interface to TsWorksheetGrid
|
||||||
property BiDiMode: TsBiDiMode read FBiDiMode write SetBiDiMode;
|
property BiDiMode: TsBiDiMode read FBiDiMode write SetBiDiMode;
|
||||||
{@@ Parameters controlling visibility of grid lines and row/column headers,
|
|
||||||
usage of frozen panes etc. }
|
|
||||||
property Options: TsSheetOptions read FOptions write FOptions;
|
|
||||||
{@@ Column index of the selected cell of this worksheet }
|
{@@ Column index of the selected cell of this worksheet }
|
||||||
property ActiveCellCol: Cardinal read FActiveCellCol;
|
property ActiveCellCol: Cardinal read FActiveCellCol;
|
||||||
{@@ Row index of the selected cell of this worksheet }
|
{@@ Row index of the selected cell of this worksheet }
|
||||||
@ -656,43 +628,6 @@ type
|
|||||||
property OnZoom: TsNotifyEvent read FOnZoom write FOnZoom;
|
property OnZoom: TsNotifyEvent read FOnZoom write FOnZoom;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@
|
|
||||||
Option flags for the workbook
|
|
||||||
|
|
||||||
@param boVirtualMode If in virtual mode date are not taken from cells
|
|
||||||
when a spreadsheet is written to file, but are
|
|
||||||
provided by means of the event OnWriteCellData.
|
|
||||||
Similarly, when data are read they are not added
|
|
||||||
as cells but passed the the event OnReadCellData;
|
|
||||||
@param boBufStream When this option is set a buffered stream is used
|
|
||||||
for writing (a memory stream swapping to disk) or
|
|
||||||
reading (a file stream pre-reading chunks of data
|
|
||||||
to memory)
|
|
||||||
@param boFileStream Uses file streams and temporary files during
|
|
||||||
reading and writing. Lowest memory consumptions,
|
|
||||||
but slow.
|
|
||||||
@param boAutoCalc Automatically recalculate formulas whenever a
|
|
||||||
cell value changes.
|
|
||||||
@param boCalcBeforeSaving Calculates formulas before saving the file.
|
|
||||||
Otherwise there are no results when the file is
|
|
||||||
loaded back by fpspreadsheet.
|
|
||||||
@param boReadFormulas Allows to turn off reading of rpn formulas; this
|
|
||||||
is a precaution since formulas not correctly
|
|
||||||
implemented by fpspreadsheet could crash the
|
|
||||||
reading operation.
|
|
||||||
@param boWriteZoomfactor Instructs the writer to write the current zoom
|
|
||||||
factors of the worksheets to file.
|
|
||||||
@param boAbortReadOnFormulaError Aborts reading if a formula error is
|
|
||||||
encountered
|
|
||||||
@param boIgnoreFormulas Formulas are not checked and not calculated.
|
|
||||||
Cannot be used for biff formats. }
|
|
||||||
TsWorkbookOption = (boVirtualMode, boBufStream, boFileStream,
|
|
||||||
boAutoCalc, boCalcBeforeSaving, boReadFormulas, boWriteZoomFactor,
|
|
||||||
boAbortReadOnFormulaError, boIgnoreFormulas);
|
|
||||||
|
|
||||||
{@@ Set of option flags for the workbook }
|
|
||||||
TsWorkbookOptions = set of TsWorkbookOption;
|
|
||||||
|
|
||||||
{@@ Event fired when reading a file in virtual mode. Read data are provided in
|
{@@ Event fired when reading a file in virtual mode. Read data are provided in
|
||||||
the "ADataCell" (which is not added to the worksheet in virtual mode). }
|
the "ADataCell" (which is not added to the worksheet in virtual mode). }
|
||||||
TsWorkbookReadCellDataEvent = procedure(Sender: TObject; ARow, ACol: Cardinal;
|
TsWorkbookReadCellDataEvent = procedure(Sender: TObject; ARow, ACol: Cardinal;
|
||||||
@ -707,40 +642,32 @@ type
|
|||||||
{@@ FSome action has an effect on existing formulas which must be corrected. }
|
{@@ FSome action has an effect on existing formulas which must be corrected. }
|
||||||
TsFormulaCorrection = (fcWorksheetRenamed);
|
TsFormulaCorrection = (fcWorksheetRenamed);
|
||||||
|
|
||||||
{ TsWorkbook }
|
|
||||||
|
{ TsWorkbook }
|
||||||
|
|
||||||
{@@ The workbook contains the worksheets and provides methods for reading from
|
{@@ The workbook contains the worksheets and provides methods for reading from
|
||||||
and writing to file. }
|
and writing to file. }
|
||||||
TsWorkbook = class
|
TsWorkbook = class(TsBasicWorkbook)
|
||||||
private
|
private
|
||||||
{ Internal data }
|
{ Internal data }
|
||||||
FWorksheets: TFPList;
|
FWorksheets: TFPList;
|
||||||
FFormatID: TsSpreadFormatID;
|
|
||||||
FBuiltinFontCount: Integer;
|
FBuiltinFontCount: Integer;
|
||||||
FReadWriteFlag: TsReadWriteFlag;
|
FReadWriteFlag: TsReadWriteFlag;
|
||||||
FCalculationLock: Integer;
|
FCalculationLock: Integer;
|
||||||
FOptions: TsWorkbookOptions;
|
|
||||||
FActiveWorksheet: TsWorksheet;
|
FActiveWorksheet: TsWorksheet;
|
||||||
FOnOpenWorkbook: TNotifyEvent;
|
FOnOpenWorkbook: TNotifyEvent;
|
||||||
FOnReadCellData: TsWorkbookReadCellDataEvent;
|
|
||||||
FOnChangeWorksheet: TsWorksheetEvent;
|
FOnChangeWorksheet: TsWorksheetEvent;
|
||||||
FOnRenameWorksheet: TsWorksheetEvent;
|
FOnRenameWorksheet: TsWorksheetEvent;
|
||||||
FOnAddWorksheet: TsWorksheetEvent;
|
FOnAddWorksheet: TsWorksheetEvent;
|
||||||
FOnRemoveWorksheet: TsRemoveWorksheetEvent;
|
FOnRemoveWorksheet: TsRemoveWorksheetEvent;
|
||||||
FOnRemovingWorksheet: TsWorksheetEvent;
|
FOnRemovingWorksheet: TsWorksheetEvent;
|
||||||
FOnSelectWorksheet: TsWorksheetEvent;
|
FOnSelectWorksheet: TsWorksheetEvent;
|
||||||
FFileName: String;
|
FOnReadCellData: TsWorkbookReadCellDataEvent;
|
||||||
FLockCount: Integer;
|
FLockCount: Integer;
|
||||||
FLog: TStringList;
|
|
||||||
FSearchEngine: TObject;
|
FSearchEngine: TObject;
|
||||||
FUnits: TsSizeUnits;
|
|
||||||
FProtection: TsWorkbookProtections;
|
|
||||||
FCryptoInfo: TsCryptoInfo;
|
FCryptoInfo: TsCryptoInfo;
|
||||||
{FrevisionsCrypto: TsCryptoInfo;} // Commented out because it needs revision handling
|
{FrevisionsCrypto: TsCryptoInfo;} // Commented out because it needs revision handling
|
||||||
|
|
||||||
{ Setter/Getter }
|
|
||||||
function GetErrorMsg: String;
|
|
||||||
|
|
||||||
{ Callback procedures }
|
{ Callback procedures }
|
||||||
procedure RemoveWorksheetsCallback(data, arg: pointer);
|
procedure RemoveWorksheetsCallback(data, arg: pointer);
|
||||||
|
|
||||||
@ -764,11 +691,6 @@ type
|
|||||||
// procedure ReCalc;
|
// procedure ReCalc;
|
||||||
|
|
||||||
public
|
public
|
||||||
{@@ A copy of SysUtil's DefaultFormatSettings (converted to UTF8) to provide
|
|
||||||
some kind of localization to some formatting strings.
|
|
||||||
Can be modified before loading/writing files }
|
|
||||||
FormatSettings: TFormatSettings;
|
|
||||||
|
|
||||||
{ Base methods }
|
{ Base methods }
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -809,7 +731,7 @@ type
|
|||||||
function GetWorksheetByIndex(AIndex: Integer): TsWorksheet;
|
function GetWorksheetByIndex(AIndex: Integer): TsWorksheet;
|
||||||
function GetWorksheetByName(AName: String): TsWorksheet;
|
function GetWorksheetByName(AName: String): TsWorksheet;
|
||||||
function GetWorksheetCount: Integer;
|
function GetWorksheetCount: Integer;
|
||||||
function GetWorksheetIndex(AWorksheet: TsWorksheet): Integer; overload;
|
function GetWorksheetIndex(AWorksheet: TsBasicWorksheet): Integer; overload;
|
||||||
function GetWorksheetIndex(const AWorksheetName: String): Integer; overload;
|
function GetWorksheetIndex(const AWorksheetName: String): Integer; overload;
|
||||||
procedure RemoveAllWorksheets;
|
procedure RemoveAllWorksheets;
|
||||||
procedure RemoveAllEmptyWorksheets;
|
procedure RemoveAllEmptyWorksheets;
|
||||||
@ -886,33 +808,16 @@ type
|
|||||||
procedure UpdateCaches;
|
procedure UpdateCaches;
|
||||||
procedure GetLastRowColIndex(out ALastRow, ALastCol: Cardinal);
|
procedure GetLastRowColIndex(out ALastRow, ALastCol: Cardinal);
|
||||||
|
|
||||||
{ Protection }
|
|
||||||
function IsProtected: Boolean;
|
|
||||||
|
|
||||||
{ Notification }
|
{ Notification }
|
||||||
procedure ChangedWorksheet(AWorksheet: TsWorksheet);
|
procedure ChangedWorksheet(AWorksheet: TsWorksheet);
|
||||||
procedure DisableNotifications;
|
procedure DisableNotifications;
|
||||||
procedure EnableNotifications;
|
procedure EnableNotifications;
|
||||||
function NotificationsEnabled: Boolean;
|
function NotificationsEnabled: Boolean;
|
||||||
|
|
||||||
{ Error messages }
|
|
||||||
procedure AddErrorMsg(const AMsg: String); overload;
|
|
||||||
procedure AddErrorMsg(const AMsg: String; const Args: array of const); overload;
|
|
||||||
procedure ClearErrorList;
|
|
||||||
|
|
||||||
{@@ Identifies the "active" worksheet (only for visual controls)}
|
{@@ Identifies the "active" worksheet (only for visual controls)}
|
||||||
property ActiveWorksheet: TsWorksheet read FActiveWorksheet write SelectWorksheet;
|
property ActiveWorksheet: TsWorksheet read FActiveWorksheet write SelectWorksheet;
|
||||||
property CryptoInfo: TsCryptoInfo read FCryptoInfo write FCryptoInfo;
|
property CryptoInfo: TsCryptoInfo read FCryptoInfo write FCryptoInfo;
|
||||||
{@@ Retrieves error messages collected during reading/writing }
|
|
||||||
property ErrorMsg: String read GetErrorMsg;
|
|
||||||
{@@ Filename of the saved workbook }
|
|
||||||
property FileName: String read FFileName;
|
|
||||||
{@@ Identifies the file format which was detected when reading the file }
|
|
||||||
property FileFormatID: TsSpreadFormatID read FFormatID;
|
|
||||||
property Options: TsWorkbookOptions read FOptions write FOptions;
|
|
||||||
{property RevisionsCrypto: TsCryptoInfo read FRevisionsCrypto write FRevisionsCrypto;}
|
{property RevisionsCrypto: TsCryptoInfo read FRevisionsCrypto write FRevisionsCrypto;}
|
||||||
property Protection: TsWorkbookProtections read FProtection write FProtection;
|
|
||||||
property Units: TsSizeUnits read FUnits;
|
|
||||||
|
|
||||||
{@@ This event fires whenever a new worksheet is added }
|
{@@ This event fires whenever a new worksheet is added }
|
||||||
property OnAddWorksheet: TsWorksheetEvent read FOnAddWorksheet write FOnAddWorksheet;
|
property OnAddWorksheet: TsWorksheetEvent read FOnAddWorksheet write FOnAddWorksheet;
|
||||||
@ -1217,7 +1122,6 @@ begin
|
|||||||
FActiveCellRow := UNASSIGNED_ROW_COL_INDEX;
|
FActiveCellRow := UNASSIGNED_ROW_COL_INDEX;
|
||||||
FActiveCellCol := UNASSIGNED_ROW_COL_INDEX;
|
FActiveCellCol := UNASSIGNED_ROW_COL_INDEX;
|
||||||
|
|
||||||
FProtection := DEFAULT_SHEET_PROTECTION;
|
|
||||||
InitCryptoInfo(FCryptoInfo);
|
InitCryptoInfo(FCryptoInfo);
|
||||||
|
|
||||||
FOptions := [soShowGridLines, soShowHeaders];
|
FOptions := [soShowGridLines, soShowHeaders];
|
||||||
@ -1336,8 +1240,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
rtBoolean : WriteBoolValue(ACell, res.ResBoolean);
|
rtBoolean : WriteBoolValue(ACell, res.ResBoolean);
|
||||||
rtCell : begin
|
rtCell : begin
|
||||||
// cell := GetCell(res.ResRow, res.ResCol);
|
cell := (res.Worksheet as TsWorksheet).FindCell(res.ResRow, res.ResCol);
|
||||||
cell := res.Worksheet.FindCell(res.ResRow, res.ResCol);
|
|
||||||
if cell <> nil then
|
if cell <> nil then
|
||||||
case cell^.ContentType of
|
case cell^.ContentType of
|
||||||
cctNumber : WriteNumber(ACell, cell^.NumberValue);
|
cctNumber : WriteNumber(ACell, cell^.NumberValue);
|
||||||
@ -1603,14 +1506,6 @@ begin
|
|||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Checks whether the specified cell contains a hyperlink
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function TsWorksheet.HasHyperlink(ACell: PCell): Boolean;
|
|
||||||
begin
|
|
||||||
Result := (ACell <> nil) and (cfHyperlink in ACell^.Flags);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Reads the hyperlink information of a specified cell.
|
Reads the hyperlink information of a specified cell.
|
||||||
|
|
||||||
@ -4201,14 +4096,6 @@ begin
|
|||||||
FWorkbook.ChangedWorksheet(self);
|
FWorkbook.ChangedWorksheet(self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Returns whether the worksheet is protected
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function TsWorksheet.IsProtected: Boolean;
|
|
||||||
begin
|
|
||||||
Result := soProtected in FOptions;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Setter for the worksheet name property. Checks if the name is valid, and
|
Setter for the worksheet name property. Checks if the name is valid, and
|
||||||
@ -4221,9 +4108,11 @@ begin
|
|||||||
if (FWorkbook <> nil) then //and FWorkbook.ValidWorksheetName(AName) then
|
if (FWorkbook <> nil) then //and FWorkbook.ValidWorksheetName(AName) then
|
||||||
begin
|
begin
|
||||||
FName := AName;
|
FName := AName;
|
||||||
FWorkbook.FixFormulas(fcWorksheetRenamed, self, 0);
|
if FWorkbook.FReadWriteFlag = rwfNormal then begin
|
||||||
if (FWorkbook.FLockCount = 0) and Assigned(FWorkbook.FOnRenameWorksheet) then
|
FWorkbook.FixFormulas(fcWorksheetRenamed, self, 0);
|
||||||
FWorkbook.FOnRenameWorksheet(FWorkbook, self);
|
if (FWorkbook.FLockCount = 0) and Assigned(FWorkbook.FOnRenameWorksheet) then
|
||||||
|
FWorkbook.FOnRenameWorksheet(FWorkbook, self);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -8111,10 +8000,10 @@ begin
|
|||||||
InitFonts;
|
InitFonts;
|
||||||
|
|
||||||
// Clear error log
|
// Clear error log
|
||||||
FLog.Clear;
|
ClearErrorList;
|
||||||
|
|
||||||
// Abort if virtual mode is active without an event handler
|
// Abort if virtual mode is active without an event handler
|
||||||
if (boVirtualMode in FOptions) and not Assigned(FOnReadCellData) then
|
if (boVirtualMode in FOptions) and not Assigned(OnReadCellData) then
|
||||||
raise EFPSpreadsheet.Create('[TsWorkbook.PrepareBeforeReading] Event handler "OnReadCellData" required for virtual mode.');
|
raise EFPSpreadsheet.Create('[TsWorkbook.PrepareBeforeReading] Event handler "OnReadCellData" required for virtual mode.');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -8129,7 +8018,7 @@ var
|
|||||||
virtModeOK: Boolean;
|
virtModeOK: Boolean;
|
||||||
begin
|
begin
|
||||||
// Clear error log
|
// Clear error log
|
||||||
FLog.Clear;
|
ClearErrorList;
|
||||||
|
|
||||||
// Updates fist/last column/row index
|
// Updates fist/last column/row index
|
||||||
UpdateCaches;
|
UpdateCaches;
|
||||||
@ -8280,13 +8169,6 @@ var
|
|||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FWorksheets := TFPList.Create;
|
FWorksheets := TFPList.Create;
|
||||||
FLog := TStringList.Create;
|
|
||||||
FFormatID := sfidUnknown;
|
|
||||||
FUnits := suMillimeters; // Units for column width and row height
|
|
||||||
|
|
||||||
FormatSettings := UTF8FormatSettings;
|
|
||||||
// FormatSettings.ShortDateFormat := MakeShortDateFormat(FormatSettings.ShortDateFormat);
|
|
||||||
// FormatSettings.LongDateFormat := MakeLongDateFormat(FormatSettings.ShortDateFormat);
|
|
||||||
|
|
||||||
FFontList := TFPList.Create;
|
FFontList := TFPList.Create;
|
||||||
SetDefaultFont(DEFAULT_FONTNAME, DEFAULT_FONTSIZE);
|
SetDefaultFont(DEFAULT_FONTNAME, DEFAULT_FONTSIZE);
|
||||||
@ -8302,7 +8184,6 @@ begin
|
|||||||
|
|
||||||
// Protection
|
// Protection
|
||||||
InitCryptoInfo(FCryptoInfo);
|
InitCryptoInfo(FCryptoInfo);
|
||||||
FProtection := [];
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -8324,7 +8205,6 @@ begin
|
|||||||
RemoveAllEmbeddedObj;
|
RemoveAllEmbeddedObj;
|
||||||
FEmbeddedObjList.Free;
|
FEmbeddedObjList.Free;
|
||||||
|
|
||||||
FLog.Free;
|
|
||||||
FreeAndNil(FSearchEngine);
|
FreeAndNil(FSearchEngine);
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -8454,14 +8334,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Returns whether the workbook is protected
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function TsWorkbook.IsProtected: Boolean;
|
|
||||||
begin
|
|
||||||
Result := (FProtection <> []);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Reads the document from a file. It is assumed to have the given file format.
|
Reads the document from a file. It is assumed to have the given file format.
|
||||||
|
|
||||||
@ -9044,7 +8916,7 @@ end;
|
|||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Returns the index of a worksheet in the worksheet list
|
Returns the index of a worksheet in the worksheet list
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsWorkbook.GetWorksheetIndex(AWorksheet: TsWorksheet): Integer;
|
function TsWorkbook.GetWorksheetIndex(AWorksheet: TsBasicWorksheet): Integer;
|
||||||
begin
|
begin
|
||||||
Result := FWorksheets.IndexOf(AWorksheet);
|
Result := FWorksheets.IndexOf(AWorksheet);
|
||||||
end;
|
end;
|
||||||
@ -9609,7 +9481,7 @@ begin
|
|||||||
AddFont(AFontName, ASize, [], scBlack)
|
AddFont(AFontName, ASize, [], scBlack)
|
||||||
else
|
else
|
||||||
for i:=0 to FBuiltinFontCount-1 do
|
for i:=0 to FBuiltinFontCount-1 do
|
||||||
if (i <> 4) and (i < FFontList.Count) then
|
if (i <> 4) and (i < FFontList.Count) then // wp: why if font #4 relevant here ????
|
||||||
with TsFont(FFontList[i]) do
|
with TsFont(FFontList[i]) do
|
||||||
begin
|
begin
|
||||||
FontName := AFontName;
|
FontName := AFontName;
|
||||||
@ -9663,21 +9535,8 @@ end;
|
|||||||
@return String with font name, font size etc.
|
@return String with font name, font size etc.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsWorkbook.GetFontAsString(AIndex: Integer): String;
|
function TsWorkbook.GetFontAsString(AIndex: Integer): String;
|
||||||
var
|
|
||||||
fnt: TsFont;
|
|
||||||
begin
|
begin
|
||||||
fnt := GetFont(AIndex);
|
Result := fpsUtils.GetFontAsString(GetFont(AIndex));
|
||||||
if fnt <> nil then begin
|
|
||||||
Result := Format('%s; size %.1g; %s', [
|
|
||||||
fnt.FontName, fnt.Size, GetColorName(fnt.Color)]);
|
|
||||||
if (fssBold in fnt.Style) then Result := Result + '; bold';
|
|
||||||
if (fssItalic in fnt.Style) then Result := Result + '; italic';
|
|
||||||
if (fssUnderline in fnt.Style) then Result := Result + '; underline';
|
|
||||||
if (fssStrikeout in fnt.Style) then result := Result + '; strikeout';
|
|
||||||
if fnt.Position = fpSubscript then Result := Result + '; subscript';
|
|
||||||
if fnt.Position = fpSuperscript then Result := Result + '; superscript';
|
|
||||||
end else
|
|
||||||
Result := '';
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -10200,42 +10059,6 @@ begin
|
|||||||
FEmbeddedObjList.Clear;
|
FEmbeddedObjList.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Adds a (simple) error message to an internal list
|
|
||||||
|
|
||||||
@param AMsg Error text to be stored in the list
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
procedure TsWorkbook.AddErrorMsg(const AMsg: String);
|
|
||||||
begin
|
|
||||||
FLog.Add(AMsg);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Adds an error message composed by means of format codes to an internal list
|
|
||||||
|
|
||||||
@param AMsg Error text to be stored in the list
|
|
||||||
@param Args Array of arguments to be used by the Format() function
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
procedure TsWorkbook.AddErrorMsg(const AMsg: String; const Args: Array of const);
|
|
||||||
begin
|
|
||||||
FLog.Add(Format(AMsg, Args));
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Clears the internal error message list
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
procedure TsWorkbook.ClearErrorList;
|
|
||||||
begin
|
|
||||||
FLog.Clear;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Getter to retrieve the error messages collected during reading/writing
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function TsWorkbook.GetErrorMsg: String;
|
|
||||||
begin
|
|
||||||
Result := FLog.Text;
|
|
||||||
end;
|
|
||||||
(*
|
(*
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Converts a fpspreadsheet color into into a string RRGGBB.
|
Converts a fpspreadsheet color into into a string RRGGBB.
|
||||||
|
@ -23,7 +23,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, Sysutils,
|
Classes, Sysutils,
|
||||||
fpsTypes, fpsClasses, fpSpreadsheet;
|
fpsTypes, fpsClasses;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -31,16 +31,16 @@ type
|
|||||||
TsBasicSpreadReaderWriter = class
|
TsBasicSpreadReaderWriter = class
|
||||||
protected
|
protected
|
||||||
{@@ Instance of the workbook which is currently being read or written. }
|
{@@ Instance of the workbook which is currently being read or written. }
|
||||||
FWorkbook: TsWorkbook;
|
FWorkbook: TsBasicWorkbook;
|
||||||
{@@ Instance of the worksheet which is currently being read or written. }
|
{@@ Instance of the worksheet which is currently being read or written. }
|
||||||
FWorksheet: TsWorksheet;
|
FWorksheet: TsBasicWorksheet;
|
||||||
{@@ Limitations for the specific data file format }
|
{@@ Limitations for the specific data file format }
|
||||||
FLimitations: TsSpreadsheetFormatLimitations;
|
FLimitations: TsSpreadsheetFormatLimitations;
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); virtual; // to allow descendents to override it
|
constructor Create(AWorkbook: TsBasicWorkbook); virtual; // to allow descendents to override it
|
||||||
function Limitations: TsSpreadsheetFormatLimitations;
|
function Limitations: TsSpreadsheetFormatLimitations;
|
||||||
{@@ Instance of the workbook which is currently being read/written. }
|
{@@ Instance of the workbook which is currently being read/written. }
|
||||||
property Workbook: TsWorkbook read FWorkbook;
|
property Workbook: TsBasicWorkbook read FWorkbook;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TsBasicSpreadReader }
|
{ TsBasicSpreadReader }
|
||||||
@ -93,9 +93,9 @@ type
|
|||||||
{ Helper methods }
|
{ Helper methods }
|
||||||
procedure AddBuiltinNumFormats; virtual;
|
procedure AddBuiltinNumFormats; virtual;
|
||||||
{@@ Removes column records if all of them have the same column width }
|
{@@ Removes column records if all of them have the same column width }
|
||||||
procedure FixCols(AWorksheet: TsWorksheet);
|
procedure FixCols(AWorksheet: TsBasicWorksheet);
|
||||||
{@@ Removes row records if all of them have the same row height }
|
{@@ Removes row records if all of them have the same row height }
|
||||||
procedure FixRows(AWorksheet: TsWorksheet);
|
procedure FixRows(AWorksheet: TsBasicWorksheet);
|
||||||
|
|
||||||
{ Record reading methods }
|
{ Record reading methods }
|
||||||
{@@ Abstract method for reading a blank cell. Must be overridden by descendent classes. }
|
{@@ Abstract method for reading a blank cell. Must be overridden by descendent classes. }
|
||||||
@ -110,7 +110,7 @@ type
|
|||||||
procedure ReadNumber(AStream: TStream); virtual; abstract;
|
procedure ReadNumber(AStream: TStream); virtual; abstract;
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
{ General writing methods }
|
{ General writing methods }
|
||||||
@ -148,7 +148,7 @@ type
|
|||||||
function FindNumFormatInList(ANumFormatStr: String): Integer;
|
function FindNumFormatInList(ANumFormatStr: String): Integer;
|
||||||
// function FixColor(AColor: TsColor): TsColor; virtual;
|
// function FixColor(AColor: TsColor): TsColor; virtual;
|
||||||
procedure FixFormat(ACell: PCell); virtual;
|
procedure FixFormat(ACell: PCell); virtual;
|
||||||
procedure GetSheetDimensions(AWorksheet: TsWorksheet;
|
procedure GetSheetDimensions(AWorksheet: TsBasicWorksheet;
|
||||||
out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal); virtual;
|
out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal); virtual;
|
||||||
procedure ListAllNumFormats; virtual;
|
procedure ListAllNumFormats; virtual;
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ type
|
|||||||
const AValue: double; ACell: PCell); virtual; abstract;
|
const AValue: double; ACell: PCell); virtual; abstract;
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
{ General writing methods }
|
{ General writing methods }
|
||||||
@ -219,7 +219,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Math, LazUTF8,
|
Math, LazUTF8,
|
||||||
fpsStrings, fpsUtils, fpsNumFormat, fpsStreams;
|
fpsStrings, fpsUtils, fpsNumFormat, fpsStreams, fpspreadsheet;
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
@ -234,7 +234,7 @@ uses
|
|||||||
file is written. This parameter is passed from the workbook
|
file is written. This parameter is passed from the workbook
|
||||||
which creates the reader/writer.
|
which creates the reader/writer.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
constructor TsBasicSpreadReaderWriter.Create(AWorkbook: TsWorkbook);
|
constructor TsBasicSpreadReaderWriter.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FWorkbook := AWorkbook;
|
FWorkbook := AWorkbook;
|
||||||
@ -264,24 +264,27 @@ end;
|
|||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsBasicSpreadWriter.CheckLimitations;
|
procedure TsBasicSpreadWriter.CheckLimitations;
|
||||||
var
|
var
|
||||||
|
workbook: TsWorkbook;
|
||||||
lastCol, lastRow: Cardinal;
|
lastCol, lastRow: Cardinal;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
Workbook.GetLastRowColIndex(lastRow, lastCol);
|
workbook := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
|
workbook.GetLastRowColIndex(lastRow, lastCol);
|
||||||
|
|
||||||
// Check row count
|
// Check row count
|
||||||
if lastRow >= FLimitations.MaxRowCount then
|
if lastRow >= FLimitations.MaxRowCount then
|
||||||
Workbook.AddErrorMsg(rsMaxRowsExceeded, [lastRow+1, FLimitations.MaxRowCount]);
|
workbook.AddErrorMsg(rsMaxRowsExceeded, [lastRow+1, FLimitations.MaxRowCount]);
|
||||||
|
|
||||||
// Check column count
|
// Check column count
|
||||||
if lastCol >= FLimitations.MaxColCount then
|
if lastCol >= FLimitations.MaxColCount then
|
||||||
Workbook.AddErrorMsg(rsMaxColsExceeded, [lastCol+1, FLimitations.MaxColCount]);
|
workbook.AddErrorMsg(rsMaxColsExceeded, [lastCol+1, FLimitations.MaxColCount]);
|
||||||
|
|
||||||
// Check worksheet names
|
// Check worksheet names
|
||||||
for i:=0 to Workbook.GetWorksheetCount-1 do
|
for i:=0 to workbook.GetWorksheetCount-1 do
|
||||||
begin
|
begin
|
||||||
sheet := Workbook.GetWorksheetByIndex(i);
|
sheet := workbook.GetWorksheetByIndex(i);
|
||||||
if UTF8Length(sheet.Name) > FLimitations.MaxSheetNameLength then
|
if UTF8Length(sheet.Name) > FLimitations.MaxSheetNameLength then
|
||||||
// Worksheet name is too long.
|
// Worksheet name is too long.
|
||||||
// We abort saving here because it is not safe to chop the sheet name
|
// We abort saving here because it is not safe to chop the sheet name
|
||||||
@ -306,7 +309,7 @@ end;
|
|||||||
This parameter is passed from the workbook which creates
|
This parameter is passed from the workbook which creates
|
||||||
the reader.
|
the reader.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
constructor TsCustomSpreadReader.Create(AWorkbook: TsWorkbook);
|
constructor TsCustomSpreadReader.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
// Font list
|
// Font list
|
||||||
@ -316,7 +319,7 @@ begin
|
|||||||
AddBuiltinNumFormats;
|
AddBuiltinNumFormats;
|
||||||
// Virtual mode
|
// Virtual mode
|
||||||
FIsVirtualMode := (boVirtualMode in FWorkbook.Options) and
|
FIsVirtualMode := (boVirtualMode in FWorkbook.Options) and
|
||||||
Assigned(FWorkbook.OnReadCellData);
|
Assigned((FWorkbook as TsWorkbook).OnReadCellData);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -353,10 +356,11 @@ end;
|
|||||||
|
|
||||||
@param AWorksheet The columns in this worksheet are processed.
|
@param AWorksheet The columns in this worksheet are processed.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsCustomSpreadReader.FixCols(AWorkSheet: TsWorksheet);
|
procedure TsCustomSpreadReader.FixCols(AWorkSheet: TsBasicWorksheet);
|
||||||
const
|
const
|
||||||
EPS = 1E-3;
|
EPS = 1E-3;
|
||||||
var
|
var
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
c: LongInt;
|
c: LongInt;
|
||||||
w: Single;
|
w: Single;
|
||||||
lCol: PCol;
|
lCol: PCol;
|
||||||
@ -365,30 +369,30 @@ begin
|
|||||||
// If the count of columns is equal to the max colcount of the file format
|
// If the count of columns is equal to the max colcount of the file format
|
||||||
// then it is likely that dummy columns have been added -> delete all empty
|
// then it is likely that dummy columns have been added -> delete all empty
|
||||||
// columns (starting at the right) until the first non-empty column is found
|
// columns (starting at the right) until the first non-empty column is found
|
||||||
if AWorksheet.Cols.Count = SizeInt(FLimitations.MaxColCount) then
|
if sheet.Cols.Count = SizeInt(FLimitations.MaxColCount) then
|
||||||
begin
|
begin
|
||||||
c := AWorksheet.Cols.Count - 1;
|
c := sheet.Cols.Count - 1;
|
||||||
lCol := PCol(AWorksheet.Cols[c]);
|
lCol := PCol(sheet.Cols[c]);
|
||||||
w := lCol.Width;
|
w := lCol.Width;
|
||||||
while c >= 0 do begin
|
while c >= 0 do begin
|
||||||
lCol := PCol(AWorksheet.Cols[c]);
|
lCol := PCol(sheet.Cols[c]);
|
||||||
if not SameValue(lCol^.Width, w, EPS) then
|
if not SameValue(lCol^.Width, w, EPS) then
|
||||||
break;
|
break;
|
||||||
if AWorksheet.FindNextCellInCol(0, c) <> nil then
|
if sheet.FindNextCellInCol(0, c) <> nil then
|
||||||
break;
|
break;
|
||||||
AWorksheet.RemoveCol(c);
|
sheet.RemoveCol(c);
|
||||||
dec(c);
|
dec(c);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if AWorksheet.Cols.Count < 2 then
|
if sheet.Cols.Count < 2 then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
// Check whether all columns have the same column width
|
// Check whether all columns have the same column width
|
||||||
sameWidth := true;
|
sameWidth := true;
|
||||||
w := PCol(AWorksheet.Cols[0])^.Width;
|
w := PCol(sheet.Cols[0])^.Width;
|
||||||
for c := 1 to AWorksheet.Cols.Count-1 do begin
|
for c := 1 to sheet.Cols.Count-1 do begin
|
||||||
lCol := PCol(AWorksheet.Cols[c]);
|
lCol := PCol(sheet.Cols[c]);
|
||||||
if not SameValue(lCol^.Width, w, EPS) then
|
if not SameValue(lCol^.Width, w, EPS) then
|
||||||
begin
|
begin
|
||||||
sameWidth := false;
|
sameWidth := false;
|
||||||
@ -399,12 +403,12 @@ begin
|
|||||||
if sameWidth then begin
|
if sameWidth then begin
|
||||||
// At this point we know that all columns have the same width. We pass this
|
// At this point we know that all columns have the same width. We pass this
|
||||||
// to the DefaultColWidth ...
|
// to the DefaultColWidth ...
|
||||||
AWorksheet.WriteDefaultColWidth(w, FWorkbook.Units);
|
sheet.WriteDefaultColWidth(w, FWorkbook.Units);
|
||||||
|
|
||||||
// ...and delete all column records with non-default format
|
// ...and delete all column records with non-default format
|
||||||
for c := AWorksheet.Cols.Count-1 downto 0 do begin
|
for c := sheet.Cols.Count-1 downto 0 do begin
|
||||||
lCol := PCol(AWorksheet.Cols[c]);
|
lCol := PCol(sheet.Cols[c]);
|
||||||
if lCol^.FormatIndex = 0 then AWorksheet.RemoveCol(c);
|
if lCol^.FormatIndex = 0 then sheet.RemoveCol(c);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -414,21 +418,22 @@ end;
|
|||||||
row records if they do. Such unnecessary row records are often written
|
row records if they do. Such unnecessary row records are often written
|
||||||
when an Office application converts a file to another format.
|
when an Office application converts a file to another format.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsCustomSpreadReader.FixRows(AWorkSheet: TsWorksheet);
|
procedure TsCustomSpreadReader.FixRows(AWorkSheet: TsBasicWorksheet);
|
||||||
const
|
const
|
||||||
EPS = 1E-3;
|
EPS = 1E-3;
|
||||||
var
|
var
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
r, rLast: Cardinal;
|
r, rLast: Cardinal;
|
||||||
h: Single;
|
h: Single;
|
||||||
lRow: PRow;
|
lRow: PRow;
|
||||||
begin
|
begin
|
||||||
if AWorksheet.Rows.Count <= 1 then
|
if sheet.Rows.Count <= 1 then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
// Check whether all rows have the same height
|
// Check whether all rows have the same height
|
||||||
h := PRow(AWorksheet.Rows[0])^.Height;
|
h := PRow(sheet.Rows[0])^.Height;
|
||||||
for r := 1 to AWorksheet.Rows.Count-1 do begin
|
for r := 1 to sheet.Rows.Count-1 do begin
|
||||||
lRow := PRow(AWorksheet.Rows[r]);
|
lRow := PRow(sheet.Rows[r]);
|
||||||
if not SameValue(lRow^.Height, h, EPS) then
|
if not SameValue(lRow^.Height, h, EPS) then
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
@ -436,21 +441,21 @@ begin
|
|||||||
// If there are more rows than row records and the common row height is not
|
// If there are more rows than row records and the common row height is not
|
||||||
// the default row height (i.e. the row height of the non-record rows) then
|
// the default row height (i.e. the row height of the non-record rows) then
|
||||||
// the row heights are different
|
// the row heights are different
|
||||||
rLast := AWorksheet.GetLastRowIndex;
|
rLast := sheet.GetLastRowIndex;
|
||||||
if (AWorksheet.Rows.Count > 0) and
|
if (sheet.Rows.Count > 0) and
|
||||||
(rLast <> PRow(AWorksheet.Rows[AWorksheet.Rows.Count-1]).Row) and
|
(rLast <> PRow(sheet.Rows[sheet.Rows.Count-1]).Row) and
|
||||||
not SameValue(h, AWorksheet.ReadDefaultRowHeight(FWorkbook.Units), EPS)
|
not SameValue(h, sheet.ReadDefaultRowHeight(FWorkbook.Units), EPS)
|
||||||
then
|
then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
// At this point we know that all rows have the same height. We pass this
|
// At this point we know that all rows have the same height. We pass this
|
||||||
// to the DefaultRowHeight ...
|
// to the DefaultRowHeight ...
|
||||||
AWorksheet.WriteDefaultRowHeight(h, FWorkbook.Units);
|
sheet.WriteDefaultRowHeight(h, FWorkbook.Units);
|
||||||
|
|
||||||
// ... and delete all row records with default format.
|
// ... and delete all row records with default format.
|
||||||
for r := AWorksheet.Rows.Count-1 downto 0 do begin
|
for r := sheet.Rows.Count-1 downto 0 do begin
|
||||||
lRow := PRow(AWorksheet.Rows[r]);
|
lRow := PRow(sheet.Rows[r]);
|
||||||
if lRow^.FormatIndex = 0 then AWorksheet.RemoveRow(r);
|
if lRow^.FormatIndex = 0 then sheet.RemoveRow(r);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -549,7 +554,7 @@ end;
|
|||||||
@param AWorkbook Workbook from with the file is written. This parameter is
|
@param AWorkbook Workbook from with the file is written. This parameter is
|
||||||
passed from the workbook which creates the writer.
|
passed from the workbook which creates the writer.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
constructor TsCustomSpreadWriter.Create(AWorkbook: TsWorkbook);
|
constructor TsCustomSpreadWriter.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
// Number formats
|
// Number formats
|
||||||
@ -616,26 +621,32 @@ end;
|
|||||||
@param AFirstCol Index of first column to be written
|
@param AFirstCol Index of first column to be written
|
||||||
@param ALastCol Index of last column to be written
|
@param ALastCol Index of last column to be written
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsCustomSpreadWriter.GetSheetDimensions(AWorksheet: TsWorksheet;
|
procedure TsCustomSpreadWriter.GetSheetDimensions(AWorksheet: TsBasicWorksheet;
|
||||||
out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal);
|
out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal);
|
||||||
|
var
|
||||||
|
book: TsWorkbook;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
if (boVirtualMode in AWorksheet.Workbook.Options) then
|
book := FWorkbook as TsWorkbook;
|
||||||
|
sheet := AWorksheet as TsWorksheet;
|
||||||
|
|
||||||
|
if (boVirtualMode in sheet.Workbook.Options) then
|
||||||
begin
|
begin
|
||||||
AFirstRow := 0;
|
AFirstRow := 0;
|
||||||
AFirstCol := 0;
|
AFirstCol := 0;
|
||||||
ALastRow := LongInt(AWorksheet.VirtualRowCount)-1;
|
ALastRow := LongInt(sheet.VirtualRowCount)-1;
|
||||||
ALastCol := LongInt(AWorksheet.VirtualColCount)-1;
|
ALastCol := LongInt(sheet.VirtualColCount)-1;
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
Workbook.UpdateCaches;
|
book.UpdateCaches;
|
||||||
AFirstRow := AWorksheet.GetFirstRowIndex;
|
AFirstRow := sheet.GetFirstRowIndex;
|
||||||
if AFirstRow = Cardinal(-1) then
|
if AFirstRow = Cardinal(-1) then
|
||||||
AFirstRow := 0; // this happens if the sheet is empty and does not contain row records
|
AFirstRow := 0; // this happens if the sheet is empty and does not contain row records
|
||||||
AFirstCol := AWorksheet.GetFirstColIndex;
|
AFirstCol := sheet.GetFirstColIndex;
|
||||||
if AFirstCol = Cardinal(-1) then
|
if AFirstCol = Cardinal(-1) then
|
||||||
AFirstCol := 0; // this happens if the sheet is empty and does not contain col records
|
AFirstCol := 0; // this happens if the sheet is empty and does not contain col records
|
||||||
ALastRow := AWorksheet.GetLastRowIndex;
|
ALastRow := sheet.GetLastRowIndex;
|
||||||
ALastCol := AWorksheet.GetLastColIndex;
|
ALastCol := sheet.GetLastColIndex;
|
||||||
end;
|
end;
|
||||||
if AFirstCol >= Limitations.MaxColCount then
|
if AFirstCol >= Limitations.MaxColCount then
|
||||||
AFirstCol := Limitations.MaxColCount-1;
|
AFirstCol := Limitations.MaxColCount-1;
|
||||||
@ -657,9 +668,9 @@ var
|
|||||||
numFmt: TsNumFormatParams;
|
numFmt: TsNumFormatParams;
|
||||||
numFmtStr: String;
|
numFmtStr: String;
|
||||||
begin
|
begin
|
||||||
for i:=0 to Workbook.GetNumberFormatCount - 1 do
|
for i:=0 to TsWorkbook(Workbook).GetNumberFormatCount - 1 do
|
||||||
begin
|
begin
|
||||||
numFmt := Workbook.GetNumberFormat(i);
|
numFmt := TsWorkbook(Workbook).GetNumberFormat(i);
|
||||||
if numFmt <> nil then
|
if numFmt <> nil then
|
||||||
begin
|
begin
|
||||||
numFmtStr := numFmt.NumFormatStr;
|
numFmtStr := numFmt.NumFormatStr;
|
||||||
@ -699,7 +710,7 @@ begin
|
|||||||
WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue, ACell);
|
WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue, ACell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FWorksheet.ReadComment(ACell) <> '' then
|
if TsWorksheet(FWorksheet).ReadComment(ACell) <> '' then
|
||||||
WriteComment(AStream, ACell);
|
WriteComment(AStream, ACell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -23,6 +23,10 @@ type
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
type
|
type
|
||||||
|
{ Forward declarations }
|
||||||
|
TsBasicWorksheet = class;
|
||||||
|
TsBasicWorkbook = class;
|
||||||
|
|
||||||
{@@ Built-in file formats of fpspreadsheet }
|
{@@ Built-in file formats of fpspreadsheet }
|
||||||
TsSpreadsheetFormat = (sfExcel2, sfExcel5, sfExcel8, sfExcelXML, sfOOXML,
|
TsSpreadsheetFormat = (sfExcel2, sfExcel5, sfExcel8, sfExcelXML, sfOOXML,
|
||||||
sfOpenDocument, sfCSV, sfHTML, sfWikiTable_Pipes, sfWikiTable_WikiMedia,
|
sfOpenDocument, sfCSV, sfHTML, sfWikiTable_Pipes, sfWikiTable_WikiMedia,
|
||||||
@ -732,7 +736,7 @@ type
|
|||||||
{ Location of the cell }
|
{ Location of the cell }
|
||||||
Row: Cardinal; // zero-based
|
Row: Cardinal; // zero-based
|
||||||
Col: Cardinal; // zero-based
|
Col: Cardinal; // zero-based
|
||||||
Worksheet: Pointer; // Must be cast to TsWorksheet when used (avoids circular unit reference)
|
Worksheet: TsBasicWorksheet; // Must be cast to TsWorksheet when used (avoids circular unit reference)
|
||||||
{ Status flags }
|
{ Status flags }
|
||||||
Flags: TsCellFlags;
|
Flags: TsCellFlags;
|
||||||
{ Index of format record in the workbook's CellFormatList }
|
{ Index of format record in the workbook's CellFormatList }
|
||||||
@ -874,6 +878,124 @@ type
|
|||||||
TsStreamParam = (spClipboard, spWindowsClipboardHTML);
|
TsStreamParam = (spClipboard, spWindowsClipboardHTML);
|
||||||
TsStreamParams = set of TsStreamParam;
|
TsStreamParams = set of TsStreamParam;
|
||||||
|
|
||||||
|
{@@ Worksheet user interface options:
|
||||||
|
@param soShowGridLines Show or hide the grid lines in the spreadsheet
|
||||||
|
@param soShowHeaders Show or hide the column or row headers of the
|
||||||
|
spreadsheet
|
||||||
|
@param soHasFrozenPanes If set a number of rows and columns of the
|
||||||
|
spreadsheet is fixed and does not scroll. The number
|
||||||
|
is defined by LeftPaneWidth and TopPaneHeight.
|
||||||
|
@param soHidden Worksheet is hidden.
|
||||||
|
@param soProtected Worksheet is protected
|
||||||
|
@param soPanesProtection Panes are locked due to workbook protection }
|
||||||
|
TsSheetOption = (soShowGridLines, soShowHeaders, soHasFrozenPanes, soHidden,
|
||||||
|
soProtected, soPanesProtection);
|
||||||
|
|
||||||
|
{@@ Set of user interface options
|
||||||
|
@ see TsSheetOption }
|
||||||
|
TsSheetOptions = set of TsSheetOption;
|
||||||
|
|
||||||
|
{@@ Option flags for the workbook
|
||||||
|
@param boVirtualMode If in virtual mode date are not taken from cells
|
||||||
|
when a spreadsheet is written to file, but are
|
||||||
|
provided by means of the event OnWriteCellData.
|
||||||
|
Similarly, when data are read they are not added
|
||||||
|
as cells but passed the the event OnReadCellData;
|
||||||
|
@param boBufStream When this option is set a buffered stream is used
|
||||||
|
for writing (a memory stream swapping to disk) or
|
||||||
|
reading (a file stream pre-reading chunks of data
|
||||||
|
to memory)
|
||||||
|
@param boFileStream Uses file streams and temporary files during
|
||||||
|
reading and writing. Lowest memory consumptions,
|
||||||
|
but slow.
|
||||||
|
@param boAutoCalc Automatically recalculate formulas whenever a
|
||||||
|
cell value changes.
|
||||||
|
@param boCalcBeforeSaving Calculates formulas before saving the file.
|
||||||
|
Otherwise there are no results when the file is
|
||||||
|
loaded back by fpspreadsheet.
|
||||||
|
@param boReadFormulas Allows to turn off reading of rpn formulas; this
|
||||||
|
is a precaution since formulas not correctly
|
||||||
|
implemented by fpspreadsheet could crash the
|
||||||
|
reading operation.
|
||||||
|
@param boWriteZoomfactor Instructs the writer to write the current zoom
|
||||||
|
factors of the worksheets to file.
|
||||||
|
@param boAbortReadOnFormulaError Aborts reading if a formula error is
|
||||||
|
encountered
|
||||||
|
@param boIgnoreFormulas Formulas are not checked and not calculated.
|
||||||
|
Cannot be used for biff formats. }
|
||||||
|
TsWorkbookOption = (boVirtualMode, boBufStream, boFileStream,
|
||||||
|
boAutoCalc, boCalcBeforeSaving, boReadFormulas, boWriteZoomFactor,
|
||||||
|
boAbortReadOnFormulaError, boIgnoreFormulas);
|
||||||
|
|
||||||
|
{@@ Set of option flags for the workbook }
|
||||||
|
TsWorkbookOptions = set of TsWorkbookOption;
|
||||||
|
|
||||||
|
{@@ Basic worksheet class to avoid circular unit references. It has only those
|
||||||
|
properties and methods which do not require any other unit than fpstypes. }
|
||||||
|
TsBasicWorksheet = class
|
||||||
|
protected
|
||||||
|
FName: String; // Name of the worksheet (displayed at the tab)
|
||||||
|
FOptions: TsSheetOptions;
|
||||||
|
FProtection: TsWorksheetProtections;
|
||||||
|
procedure SetName(const AName: String); virtual; abstract;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
function HasHyperlink(ACell: PCell): Boolean;
|
||||||
|
function IsProtected: Boolean;
|
||||||
|
{@@ Name of the sheet. In the popular spreadsheet applications this is
|
||||||
|
displayed in the tab of the sheet. }
|
||||||
|
property Name: string read FName write SetName;
|
||||||
|
{@@ Parameters controlling visibility of grid lines and row/column headers,
|
||||||
|
usage of frozen panes etc. }
|
||||||
|
property Options: TsSheetOptions read FOptions write FOptions;
|
||||||
|
{@@ Worksheet protection options }
|
||||||
|
property Protection: TsWorksheetProtections read FProtection write FProtection;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ Basic worksheet class to avoid circular unit references. It contains only
|
||||||
|
those properties and methods which do not require any other unit than
|
||||||
|
fpstypes. }
|
||||||
|
TsBasicWorkbook = class
|
||||||
|
private
|
||||||
|
FLog: TStringList;
|
||||||
|
function GetErrorMsg: String;
|
||||||
|
protected
|
||||||
|
FFileName: String;
|
||||||
|
FFormatID: TsSpreadFormatID;
|
||||||
|
FOptions: TsWorkbookOptions;
|
||||||
|
FProtection: TsWorkbookProtections;
|
||||||
|
FUnits: TsSizeUnits;
|
||||||
|
public
|
||||||
|
{@@ A copy of SysUtil's DefaultFormatSettings (converted to UTF8) to provide
|
||||||
|
some kind of localization to some formatting strings.
|
||||||
|
Can be modified before loading/writing files }
|
||||||
|
FormatSettings: TFormatSettings;
|
||||||
|
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
{ Error messages }
|
||||||
|
procedure AddErrorMsg(const AMsg: String); overload;
|
||||||
|
procedure AddErrorMsg(const AMsg: String; const Args: array of const); overload;
|
||||||
|
procedure ClearErrorList; inline;
|
||||||
|
|
||||||
|
{ Protection }
|
||||||
|
function IsProtected: Boolean;
|
||||||
|
|
||||||
|
{@@ Retrieves error messages collected during reading/writing }
|
||||||
|
property ErrorMsg: String read GetErrorMsg;
|
||||||
|
{@@ Identifies the file format which was detected when reading the file }
|
||||||
|
property FileFormatID: TsSpreadFormatID read FFormatID;
|
||||||
|
{@@ Filename of the saved workbook }
|
||||||
|
property FileName: String read FFileName;
|
||||||
|
{@@ Option flags for the workbook - see boXXXX declarations }
|
||||||
|
property Options: TsWorkbookOptions read FOptions write FOptions;
|
||||||
|
{@@ Workbook protection flags }
|
||||||
|
property Protection: TsWorkbookProtections read FProtection write FProtection;
|
||||||
|
{@@ Units of row heights and column widths }
|
||||||
|
property Units: TsSizeUnits read FUnits;
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ Exception types for fpspreadsheet }
|
{@@ Exception types for fpspreadsheet }
|
||||||
EFpSpreadsheet = class(Exception);
|
EFpSpreadsheet = class(Exception);
|
||||||
EFpSpreadsheetReader = class(EFpSpreadsheet);
|
EFpSpreadsheetReader = class(EFpSpreadsheet);
|
||||||
@ -892,6 +1014,10 @@ const
|
|||||||
HEADER_FOOTER_INDEX_EVEN = 2;
|
HEADER_FOOTER_INDEX_EVEN = 2;
|
||||||
HEADER_FOOTER_INDEX_ALL = 1;
|
HEADER_FOOTER_INDEX_ALL = 1;
|
||||||
|
|
||||||
|
var
|
||||||
|
{@@ FPC format settings for which all strings have been converted to UTF8 }
|
||||||
|
UTF8FormatSettings: TFormatSettings;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -914,5 +1040,125 @@ begin
|
|||||||
Position := AFont.Position;
|
Position := AFont.Position;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{-------------------------------------------------------------------------------
|
||||||
|
sBasicWorksheet
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
|
||||||
|
constructor TsBasicWorksheet.Create;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
FProtection := DEFAULT_SHEET_PROTECTION;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Checks whether the specified cell contains a hyperlink
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsBasicWorksheet.HasHyperlink(ACell: PCell): Boolean;
|
||||||
|
begin
|
||||||
|
Result := (ACell <> nil) and (cfHyperlink in ACell^.Flags);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Returns whether the worksheet is protected
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsBasicWorksheet.IsProtected: Boolean;
|
||||||
|
begin
|
||||||
|
Result := soProtected in FOptions;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{-------------------------------------------------------------------------------
|
||||||
|
TsBasicWorkbook
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
constructor TsBasicWorkbook.Create;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
FormatSettings := UTF8FormatSettings;
|
||||||
|
FUnits := suMillimeters; // Units for column width and row height
|
||||||
|
FFormatID := sfidUnknown;
|
||||||
|
FLog := TStringList.Create;
|
||||||
|
FProtection := [];
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TsBasicWorkbook.Destroy;
|
||||||
|
begin
|
||||||
|
FLog.Free;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Adds a (simple) error message to an internal list
|
||||||
|
|
||||||
|
@param AMsg Error text to be stored in the list
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsBasicWorkbook.AddErrorMsg(const AMsg: String);
|
||||||
|
begin
|
||||||
|
FLog.Add(AMsg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Adds an error message composed by means of format codes to an internal list
|
||||||
|
|
||||||
|
@param AMsg Error text to be stored in the list
|
||||||
|
@param Args Array of arguments to be used by the Format() function
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsBasicWorkbook.AddErrorMsg(const AMsg: String;
|
||||||
|
const Args: Array of const);
|
||||||
|
begin
|
||||||
|
FLog.Add(Format(AMsg, Args));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Clears the internal error message list
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsBasicWorkbook.ClearErrorList;
|
||||||
|
begin
|
||||||
|
FLog.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Getter to retrieve the error messages collected during reading/writing
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsBasicWorkbook.GetErrorMsg: String;
|
||||||
|
begin
|
||||||
|
Result := FLog.Text;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Returns whether the workbook is protected
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsBasicWorkbook.IsProtected: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (FProtection <> []);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Creates a FPC format settings record in which all strings are encoded as
|
||||||
|
UTF8.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure InitUTF8FormatSettings;
|
||||||
|
// remove when available in LazUtils
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
UTF8FormatSettings := DefaultFormatSettings;
|
||||||
|
UTF8FormatSettings.CurrencyString := AnsiToUTF8(DefaultFormatSettings.CurrencyString);
|
||||||
|
for i:=1 to 12 do begin
|
||||||
|
UTF8FormatSettings.LongMonthNames[i] := AnsiToUTF8(DefaultFormatSettings.LongMonthNames[i]);
|
||||||
|
UTF8FormatSettings.ShortMonthNames[i] := AnsiToUTF8(DefaultFormatSettings.ShortMonthNames[i]);
|
||||||
|
end;
|
||||||
|
for i:=1 to 7 do begin
|
||||||
|
UTF8FormatSettings.LongDayNames[i] := AnsiToUTF8(DefaultFormatSettings.LongDayNames[i]);
|
||||||
|
UTF8FormatSettings.ShortDayNames[i] := AnsiToUTF8(DefaultFormatSettings.ShortDayNames[i]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
initialization
|
||||||
|
InitUTF8FormatSettings;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ unit fpsutils;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, TypInfo, //StrUtils,
|
Classes, SysUtils, TypInfo,
|
||||||
fpstypes;
|
fpstypes;
|
||||||
|
|
||||||
// Exported types
|
// Exported types
|
||||||
@ -194,7 +194,8 @@ procedure SplitHyperlink(AValue: String; out ATarget, ABookmark: String);
|
|||||||
procedure FixHyperlinkPathDelims(var ATarget: String);
|
procedure FixHyperlinkPathDelims(var ATarget: String);
|
||||||
|
|
||||||
procedure InitCell(out ACell: TCell); overload;
|
procedure InitCell(out ACell: TCell); overload;
|
||||||
procedure InitCell(AWorksheet: Pointer; ARow, ACol: Cardinal; out ACell: TCell); overload;
|
procedure InitCell(AWorksheet: TsBasicWorksheet; ARow, ACol: Cardinal;
|
||||||
|
out ACell: TCell); overload;
|
||||||
procedure InitCryptoInfo(out AValue: TsCryptoInfo);
|
procedure InitCryptoInfo(out AValue: TsCryptoInfo);
|
||||||
procedure InitFormatRecord(out AValue: TsCellFormat);
|
procedure InitFormatRecord(out AValue: TsCellFormat);
|
||||||
procedure InitImageRecord(out AValue: TsImage; ARow, ACol: Cardinal;
|
procedure InitImageRecord(out AValue: TsImage; ARow, ACol: Cardinal;
|
||||||
@ -210,6 +211,8 @@ function SameFont(AFont: TsFont; AFontName: String; AFontSize: Single;
|
|||||||
|
|
||||||
function Range(ARow1, ACol1, ARow2, ACol2: Cardinal): TsCellRange;
|
function Range(ARow1, ACol1, ARow2, ACol2: Cardinal): TsCellRange;
|
||||||
|
|
||||||
|
function GetFontAsString(AFont: TsFont): String;
|
||||||
|
|
||||||
//function GetUniqueTempDir(Global: Boolean): String;
|
//function GetUniqueTempDir(Global: Boolean): String;
|
||||||
|
|
||||||
procedure AppendToStream(AStream: TStream; const AString: String); inline; overload;
|
procedure AppendToStream(AStream: TStream; const AString: String); inline; overload;
|
||||||
@ -226,9 +229,6 @@ var
|
|||||||
for conversion of distances to pixels}
|
for conversion of distances to pixels}
|
||||||
ScreenPixelsPerInch: Integer = 96;
|
ScreenPixelsPerInch: Integer = 96;
|
||||||
|
|
||||||
{@@ FPC format settings for which all strings have been converted to UTF8 }
|
|
||||||
UTF8FormatSettings: TFormatSettings;
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -2348,7 +2348,8 @@ end;
|
|||||||
@param ACol Column index of the new cell
|
@param ACol Column index of the new cell
|
||||||
@return New cell record with row and column fields preset to passed values.
|
@return New cell record with row and column fields preset to passed values.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure InitCell(AWorksheet: Pointer; ARow, ACol: Cardinal; out ACell: TCell);
|
procedure InitCell(AWorksheet: TsbasicWorksheet;
|
||||||
|
ARow, ACol: Cardinal; out ACell: TCell);
|
||||||
begin
|
begin
|
||||||
InitCell(ACell);
|
InitCell(ACell);
|
||||||
ACell.Worksheet := AWorksheet;
|
ACell.Worksheet := AWorksheet;
|
||||||
@ -2552,6 +2553,26 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Combines the relevant font properties into a string
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function GetFontAsString(AFont: TsFont): String;
|
||||||
|
begin
|
||||||
|
if AFont = nil then
|
||||||
|
Result := ''
|
||||||
|
else begin
|
||||||
|
Result := Format('%s; size %.1g; %s', [
|
||||||
|
AFont.FontName, AFont.Size, GetColorName(AFont.Color)]);
|
||||||
|
if (fssBold in AFont.Style) then Result := Result + '; bold';
|
||||||
|
if (fssItalic in AFont.Style) then Result := Result + '; italic';
|
||||||
|
if (fssUnderline in AFont.Style) then Result := Result + '; underline';
|
||||||
|
if (fssStrikeout in AFont.Style) then result := Result + '; strikeout';
|
||||||
|
if AFont.Position = fpSubscript then Result := Result + '; subscript';
|
||||||
|
if AFont.Position = fpSuperscript then Result := Result + '; superscript';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
(*
|
(*
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Constructs a string of length "Len" containing random uppercase characters
|
Constructs a string of length "Len" containing random uppercase characters
|
||||||
@ -2838,30 +2859,5 @@ end;
|
|||||||
{$POP}
|
{$POP}
|
||||||
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Creates a FPC format settings record in which all strings are encoded as
|
|
||||||
UTF8.
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
procedure InitUTF8FormatSettings;
|
|
||||||
// remove when available in LazUtils
|
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
|
||||||
UTF8FormatSettings := DefaultFormatSettings;
|
|
||||||
UTF8FormatSettings.CurrencyString := AnsiToUTF8(DefaultFormatSettings.CurrencyString);
|
|
||||||
for i:=1 to 12 do begin
|
|
||||||
UTF8FormatSettings.LongMonthNames[i] := AnsiToUTF8(DefaultFormatSettings.LongMonthNames[i]);
|
|
||||||
UTF8FormatSettings.ShortMonthNames[i] := AnsiToUTF8(DefaultFormatSettings.ShortMonthNames[i]);
|
|
||||||
end;
|
|
||||||
for i:=1 to 7 do begin
|
|
||||||
UTF8FormatSettings.LongDayNames[i] := AnsiToUTF8(DefaultFormatSettings.LongDayNames[i]);
|
|
||||||
UTF8FormatSettings.ShortDayNames[i] := AnsiToUTF8(DefaultFormatSettings.ShortDayNames[i]);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
initialization
|
|
||||||
InitUTF8FormatSettings;
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ uses
|
|||||||
{$ELSE}
|
{$ELSE}
|
||||||
fpszipper,
|
fpszipper,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
fpSpreadsheet, fpsreaderwriter;
|
fpstypes, fpsreaderwriter;
|
||||||
|
|
||||||
type
|
type
|
||||||
TsSpreadXMLReader = class(TsCustomSpreadReader)
|
TsSpreadXMLReader = class(TsCustomSpreadReader)
|
||||||
@ -53,7 +53,8 @@ procedure UnzipFile(AZipFileName, AZippedFile, ADestFolder: String);
|
|||||||
function UnzipToStream(AZipStream: TStream; const AZippedFile: String;
|
function UnzipToStream(AZipStream: TStream; const AZippedFile: String;
|
||||||
ADestStream: TStream): Boolean;
|
ADestStream: TStream): Boolean;
|
||||||
|
|
||||||
function CreateTempStream(AWorkbook: TsWorkbook; AFileNameBase: String): TStream;
|
function CreateTempStream(AWorkbook: TsBasicWorkbook;
|
||||||
|
AFileNameBase: String): TStream;
|
||||||
procedure DestroyTempStream(AStream: TStream);
|
procedure DestroyTempStream(AStream: TStream);
|
||||||
|
|
||||||
|
|
||||||
@ -379,7 +380,8 @@ end;
|
|||||||
In the latter two cases a filename mask is provided to create a temporary
|
In the latter two cases a filename mask is provided to create a temporary
|
||||||
filename around this mask.
|
filename around this mask.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function CreateTempStream(AWorkbook: TsWorkbook; AFilenameBase: String): TStream;
|
function CreateTempStream(AWorkbook: TsBasicWorkbook;
|
||||||
|
AFilenameBase: String): TStream;
|
||||||
begin
|
begin
|
||||||
if boFileStream in AWorkbook.Options then
|
if boFileStream in AWorkbook.Options then
|
||||||
Result := TFileStream.Create(GetTempFileName('', AFilenameBase), fmCreate)
|
Result := TFileStream.Create(GetTempFileName('', AFilenameBase), fmCreate)
|
||||||
|
@ -31,7 +31,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
fpimage, fgl, lconvencoding,
|
fpimage, fgl, lconvencoding,
|
||||||
fpsTypes, fpSpreadsheet, fpsUtils, fpsReaderWriter;
|
fpsTypes, fpsUtils, fpsReaderWriter;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -52,10 +52,10 @@ type
|
|||||||
|
|
||||||
TWikiTableTokenizer = class
|
TWikiTableTokenizer = class
|
||||||
private
|
private
|
||||||
FWorkbook: TsWorkbook;
|
FWorkbook: TsBasicWorkbook;
|
||||||
public
|
public
|
||||||
Tokens: TWikiTableTokenList;
|
Tokens: TWikiTableTokenList;
|
||||||
constructor Create(AWorkbook: TsWorkbook); virtual;
|
constructor Create(AWorkbook: TsBasicWorkbook); virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
function AddToken(AValue: string): TWikiTableToken;
|
function AddToken(AValue: string): TWikiTableToken;
|
||||||
@ -79,7 +79,7 @@ type
|
|||||||
|
|
||||||
TsWikiTable_PipesReader = class(TsWikiTableReader)
|
TsWikiTable_PipesReader = class(TsWikiTableReader)
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ type
|
|||||||
|
|
||||||
TsWikiTable_WikiMediaWriter = class(TsWikiTableWriter)
|
TsWikiTable_WikiMediaWriter = class(TsWikiTableWriter)
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -110,12 +110,12 @@ var
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
fpsStrings, fpsXMLCommon;
|
fpsStrings, fpsXMLCommon, fpSpreadsheet;
|
||||||
|
|
||||||
|
|
||||||
{ TWikiTableTokenizer }
|
{ TWikiTableTokenizer }
|
||||||
|
|
||||||
constructor TWikiTableTokenizer.Create(AWorkbook: TsWorkbook);
|
constructor TWikiTableTokenizer.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FWorkbook := AWorkbook;
|
FWorkbook := AWorkbook;
|
||||||
@ -321,7 +321,7 @@ var
|
|||||||
lLineSplitter: TWikiTableTokenizer;
|
lLineSplitter: TWikiTableTokenizer;
|
||||||
lCurToken: TWikiTableToken;
|
lCurToken: TWikiTableToken;
|
||||||
begin
|
begin
|
||||||
FWorksheet := FWorkbook.AddWorksheet('Table', true);
|
FWorksheet := (FWorkbook as TsWorkbook).AddWorksheet('Table', true);
|
||||||
lLineSplitter := TWikiTableTokenizer.Create(FWorkbook);
|
lLineSplitter := TWikiTableTokenizer.Create(FWorkbook);
|
||||||
try
|
try
|
||||||
for i := 0 to AStrings.Count-1 do
|
for i := 0 to AStrings.Count-1 do
|
||||||
@ -331,11 +331,11 @@ begin
|
|||||||
for j := 0 to lLineSplitter.Tokens.Count-1 do
|
for j := 0 to lLineSplitter.Tokens.Count-1 do
|
||||||
begin
|
begin
|
||||||
lCurToken := lLineSplitter.Tokens[j];
|
lCurToken := lLineSplitter.Tokens[j];
|
||||||
FWorksheet.WriteText(i, j, lCurToken.Value);
|
(FWorksheet as TsWorksheet).WriteText(i, j, lCurToken.Value);
|
||||||
if lCurToken.Bold then
|
if lCurToken.Bold then
|
||||||
FWorksheet.WriteFontStyle(i, j, [fssBold]);
|
(FWorksheet as TsWorksheet).WriteFontStyle(i, j, [fssBold]);
|
||||||
if lCurToken.UseBackgroundColor then
|
if lCurToken.UseBackgroundColor then
|
||||||
FWorksheet.WriteBackgroundColor(i, j, lCurToken.BackgroundColor);
|
(FWorksheet as TsWorksheet).WriteBackgroundColor(i, j, lCurToken.BackgroundColor);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
@ -346,7 +346,7 @@ end;
|
|||||||
|
|
||||||
{ TsWikiTable_PipesReader }
|
{ TsWikiTable_PipesReader }
|
||||||
|
|
||||||
constructor TsWikiTable_PipesReader.Create(AWorkbook: TsWorkbook);
|
constructor TsWikiTable_PipesReader.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
SubFormat := sfWikiTable_Pipes;
|
SubFormat := sfWikiTable_Pipes;
|
||||||
@ -420,25 +420,27 @@ var
|
|||||||
borders: TsCellBorders;
|
borders: TsCellBorders;
|
||||||
fs: TFormatSettings;
|
fs: TFormatSettings;
|
||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
FWorksheet := Workbook.GetFirstWorksheet();
|
FWorksheet := (Workbook as TsWorkbook).GetFirstWorksheet();
|
||||||
FWorksheet.UpdateCaches;
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
sheet.UpdateCaches;
|
||||||
|
|
||||||
fs := FWorksheet.FormatSettings;
|
fs := sheet.FormatSettings;
|
||||||
fs.DecimalSeparator := '.';
|
fs.DecimalSeparator := '.';
|
||||||
fs.ThousandSeparator := ',';
|
fs.ThousandSeparator := ',';
|
||||||
|
|
||||||
AStrings.Add('<!-- generated by fpspreadsheet -->');
|
AStrings.Add('<!-- generated by fpspreadsheet -->');
|
||||||
|
|
||||||
// Show/hide grid lines
|
// Show/hide grid lines
|
||||||
if soShowGridLines in FWorksheet.Options then
|
if soShowGridLines in sheet.Options then
|
||||||
lCurStr := '{| class="wikitable"' // sortable"'
|
lCurStr := '{| class="wikitable"' // sortable"'
|
||||||
else
|
else
|
||||||
lCurStr := '{| border="0" cellpadding="2"';
|
lCurStr := '{| border="0" cellpadding="2"';
|
||||||
|
|
||||||
// Default font
|
// Default font
|
||||||
lStyleStr := '';
|
lStyleStr := '';
|
||||||
lFont := FWorkbook.GetDefaultFont;
|
lFont := (FWorkbook as TsWorkbook).GetDefaultFont;
|
||||||
if lFont.FontName <> DEFAULT_FONTNAME then
|
if lFont.FontName <> DEFAULT_FONTNAME then
|
||||||
lStyleStr := lStyleStr + Format('font-family:%s;', [lFont.FontName]);
|
lStyleStr := lStyleStr + Format('font-family:%s;', [lFont.FontName]);
|
||||||
if fssBold in lFont.Style then
|
if fssBold in lFont.Style then
|
||||||
@ -454,16 +456,16 @@ begin
|
|||||||
|
|
||||||
AStrings.Add(lCurStr);
|
AStrings.Add(lCurStr);
|
||||||
|
|
||||||
for i := 0 to FWorksheet.GetLastRowIndex() do
|
for i := 0 to sheet.GetLastRowIndex() do
|
||||||
begin
|
begin
|
||||||
AStrings.Add('|-');
|
AStrings.Add('|-');
|
||||||
//lRow := FWorksheet.FindRow(i);
|
//lRow := sheet.FindRow(i);
|
||||||
|
|
||||||
for j := 0 to FWorksheet.GetLastColIndex do
|
for j := 0 to sheet.GetLastColIndex do
|
||||||
begin
|
begin
|
||||||
lCell := FWorksheet.FindCell(i, j);
|
lCell := sheet.FindCell(i, j);
|
||||||
//lCol := FWorksheet.FindCol(j);
|
//lCol := sheet.FindCol(j);
|
||||||
lCurStr := FWorksheet.ReadAsText(lCell, fs);
|
lCurStr := sheet.ReadAsText(lCell, fs);
|
||||||
|
|
||||||
// Check for invalid characters
|
// Check for invalid characters
|
||||||
if not ValidXMLText(lCurStr, false) then
|
if not ValidXMLText(lCurStr, false) then
|
||||||
@ -480,32 +482,32 @@ begin
|
|||||||
lRowHeightStr := '';
|
lRowHeightStr := '';
|
||||||
|
|
||||||
// Format
|
// Format
|
||||||
fmt := FWorksheet.GetPointerToEffectiveCellFormat(i, j);
|
fmt := sheet.GetPointerToEffectiveCellFormat(i, j);
|
||||||
if fmt <> nil then
|
if fmt <> nil then
|
||||||
lCurUsedFormatting := fmt^.UsedFormattingFields else
|
lCurUsedFormatting := fmt^.UsedFormattingFields else
|
||||||
lCurUsedFormatting := [];
|
lCurUsedFormatting := [];
|
||||||
|
|
||||||
// Row header
|
// Row header
|
||||||
isHeader := (soHasFrozenPanes in FWorksheet.Options) and
|
isHeader := (soHasFrozenPanes in FWorksheet.Options) and
|
||||||
((i < cardinal(FWorksheet.TopPaneHeight)) or (j < cardinal(FWorksheet.LeftPaneWidth)));
|
((i < cardinal(sheet.TopPaneHeight)) or (j < cardinal(sheet.LeftPaneWidth)));
|
||||||
|
|
||||||
// Column width (to be considered in first row)
|
// Column width (to be considered in first row)
|
||||||
if i = 0 then
|
if i = 0 then
|
||||||
lColWidthStr := Format(' width="%.0fpt"', [
|
lColWidthStr := Format(' width="%.0fpt"', [
|
||||||
FWorkbook.ConvertUnits(FWorksheet.GetColWidth(i, suChars), FWorkbook.Units, suPoints)
|
(FWorkbook as TsWorkbook).ConvertUnits(sheet.GetColWidth(i, suChars), FWorkbook.Units, suPoints)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Row height (to be considered in first column)
|
// Row height (to be considered in first column)
|
||||||
if j = 0 then
|
if j = 0 then
|
||||||
lRowHeightStr := Format(' height="%.0fpt"', [
|
lRowHeightStr := Format(' height="%.0fpt"', [
|
||||||
FWorkbook.ConvertUnits(FWorksheet.GetRowHeight(j, suLines), FWorkbook.Units, suPoints)
|
(FWorkbook as TsWorkbook).ConvertUnits(sheet.GetRowHeight(j, suLines), FWorkbook.Units, suPoints)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Font
|
// Font
|
||||||
lFont := FWorkbook.GetDefaultFont;
|
lFont := (FWorkbook as TsWorkbook).GetDefaultFont;
|
||||||
if (uffFont in lCurUsedFormatting) and (fmt <> nil) then
|
if (uffFont in lCurUsedFormatting) and (fmt <> nil) then
|
||||||
begin
|
begin
|
||||||
lFont := FWorkbook.GetFont(fmt^.FontIndex);
|
lFont := (FWorkbook as TsWorkbook).GetFont(fmt^.FontIndex);
|
||||||
if fssBold in lFont.Style then lCurStr := '<b>' + lCurStr + '</b>';
|
if fssBold in lFont.Style then lCurStr := '<b>' + lCurStr + '</b>';
|
||||||
if fssItalic in lFont.Style then lCurStr := '<i>' + lCurStr + '</i>';
|
if fssItalic in lFont.Style then lCurStr := '<i>' + lCurStr + '</i>';
|
||||||
if fssUnderline in lFont.Style then lCurStr := '<u>' + lCurStr + '</u>';
|
if fssUnderline in lFont.Style then lCurStr := '<u>' + lCurStr + '</u>';
|
||||||
@ -570,9 +572,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Merged cells
|
// Merged cells
|
||||||
if FWorksheet.IsMerged(lCell) then
|
if sheet.IsMerged(lCell) then
|
||||||
begin
|
begin
|
||||||
FWorksheet.FindMergedRange(lCell, r1, c1, r2, c2);
|
sheet.FindMergedRange(lCell, r1, c1, r2, c2);
|
||||||
if (i = r1) and (j = c1) then
|
if (i = r1) and (j = c1) then
|
||||||
begin
|
begin
|
||||||
if r1 < r2 then
|
if r1 < r2 then
|
||||||
@ -619,7 +621,7 @@ end;
|
|||||||
|
|
||||||
{ TsWikiTable_WikiMediaWriter }
|
{ TsWikiTable_WikiMediaWriter }
|
||||||
|
|
||||||
constructor TsWikiTable_WikiMediaWriter.Create(AWorkbook: TsWorkbook);
|
constructor TsWikiTable_WikiMediaWriter.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
SubFormat := sfWikiTable_WikiMedia;
|
SubFormat := sfWikiTable_WikiMedia;
|
||||||
|
@ -34,7 +34,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, lconvencoding,
|
Classes, SysUtils, lconvencoding,
|
||||||
fpsTypes, fpspreadsheet, fpsUtils, xlscommon;
|
fpsTypes, fpsUtils, xlscommon;
|
||||||
|
|
||||||
const
|
const
|
||||||
BIFF2_MAX_PALETTE_SIZE = 8;
|
BIFF2_MAX_PALETTE_SIZE = 8;
|
||||||
@ -75,7 +75,7 @@ type
|
|||||||
procedure ReadWindow2(AStream: TStream); override;
|
procedure ReadWindow2(AStream: TStream); override;
|
||||||
procedure ReadXF(AStream: TStream);
|
procedure ReadXF(AStream: TStream);
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
{ General reading methods }
|
{ General reading methods }
|
||||||
procedure ReadFromStream(AStream: TStream; APassword: String = '';
|
procedure ReadFromStream(AStream: TStream; APassword: String = '';
|
||||||
AParams: TsStreamParams = []); override;
|
AParams: TsStreamParams = []); override;
|
||||||
@ -100,8 +100,8 @@ type
|
|||||||
procedure WriteColumnDefault(AStream: TStream;
|
procedure WriteColumnDefault(AStream: TStream;
|
||||||
AFirstColIndex, ALastColIndex: Word; AFormatIndex: Integer);
|
AFirstColIndex, ALastColIndex: Word; AFormatIndex: Integer);
|
||||||
procedure WriteColumnDefaults(AStream: TStream);
|
procedure WriteColumnDefaults(AStream: TStream);
|
||||||
procedure WriteDefaultRowHeight(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteDefaultRowHeight(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteDimensions(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteEOF(AStream: TStream);
|
procedure WriteEOF(AStream: TStream);
|
||||||
procedure WriteFont(AStream: TStream; AFontIndex: Integer);
|
procedure WriteFont(AStream: TStream; AFontIndex: Integer);
|
||||||
procedure WriteFonts(AStream: TStream);
|
procedure WriteFonts(AStream: TStream);
|
||||||
@ -111,7 +111,7 @@ type
|
|||||||
procedure AddBuiltinNumFormats; override;
|
procedure AddBuiltinNumFormats; override;
|
||||||
function FunctionSupported(AExcelCode: Integer;
|
function FunctionSupported(AExcelCode: Integer;
|
||||||
const AFuncName: String): Boolean; override;
|
const AFuncName: String): Boolean; override;
|
||||||
procedure PopulatePalette(AWorkbook: TsWorkbook); override;
|
procedure PopulatePalette(AWorkbook: TsbasicWorkbook); override;
|
||||||
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
ACell: PCell); override;
|
ACell: PCell); override;
|
||||||
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
@ -126,7 +126,7 @@ type
|
|||||||
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: double; ACell: PCell); override;
|
const AValue: double; ACell: PCell); override;
|
||||||
procedure WritePASSWORD(AStream: TStream);
|
procedure WritePASSWORD(AStream: TStream);
|
||||||
procedure WriteRow(AStream: TStream; ASheet: TsWorksheet;
|
procedure WriteRow(AStream: TStream; ASheet: TsBasicWorksheet;
|
||||||
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow); override;
|
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow); override;
|
||||||
procedure WriteRPNFormula(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteRPNFormula(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
AFormula: TsRPNFormula; ACell: PCell); override;
|
AFormula: TsRPNFormula; ACell: PCell); override;
|
||||||
@ -134,11 +134,11 @@ type
|
|||||||
procedure WriteRPNTokenArraySize(AStream: TStream; ASize: Word); override;
|
procedure WriteRPNTokenArraySize(AStream: TStream; ASize: Word); override;
|
||||||
procedure WriteStringRecord(AStream: TStream; AString: String); override;
|
procedure WriteStringRecord(AStream: TStream; AString: String); override;
|
||||||
procedure WriteWindow1(AStream: TStream); override;
|
procedure WriteWindow1(AStream: TStream); override;
|
||||||
procedure WriteWindow2(AStream: TStream; ASheet: TsWorksheet);
|
procedure WriteWindow2(AStream: TStream; ASheet: TsBasicWorksheet);
|
||||||
procedure WriteXF(AStream: TStream; AFormatRecord: PsCellFormat;
|
procedure WriteXF(AStream: TStream; AFormatRecord: PsCellFormat;
|
||||||
XFType_Prot: Byte = 0); override;
|
XFType_Prot: Byte = 0); override;
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsbasicWorkbook); override;
|
||||||
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
|
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ uses
|
|||||||
LazLogger,
|
LazLogger,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Math,
|
Math,
|
||||||
fpsStrings, fpsReaderWriter, fpsPalette, fpsNumFormat;
|
fpsStrings, fpspreadsheet, fpsReaderWriter, fpsPalette, fpsNumFormat;
|
||||||
|
|
||||||
const
|
const
|
||||||
{ Excel record IDs }
|
{ Excel record IDs }
|
||||||
@ -320,7 +320,7 @@ end;
|
|||||||
{ TsSpreadBIFF2Reader }
|
{ TsSpreadBIFF2Reader }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
constructor TsSpreadBIFF2Reader.Create(AWorkbook: TsWorkbook);
|
constructor TsSpreadBIFF2Reader.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
InitBiff2Limitations(FLimitations);
|
InitBiff2Limitations(FLimitations);
|
||||||
@ -342,10 +342,10 @@ begin
|
|||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := TsWorksheet(FWorksheet).AddCell(ARow, ACol);
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
TsWorkbook(FWorkbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -358,7 +358,10 @@ var
|
|||||||
r, c: Cardinal;
|
r, c: Cardinal;
|
||||||
xf: Word;
|
xf: Word;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
{ Read entire record, starting at Row }
|
{ Read entire record, starting at Row }
|
||||||
rec.Row := 0; // to silence the compiler...
|
rec.Row := 0; // to silence the compiler...
|
||||||
AStream.ReadBuffer(rec.Row, SizeOf(TBIFF2_BoolErrRecord) - 2*SizeOf(Word));
|
AStream.ReadBuffer(rec.Row, SizeOf(TBIFF2_BoolErrRecord) - 2*SizeOf(Word));
|
||||||
@ -372,19 +375,19 @@ begin
|
|||||||
InitCell(FWorksheet, r, c, FVirtualCell);
|
InitCell(FWorksheet, r, c, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(r, c);
|
cell := sheet.AddCell(r, c);
|
||||||
|
|
||||||
{ Retrieve boolean or error value depending on the "ValueType" }
|
{ Retrieve boolean or error value depending on the "ValueType" }
|
||||||
case rec.ValueType of
|
case rec.ValueType of
|
||||||
0: FWorksheet.WriteBoolValue(cell, boolean(rec.BoolErrValue));
|
0: sheet.WriteBoolValue(cell, boolean(rec.BoolErrValue));
|
||||||
1: FWorksheet.WriteErrorValue(cell, ConvertFromExcelError(rec.BoolErrValue));
|
1: sheet.WriteErrorValue(cell, ConvertFromExcelError(rec.BoolErrValue));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Apply formatting }
|
{ Apply formatting }
|
||||||
ApplyCellFormatting(cell, xf);
|
ApplyCellFormatting(cell, xf);
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, r, c, cell);
|
TsWorkbook(FWorkbook).OnReadCellData(Workbook, r, c, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadColumnDefault(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadColumnDefault(AStream: TStream);
|
||||||
@ -398,7 +401,10 @@ var
|
|||||||
nf: TsNumFormatParams;
|
nf: TsNumFormatParams;
|
||||||
nfs: String;
|
nfs: String;
|
||||||
b: Byte;
|
b: Byte;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := TsWorkbook(FWorkbook);
|
||||||
|
|
||||||
{ Index of first column }
|
{ Index of first column }
|
||||||
col1 := WordLEToN(AStream.ReadWord);
|
col1 := WordLEToN(AStream.ReadWord);
|
||||||
|
|
||||||
@ -417,9 +423,9 @@ begin
|
|||||||
fontIndex := (attr2 and $C0) shr 6;
|
fontIndex := (attr2 and $C0) shr 6;
|
||||||
if fontIndex > 4 then dec(fontIndex); // Watch out for the nasty missing font #4...
|
if fontIndex > 4 then dec(fontIndex); // Watch out for the nasty missing font #4...
|
||||||
fnt := TsFont(FFontList[fontIndex]);
|
fnt := TsFont(FFontList[fontIndex]);
|
||||||
fmt.FontIndex := Workbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
fmt.FontIndex := book.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
||||||
if fmt.FontIndex = -1 then
|
if fmt.FontIndex = -1 then
|
||||||
fmt.FontIndex := Workbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
fmt.FontIndex := book.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
||||||
if fmt.FontIndex > 0 then
|
if fmt.FontIndex > 0 then
|
||||||
Include(fmt.UsedFormattingFields, uffFont);
|
Include(fmt.UsedFormattingFields, uffFont);
|
||||||
|
|
||||||
@ -427,8 +433,8 @@ begin
|
|||||||
b := attr2 and $3F;
|
b := attr2 and $3F;
|
||||||
nfs := NumFormatList[b];
|
nfs := NumFormatList[b];
|
||||||
if nfs <> '' then begin
|
if nfs <> '' then begin
|
||||||
fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs);
|
fmt.NumberFormatIndex := book.AddNumberFormat(nfs);
|
||||||
nf := Workbook.GetNumberFormat(fmt.NumberFormatIndex);
|
nf := book.GetNumberFormat(fmt.NumberFormatIndex);
|
||||||
fmt.NumberFormat := nf.NumFormat;
|
fmt.NumberFormat := nf.NumFormat;
|
||||||
fmt.NumberFormatStr := nf.NumFormatStr;
|
fmt.NumberFormatStr := nf.NumFormatStr;
|
||||||
if fmt.NumberFormat <> nfGeneral then
|
if fmt.NumberFormat <> nfGeneral then
|
||||||
@ -477,10 +483,10 @@ begin
|
|||||||
|
|
||||||
// Add the decoded data to the format list
|
// Add the decoded data to the format list
|
||||||
FCellFormatList.Add(fmt);
|
FCellFormatList.Add(fmt);
|
||||||
fmtIndex := FWorkbook.AddCellFormat(fmt);
|
fmtIndex := book.AddCellFormat(fmt);
|
||||||
|
|
||||||
for c := col1 to col2 do
|
for c := col1 to col2 do
|
||||||
FWorksheet.WriteColFormatIndex(c, fmtIndex);
|
TsWorksheet(FWorksheet).WriteColFormatIndex(c, fmtIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadColWidth(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadColWidth(AStream: TStream);
|
||||||
@ -490,18 +496,21 @@ var
|
|||||||
c, c1, c2: Cardinal;
|
c, c1, c2: Cardinal;
|
||||||
w: Word;
|
w: Word;
|
||||||
colwidth: Single;
|
colwidth: Single;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
sheet := TsWorksheet(FWorksheet);
|
||||||
|
|
||||||
// read column start and end index of column range
|
// read column start and end index of column range
|
||||||
c1 := AStream.ReadByte;
|
c1 := AStream.ReadByte;
|
||||||
c2 := AStream.ReadByte;
|
c2 := AStream.ReadByte;
|
||||||
// read col width in 1/256 of the width of "0" character
|
// read col width in 1/256 of the width of "0" character
|
||||||
w := WordLEToN(AStream.ReadWord);
|
w := WordLEToN(AStream.ReadWord);
|
||||||
// calculate width in units of "characters"
|
// calculate width in units of "characters"
|
||||||
colwidth := FWorkbook.ConvertUnits(w / 256, suChars, FWorkbook.Units);
|
colwidth := (FWorkbook as TsWorkbook).ConvertUnits(w / 256, suChars, FWorkbook.Units);
|
||||||
// assign width to columns, but only if different from default column width.
|
// assign width to columns, but only if different from default column width.
|
||||||
if not SameValue(colwidth, FWorksheet.ReadDefaultColWidth(FWorkbook.Units), EPS) then
|
if not SameValue(colwidth, sheet.ReadDefaultColWidth(FWorkbook.Units), EPS) then
|
||||||
for c := c1 to c2 do
|
for c := c1 to c2 do
|
||||||
FWorksheet.WriteColWidth(c, colwidth, FWorkbook.Units);
|
sheet.WriteColWidth(c, colwidth, FWorkbook.Units);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadDefRowHeight(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadDefRowHeight(AStream: TStream);
|
||||||
@ -511,12 +520,7 @@ var
|
|||||||
begin
|
begin
|
||||||
hw := WordLEToN(AStream.ReadWord);
|
hw := WordLEToN(AStream.ReadWord);
|
||||||
h := TwipsToPts(hw and $7FFF);
|
h := TwipsToPts(hw and $7FFF);
|
||||||
FWorksheet.WriteDefaultRowHeight(h, suPoints);
|
(FWorksheet as TsWorksheet).WriteDefaultRowHeight(h, suPoints);
|
||||||
{
|
|
||||||
h := TwipsToPts(hw and $8000) / FWorkbook.GetDefaultFontSize;
|
|
||||||
if h > ROW_HEIGHT_CORRECTION then
|
|
||||||
FWorksheet.DefaultRowHeight := h - ROW_HEIGHT_CORRECTION;
|
|
||||||
}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadFONT(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadFONT(AStream: TStream);
|
||||||
@ -553,7 +557,7 @@ begin
|
|||||||
FFontList.Add(FFont);
|
FFontList.Add(FFont);
|
||||||
|
|
||||||
if isDefaultFont then
|
if isDefaultFont then
|
||||||
Workbook.SetDefaultFont(FFont.FontName, FFont.Size);
|
TsWorkbook(FWorkbook).SetDefaultFont(FFont.FontName, FFont.Size);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadFONTCOLOR(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadFONTCOLOR(AStream: TStream);
|
||||||
@ -606,7 +610,7 @@ begin
|
|||||||
BIFF2EOF := False;
|
BIFF2EOF := False;
|
||||||
|
|
||||||
{ In BIFF2 files there is only one worksheet, let's create it }
|
{ In BIFF2 files there is only one worksheet, let's create it }
|
||||||
FWorksheet := FWorkbook.AddWorksheet('Sheet', true);
|
FWorksheet := TsWorkbook(FWorkbook).AddWorksheet('Sheet', true);
|
||||||
|
|
||||||
{ Read all records in a loop }
|
{ Read all records in a loop }
|
||||||
BOFFound := false;
|
BOFFound := false;
|
||||||
@ -685,7 +689,10 @@ var
|
|||||||
nfs: String;
|
nfs: String;
|
||||||
err: TsErrorValue;
|
err: TsErrorValue;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
sheet := TsWorksheet(FWorksheet);
|
||||||
|
|
||||||
{ BIFF Record row/column/style }
|
{ BIFF Record row/column/style }
|
||||||
ReadRowColXF(AStream, ARow, ACol, XF);
|
ReadRowColXF(AStream, ARow, ACol, XF);
|
||||||
|
|
||||||
@ -701,7 +708,7 @@ begin
|
|||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := sheet.AddCell(ARow, ACol);
|
||||||
|
|
||||||
// Now determine the type of the formula result
|
// Now determine the type of the formula result
|
||||||
if (Data[6] = $FF) and (Data[7] = $FF) then
|
if (Data[6] = $FF) and (Data[7] = $FF) then
|
||||||
@ -709,7 +716,7 @@ begin
|
|||||||
0: // String -> Value is found in next record (STRING)
|
0: // String -> Value is found in next record (STRING)
|
||||||
FIncompleteCell := cell;
|
FIncompleteCell := cell;
|
||||||
1: // Boolean value
|
1: // Boolean value
|
||||||
FWorksheet.WriteBoolValue(cell, Data[2] = 1);
|
sheet.WriteBoolValue(cell, Data[2] = 1);
|
||||||
2: begin // Error value
|
2: begin // Error value
|
||||||
case Data[2] of
|
case Data[2] of
|
||||||
ERR_INTERSECTION_EMPTY : err := errEmptyIntersection;
|
ERR_INTERSECTION_EMPTY : err := errEmptyIntersection;
|
||||||
@ -720,10 +727,10 @@ begin
|
|||||||
ERR_OVERFLOW : err := errOverflow;
|
ERR_OVERFLOW : err := errOverflow;
|
||||||
ERR_ARG_ERROR : err := errArgError;
|
ERR_ARG_ERROR : err := errArgError;
|
||||||
end;
|
end;
|
||||||
FWorksheet.WriteErrorValue(cell, err);
|
sheet.WriteErrorValue(cell, err);
|
||||||
end;
|
end;
|
||||||
3: // Empty cell
|
3: // Empty cell
|
||||||
FWorksheet.WriteBlank(cell);
|
sheet.WriteBlank(cell);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -733,23 +740,23 @@ begin
|
|||||||
{Find out what cell type, set content type and value}
|
{Find out what cell type, set content type and value}
|
||||||
ExtractNumberFormat(XF, nf, nfs);
|
ExtractNumberFormat(XF, nf, nfs);
|
||||||
if IsDateTime(formulaResult, nf, nfs, dt) then
|
if IsDateTime(formulaResult, nf, nfs, dt) then
|
||||||
FWorksheet.WriteDateTime(cell, dt, nf, nfs)
|
sheet.WriteDateTime(cell, dt, nf, nfs)
|
||||||
else
|
else
|
||||||
FWorksheet.WriteNumber(cell, formulaResult, nf, nfs);
|
sheet.WriteNumber(cell, formulaResult, nf, nfs);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Formula token array }
|
{ Formula token array }
|
||||||
if (boReadFormulas in FWorkbook.Options) then
|
if (boReadFormulas in FWorkbook.Options) then
|
||||||
begin
|
begin
|
||||||
ok := ReadRPNTokenArray(AStream, cell);
|
ok := ReadRPNTokenArray(AStream, cell);
|
||||||
if not ok then FWorksheet.WriteErrorValue(cell, errFormulaNotSupported);
|
if not ok then sheet.WriteErrorValue(cell, errFormulaNotSupported);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Apply formatting to cell }
|
{ Apply formatting to cell }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
|
|
||||||
if FIsVirtualMode and (cell <> FIncompleteCell) then
|
if FIsVirtualMode and (cell <> FIncompleteCell) then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
TsWorkbook(FWorkbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadLabel(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadLabel(AStream: TStream);
|
||||||
@ -761,7 +768,10 @@ var
|
|||||||
ansiStr: ansistring;
|
ansiStr: ansistring;
|
||||||
valueStr: UTF8String;
|
valueStr: UTF8String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
{ Read entire record, starting at Row, except for string data }
|
{ Read entire record, starting at Row, except for string data }
|
||||||
rec.Row := 0; // to silence the compiler...
|
rec.Row := 0; // to silence the compiler...
|
||||||
AStream.ReadBuffer(rec.Row, SizeOf(TBIFF2_LabelRecord) - 2*SizeOf(Word));
|
AStream.ReadBuffer(rec.Row, SizeOf(TBIFF2_LabelRecord) - 2*SizeOf(Word));
|
||||||
@ -777,33 +787,20 @@ begin
|
|||||||
|
|
||||||
{ Save the data }
|
{ Save the data }
|
||||||
valueStr := ConvertEncoding(ansiStr, FCodePage, encodingUTF8);
|
valueStr := ConvertEncoding(ansiStr, FCodePage, encodingUTF8);
|
||||||
{
|
|
||||||
case WorkBookEncoding of
|
|
||||||
seLatin2: AStrValue := CP1250ToUTF8(AValue);
|
|
||||||
seCyrillic: AStrValue := CP1251ToUTF8(AValue);
|
|
||||||
seGreek: AStrValue := CP1253ToUTF8(AValue);
|
|
||||||
seTurkish: AStrValue := CP1254ToUTF8(AValue);
|
|
||||||
seHebrew: AStrValue := CP1255ToUTF8(AValue);
|
|
||||||
seArabic: AStrValue := CP1256ToUTF8(AValue);
|
|
||||||
else
|
|
||||||
// Latin 1 is the default
|
|
||||||
AStrValue := CP1252ToUTF8(AValue);
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
|
|
||||||
{ Create cell }
|
{ Create cell }
|
||||||
if FIsVirtualMode then begin
|
if FIsVirtualMode then begin
|
||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := sheet.AddCell(ARow, ACol);
|
||||||
FWorksheet.WriteText(cell, valueStr);
|
sheet.WriteText(cell, valueStr);
|
||||||
|
|
||||||
{ Apply formatting to cell }
|
{ Apply formatting to cell }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
|
|
||||||
if FIsVirtualMode and (cell <> FIncompleteCell) then
|
if FIsVirtualMode and (cell <> FIncompleteCell) then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
TsWorkbook(FWorkbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadNumber(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadNumber(AStream: TStream);
|
||||||
@ -816,7 +813,10 @@ var
|
|||||||
nf: TsNumberFormat;
|
nf: TsNumberFormat;
|
||||||
nfs: String;
|
nfs: String;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
{ Read entire record, starting at Row }
|
{ Read entire record, starting at Row }
|
||||||
rec.Row := 0; // to silence the compiler...
|
rec.Row := 0; // to silence the compiler...
|
||||||
AStream.ReadBuffer(rec.Row, SizeOf(TBIFF2_NumberRecord) - 2*SizeOf(Word));
|
AStream.ReadBuffer(rec.Row, SizeOf(TBIFF2_NumberRecord) - 2*SizeOf(Word));
|
||||||
@ -831,30 +831,33 @@ begin
|
|||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := sheet.AddCell(ARow, ACol);
|
||||||
|
|
||||||
{Find out what cell type, set content type and value}
|
{Find out what cell type, set content type and value}
|
||||||
ExtractNumberFormat(XF, nf, nfs);
|
ExtractNumberFormat(XF, nf, nfs);
|
||||||
if IsDateTime(value, nf, nfs, dt) then
|
if IsDateTime(value, nf, nfs, dt) then
|
||||||
FWorksheet.WriteDateTime(cell, dt, nf, nfs)
|
sheet.WriteDateTime(cell, dt, nf, nfs)
|
||||||
else
|
else
|
||||||
FWorksheet.WriteNumber(cell, value, nf, nfs);
|
sheet.WriteNumber(cell, value, nf, nfs);
|
||||||
|
|
||||||
{ Apply formatting to cell }
|
{ Apply formatting to cell }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
|
|
||||||
if FIsVirtualMode and (cell <> FIncompleteCell) then
|
if FIsVirtualMode and (cell <> FIncompleteCell) then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
TsWorkbook(FWorkbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadInteger(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadInteger(AStream: TStream);
|
||||||
var
|
var
|
||||||
|
sheet: TsWorksheet;
|
||||||
ARow, ACol: Cardinal;
|
ARow, ACol: Cardinal;
|
||||||
XF: Word;
|
XF: Word;
|
||||||
AWord : Word = 0;
|
AWord : Word = 0;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
rec: TBIFF2_IntegerRecord;
|
rec: TBIFF2_IntegerRecord;
|
||||||
begin
|
begin
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
{ Read record into buffer }
|
{ Read record into buffer }
|
||||||
rec.Row := 0; // to silence the comiler...
|
rec.Row := 0; // to silence the comiler...
|
||||||
AStream.ReadBuffer(rec.Row, SizeOf(TBIFF2_NumberRecord) - 2*SizeOf(Word));
|
AStream.ReadBuffer(rec.Row, SizeOf(TBIFF2_NumberRecord) - 2*SizeOf(Word));
|
||||||
@ -870,16 +873,16 @@ begin
|
|||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := sheet.AddCell(ARow, ACol);
|
||||||
|
|
||||||
{ Save the data }
|
{ Save the data }
|
||||||
FWorksheet.WriteNumber(cell, AWord);
|
sheet.WriteNumber(cell, AWord);
|
||||||
|
|
||||||
{ Apply formatting to cell }
|
{ Apply formatting to cell }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
|
|
||||||
if FIsVirtualMode and (cell <> FIncompleteCell) then
|
if FIsVirtualMode and (cell <> FIncompleteCell) then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
TsWorkbook(FWorkbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -911,14 +914,14 @@ begin
|
|||||||
|
|
||||||
// Use the same password for workbook and worksheet protection because
|
// Use the same password for workbook and worksheet protection because
|
||||||
// BIFF2 can have only a single sheet.
|
// BIFF2 can have only a single sheet.
|
||||||
FWorkbook.CryptoInfo := cinfo;
|
(FWorkbook as TsWorkbook).CryptoInfo := cinfo;
|
||||||
FWorksheet.CryptoInfo := cinfo;
|
(FWorksheet as TsWorksheet).CryptoInfo := cinfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Reader.ReadPROTECT(AStream: TStream);
|
procedure TsSpreadBIFF2Reader.ReadPROTECT(AStream: TStream);
|
||||||
begin
|
begin
|
||||||
inherited ReadPROTECT(AStream);
|
inherited ReadPROTECT(AStream);
|
||||||
FWorksheet.Protect(Workbook.IsProtected);
|
(FWorksheet as TsWorksheet).Protect(Workbook.IsProtected);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -966,13 +969,18 @@ var
|
|||||||
defRowHeight: Single;
|
defRowHeight: Single;
|
||||||
containsXF: Boolean;
|
containsXF: Boolean;
|
||||||
xf: Word;
|
xf: Word;
|
||||||
|
book: TsWorkbook;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
rowRec.RowIndex := 0; // to silence the compiler...
|
rowRec.RowIndex := 0; // to silence the compiler...
|
||||||
AStream.ReadBuffer(rowrec, SizeOf(TRowRecord));
|
AStream.ReadBuffer(rowrec, SizeOf(TRowRecord));
|
||||||
h := WordLEToN(rowrec.Height);
|
h := WordLEToN(rowrec.Height);
|
||||||
auto := h and $8000 <> 0;
|
auto := h and $8000 <> 0;
|
||||||
rowheight := FWorkbook.ConvertUnits(TwipsToPts(h and $7FFF), suPoints, FWorkbook.Units);
|
rowheight := book.ConvertUnits(TwipsToPts(h and $7FFF), suPoints, FWorkbook.Units);
|
||||||
defRowHeight := FWorksheet.ReadDefaultRowHeight(FWorkbook.Units);
|
defRowHeight := sheet.ReadDefaultRowHeight(FWorkbook.Units);
|
||||||
containsXF := rowRec.ContainsXF = 1;
|
containsXF := rowRec.ContainsXF = 1;
|
||||||
xf := WordLEToN(rowRec.XFIndex);
|
xf := WordLEToN(rowRec.XFIndex);
|
||||||
|
|
||||||
@ -982,7 +990,7 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
|
|
||||||
// Otherwise: create a row record
|
// Otherwise: create a row record
|
||||||
lRow := FWorksheet.GetRow(WordLEToN(rowrec.RowIndex));
|
lRow := sheet.GetRow(WordLEToN(rowrec.RowIndex));
|
||||||
lRow^.Height := rowHeight;
|
lRow^.Height := rowHeight;
|
||||||
if auto then
|
if auto then
|
||||||
lRow^.RowHeightType := rhtAuto else
|
lRow^.RowHeightType := rhtAuto else
|
||||||
@ -1062,7 +1070,9 @@ begin
|
|||||||
FIncompleteCell^.UTF8StringValue := ConvertEncoding(s, FCodePage, encodingUTF8);
|
FIncompleteCell^.UTF8StringValue := ConvertEncoding(s, FCodePage, encodingUTF8);
|
||||||
FIncompleteCell^.ContentType := cctUTF8String;
|
FIncompleteCell^.ContentType := cctUTF8String;
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
TsWorkbook(FWorkbook).OnReadCellData(FWorkbook,
|
||||||
|
FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
FIncompleteCell := nil;
|
FIncompleteCell := nil;
|
||||||
@ -1120,7 +1130,10 @@ var
|
|||||||
nfs: String;
|
nfs: String;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
fnt: TsFont;
|
fnt: TsFont;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
// Read entire xf record into buffer
|
// Read entire xf record into buffer
|
||||||
InitFormatRecord(fmt);
|
InitFormatRecord(fmt);
|
||||||
fmt.ID := FCellFormatList.Count;
|
fmt.ID := FCellFormatList.Count;
|
||||||
@ -1132,9 +1145,9 @@ begin
|
|||||||
i := rec.FontIndex;
|
i := rec.FontIndex;
|
||||||
if i > 4 then dec(i); // Watch out for the nasty missing font #4...
|
if i > 4 then dec(i); // Watch out for the nasty missing font #4...
|
||||||
fnt := TsFont(FFontList[i]);
|
fnt := TsFont(FFontList[i]);
|
||||||
fmt.FontIndex := Workbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
fmt.FontIndex := book.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
||||||
if fmt.FontIndex = -1 then
|
if fmt.FontIndex = -1 then
|
||||||
fmt.FontIndex := Workbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
fmt.FontIndex := book.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color);
|
||||||
if fmt.FontIndex > 0 then
|
if fmt.FontIndex > 0 then
|
||||||
Include(fmt.UsedFormattingFields, uffFont);
|
Include(fmt.UsedFormattingFields, uffFont);
|
||||||
|
|
||||||
@ -1143,8 +1156,8 @@ begin
|
|||||||
nfs := NumFormatList[b];
|
nfs := NumFormatList[b];
|
||||||
if nfs <> '' then
|
if nfs <> '' then
|
||||||
begin
|
begin
|
||||||
fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs);
|
fmt.NumberFormatIndex := book.AddNumberFormat(nfs);
|
||||||
nf := Workbook.GetNumberFormat(fmt.NumberFormatIndex);
|
nf := book.GetNumberFormat(fmt.NumberFormatIndex);
|
||||||
fmt.NumberFormat := nf.NumFormat;
|
fmt.NumberFormat := nf.NumFormat;
|
||||||
fmt.NumberFormatStr := nf.NumFormatStr;
|
fmt.NumberFormatStr := nf.NumFormatStr;
|
||||||
if fmt.NumberFormat <> nfGeneral then
|
if fmt.NumberFormat <> nfGeneral then
|
||||||
@ -1211,7 +1224,7 @@ end;
|
|||||||
{ TsSpreadBIFF2Writer }
|
{ TsSpreadBIFF2Writer }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
constructor TsSpreadBIFF2Writer.Create(AWorkbook: TsWorkbook);
|
constructor TsSpreadBIFF2Writer.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
|
|
||||||
@ -1252,7 +1265,7 @@ var
|
|||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
fontIdx, formatIdx: Integer;
|
fontIdx, formatIdx: Integer;
|
||||||
begin
|
begin
|
||||||
fmt := Workbook.GetPointerToCellFormat(AFormatIndex);
|
fmt := (Workbook as TsWorkbook).GetPointerToCellFormat(AFormatIndex);
|
||||||
|
|
||||||
if fmt^.UsedFormattingFields = [] then begin
|
if fmt^.UsedFormattingFields = [] then begin
|
||||||
Attrib1 := 15 + MASK_XF_TYPE_PROT_LOCKED_BIFF2; // $40
|
Attrib1 := 15 + MASK_XF_TYPE_PROT_LOCKED_BIFF2; // $40
|
||||||
@ -1308,7 +1321,7 @@ begin
|
|||||||
AFormatIndex := 0;
|
AFormatIndex := 0;
|
||||||
if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields) then
|
if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields) then
|
||||||
begin
|
begin
|
||||||
nfParams := Workbook.GetNumberFormat(AFormatRecord^.NumberFormatIndex);
|
nfParams := TsWorkbook(FWorkbook).GetNumberFormat(AFormatRecord^.NumberFormatIndex);
|
||||||
nfs := nfParams.NumFormatStr;
|
nfs := nfParams.NumFormatStr;
|
||||||
AFormatIndex := NumFormatList.IndexOf(nfs);
|
AFormatIndex := NumFormatList.IndexOf(nfs);
|
||||||
if AFormatIndex = -1 then AFormatIndex := 0;
|
if AFormatIndex = -1 then AFormatIndex := 0;
|
||||||
@ -1323,7 +1336,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Writer.PopulatePalette(AWorkbook: TsWorkbook);
|
procedure TsSpreadBIFF2Writer.PopulatePalette(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
FPalette.Clear;
|
FPalette.Clear;
|
||||||
FPalette.AddBuiltinColors(false);
|
FPalette.AddBuiltinColors(false);
|
||||||
@ -1353,7 +1366,7 @@ var
|
|||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
w: Word;
|
w: Word;
|
||||||
begin
|
begin
|
||||||
fmt := Workbook.GetPointerToCellFormat(AFormatIndex);
|
fmt := TsWorkbook(FWorkbook).GetPointerToCellFormat(AFormatIndex);
|
||||||
rec.XFIndex_Locked_Hidden := 0; // to silence the compiler...
|
rec.XFIndex_Locked_Hidden := 0; // to silence the compiler...
|
||||||
FillChar(rec, SizeOf(rec), 0);
|
FillChar(rec, SizeOf(rec), 0);
|
||||||
|
|
||||||
@ -1466,7 +1479,7 @@ var
|
|||||||
lCol, lCol1: PCol;
|
lCol, lCol1: PCol;
|
||||||
lastcol: Integer;
|
lastcol: Integer;
|
||||||
begin
|
begin
|
||||||
sheet := Workbook.GetFirstWorksheet;
|
sheet := TsWorkbook(FWorkbook).GetFirstWorksheet;
|
||||||
j := 0;
|
j := 0;
|
||||||
while (j < sheet.Cols.Count) do begin
|
while (j < sheet.Cols.Count) do begin
|
||||||
lCol := PCol(sheet.Cols[j]);
|
lCol := PCol(sheet.Cols[j]);
|
||||||
@ -1518,9 +1531,9 @@ begin
|
|||||||
{ Column width }
|
{ Column width }
|
||||||
{ calculate width to be in units of 1/256 of pixel width of character "0" }
|
{ calculate width to be in units of 1/256 of pixel width of character "0" }
|
||||||
if ACol^.ColWidthType = cwtDefault then
|
if ACol^.ColWidthType = cwtDefault then
|
||||||
w := FWorksheet.ReadDefaultColWidth(suChars)
|
w := TsWorksheet(FWorksheet).ReadDefaultColWidth(suChars)
|
||||||
else
|
else
|
||||||
w := FWorkbook.ConvertUnits(ACol^.Width, FWorkbook.Units, suChars);
|
w := tsWorkbook(FWorkbook).ConvertUnits(ACol^.Width, FWorkbook.Units, suChars);
|
||||||
rec.ColWidth := WordToLE(round(w*256));
|
rec.ColWidth := WordToLE(round(w*256));
|
||||||
|
|
||||||
{ Write out }
|
{ Write out }
|
||||||
@ -1536,7 +1549,7 @@ var
|
|||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
col: PCol;
|
col: PCol;
|
||||||
begin
|
begin
|
||||||
sheet := Workbook.GetFirstWorksheet;
|
sheet := TsWorkbook(FWorkbook).GetFirstWorksheet;
|
||||||
for j := 0 to sheet.Cols.Count-1 do begin
|
for j := 0 to sheet.Cols.Count-1 do begin
|
||||||
col := PCol(sheet.Cols[j]);
|
col := PCol(sheet.Cols[j]);
|
||||||
WriteColWidth(AStream, col);
|
WriteColWidth(AStream, col);
|
||||||
@ -1547,7 +1560,7 @@ end;
|
|||||||
Writes an Excel 2 DIMENSIONS record
|
Writes an Excel 2 DIMENSIONS record
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF2Writer.WriteDimensions(AStream: TStream;
|
procedure TsSpreadBIFF2Writer.WriteDimensions(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
firstRow, lastRow, firstCol, lastCol: Cardinal;
|
firstRow, lastRow, firstCol, lastCol: Cardinal;
|
||||||
rec: TBIFF2_DimensionsRecord;
|
rec: TBIFF2_DimensionsRecord;
|
||||||
@ -1595,7 +1608,7 @@ var
|
|||||||
begin
|
begin
|
||||||
Unused(AParams);
|
Unused(AParams);
|
||||||
|
|
||||||
FWorksheet := Workbook.GetWorksheetByIndex(FSheetIndex);
|
FWorksheet := (FWorkbook as TsWorkbook).GetWorksheetByIndex(FSheetIndex);
|
||||||
if FWorksheet = nil then
|
if FWorksheet = nil then
|
||||||
raise EFPSpreadsheetWriter.Create(rsWorksheetNotFound1);
|
raise EFPSpreadsheetWriter.Create(rsWorksheetNotFound1);
|
||||||
|
|
||||||
@ -1633,7 +1646,7 @@ begin
|
|||||||
if (boVirtualMode in Workbook.Options) then
|
if (boVirtualMode in Workbook.Options) then
|
||||||
WriteVirtualCells(AStream, FWorksheet)
|
WriteVirtualCells(AStream, FWorksheet)
|
||||||
else
|
else
|
||||||
WriteCellsToStream(AStream, FWorksheet.Cells);
|
WriteCellsToStream(AStream, TsWorksheet(FWorksheet).Cells);
|
||||||
|
|
||||||
WriteWindow1(AStream);
|
WriteWindow1(AStream);
|
||||||
// { -- currently not working
|
// { -- currently not working
|
||||||
@ -1673,9 +1686,10 @@ end;
|
|||||||
Writes an Excel 2 WINDOW2 record
|
Writes an Excel 2 WINDOW2 record
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF2Writer.WriteWindow2(AStream: TStream;
|
procedure TsSpreadBIFF2Writer.WriteWindow2(AStream: TStream;
|
||||||
ASheet: TsWorksheet);
|
ASheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
b: Byte;
|
b: Byte;
|
||||||
|
sheet: TsWorksheet absolute ASheet;
|
||||||
begin
|
begin
|
||||||
{ BIFF Record header }
|
{ BIFF Record header }
|
||||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_WINDOW2));
|
AStream.WriteWord(WordToLE(INT_EXCEL_ID_WINDOW2));
|
||||||
@ -1685,17 +1699,17 @@ begin
|
|||||||
AStream.WriteByte(0);
|
AStream.WriteByte(0);
|
||||||
|
|
||||||
{ Show grid lines }
|
{ Show grid lines }
|
||||||
b := IfThen(soShowGridLines in ASheet.Options, 1, 0);
|
b := IfThen(soShowGridLines in sheet.Options, 1, 0);
|
||||||
AStream.WriteByte(b);
|
AStream.WriteByte(b);
|
||||||
|
|
||||||
{ Show sheet headers }
|
{ Show sheet headers }
|
||||||
b := IfThen(soShowHeaders in ASheet.Options, 1, 0);
|
b := IfThen(soShowHeaders in sheet.Options, 1, 0);
|
||||||
AStream.WriteByte(b);
|
AStream.WriteByte(b);
|
||||||
|
|
||||||
{ Panes are frozen? }
|
{ Panes are frozen? }
|
||||||
b := 0;
|
b := 0;
|
||||||
if (soHasFrozenPanes in ASheet.Options) and
|
if (soHasFrozenPanes in sheet.Options) and
|
||||||
((ASheet.LeftPaneWidth > 0) or (ASheet.TopPaneHeight > 0))
|
((sheet.LeftPaneWidth > 0) or (sheet.TopPaneHeight > 0))
|
||||||
then
|
then
|
||||||
b := 1;
|
b := 1;
|
||||||
AStream.WriteByte(b);
|
AStream.WriteByte(b);
|
||||||
@ -1820,7 +1834,7 @@ var
|
|||||||
optn: Word;
|
optn: Word;
|
||||||
font: TsFont;
|
font: TsFont;
|
||||||
begin
|
begin
|
||||||
font := Workbook.GetFont(AFontIndex);
|
font := TsWorkbook(FWorkbook).GetFont(AFontIndex);
|
||||||
if font = nil then // this happens for FONT4 in case of BIFF
|
if font = nil then // this happens for FONT4 in case of BIFF
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
@ -1868,7 +1882,7 @@ procedure TsSpreadBiff2Writer.WriteFonts(AStream: TStream);
|
|||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
for i:=0 to Workbook.GetFontCount-1 do
|
for i:=0 to TsWorkbook(FWorkbook).GetFontCount-1 do
|
||||||
WriteFont(AStream, i);
|
WriteFont(AStream, i);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2075,7 +2089,7 @@ end;
|
|||||||
corresponding ROW record
|
corresponding ROW record
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF2Writer.WriteDefaultRowHeight(AStream: TStream;
|
procedure TsSpreadBIFF2Writer.WriteDefaultRowHeight(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
h: Single;
|
h: Single;
|
||||||
begin
|
begin
|
||||||
@ -2085,7 +2099,7 @@ begin
|
|||||||
{ Default height for unused rows, in twips = 1/20 of a point
|
{ Default height for unused rows, in twips = 1/20 of a point
|
||||||
Bits 0-14: Default height for unused rows, in twips
|
Bits 0-14: Default height for unused rows, in twips
|
||||||
Bit 15 = 1: Row height not changed manually }
|
Bit 15 = 1: Row height not changed manually }
|
||||||
h := AWorksheet.ReadDefaultRowHeight(suPoints); // h is in points
|
h := TsWorksheet(AWorksheet).ReadDefaultRowHeight(suPoints); // h is in points
|
||||||
AStream.WriteWord(WordToLE(PtsToTwips(h))); // write as twips
|
AStream.WriteWord(WordToLE(PtsToTwips(h))); // write as twips
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2267,20 +2281,25 @@ procedure TsSpreadBIFF2Writer.WritePassword(AStream: TStream);
|
|||||||
var
|
var
|
||||||
hash: Word;
|
hash: Word;
|
||||||
hb, hs: LongInt;
|
hb, hs: LongInt;
|
||||||
|
book: TsWorkbook;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
|
||||||
hb := 0;
|
hb := 0;
|
||||||
if (Workbook.CryptoInfo.PasswordHash <> '') and
|
if (book.CryptoInfo.PasswordHash <> '') and
|
||||||
not TryStrToInt('$' + Workbook.CryptoInfo.PasswordHash, hb) then
|
not TryStrToInt('$' + book.CryptoInfo.PasswordHash, hb) then
|
||||||
begin
|
begin
|
||||||
Workbook.AddErrorMsg(rsPasswordRemoved_NotValid);
|
book.AddErrorMsg(rsPasswordRemoved_NotValid);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
hs := 0;
|
hs := 0;
|
||||||
if (FWorksheet.CryptoInfo.PasswordHash <> '') and
|
if (sheet.CryptoInfo.PasswordHash <> '') and
|
||||||
not TryStrToInt('$' + FWorksheet.CryptoInfo.PasswordHash, hs) then
|
not TryStrToInt('$' + sheet.CryptoInfo.PasswordHash, hs) then
|
||||||
begin
|
begin
|
||||||
Workbook.AddErrorMsg(rsPasswordRemoved_NotValid);
|
book.AddErrorMsg(rsPasswordRemoved_NotValid);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2290,28 +2309,28 @@ begin
|
|||||||
|
|
||||||
// Only workbook password set. Check for Excel algorithm.
|
// Only workbook password set. Check for Excel algorithm.
|
||||||
if (hb <> 0) and (hs = 0) then begin
|
if (hb <> 0) and (hs = 0) then begin
|
||||||
if Workbook.CryptoInfo.Algorithm <> caExcel then begin
|
if book.CryptoInfo.Algorithm <> caExcel then begin
|
||||||
Workbook.AddErrorMsg(rsPasswordRemoved_Excel);
|
book.AddErrorMsg(rsPasswordRemoved_Excel);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
hash := hb;
|
hash := hb;
|
||||||
end else
|
end else
|
||||||
// Only worksheet password set, check for Excel algorithm
|
// Only worksheet password set, check for Excel algorithm
|
||||||
if (hs <> 0) and (hb = 0) then begin
|
if (hs <> 0) and (hb = 0) then begin
|
||||||
if FWorksheet.CryptoInfo.Algorithm <> caExcel then begin
|
if sheet.CryptoInfo.Algorithm <> caExcel then begin
|
||||||
Workbook.AddErrorMsg(rsPasswordRemoved_Excel);
|
book.AddErrorMsg(rsPasswordRemoved_Excel);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
hash := hs;
|
hash := hs;
|
||||||
end else
|
end else
|
||||||
if (hs <> hb) then begin
|
if (hs <> hb) then begin
|
||||||
Workbook.AddErrorMsg(rsPasswordRemoved_BIFF2);
|
book.AddErrorMsg(rsPasswordRemoved_BIFF2);
|
||||||
exit;
|
exit;
|
||||||
end else
|
end else
|
||||||
if (Workbook.CryptoInfo.Algorithm <> caExcel) or
|
if (book.CryptoInfo.Algorithm <> caExcel) or
|
||||||
(FWorksheet.CryptoInfo.Algorithm <> caExcel) then
|
(sheet.CryptoInfo.Algorithm <> caExcel) then
|
||||||
begin
|
begin
|
||||||
Workbook.AddErrorMsg(rsPasswordRemoved_Excel);
|
book.AddErrorMsg(rsPasswordRemoved_Excel);
|
||||||
exit;
|
exit;
|
||||||
end else
|
end else
|
||||||
hash := hs; // or hb -- they are equal here.
|
hash := hs; // or hb -- they are equal here.
|
||||||
@ -2321,7 +2340,7 @@ begin
|
|||||||
AStream.WriteWord(WordToLE(hash));
|
AStream.WriteWord(WordToLE(hash));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF2Writer.WriteRow(AStream: TStream; ASheet: TsWorksheet;
|
procedure TsSpreadBIFF2Writer.WriteRow(AStream: TStream; ASheet: TsBasicWorksheet;
|
||||||
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow);
|
ARowIndex, AFirstColIndex, ALastColIndex: Cardinal; ARow: PRow);
|
||||||
var
|
var
|
||||||
containsXF: Boolean;
|
containsXF: Boolean;
|
||||||
@ -2329,6 +2348,8 @@ var
|
|||||||
auto: Boolean;
|
auto: Boolean;
|
||||||
w: Word;
|
w: Word;
|
||||||
xf: Word;
|
xf: Word;
|
||||||
|
book: TsWorkbook;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
if (ARowIndex >= FLimitations.MaxRowCount) or
|
if (ARowIndex >= FLimitations.MaxRowCount) or
|
||||||
(AFirstColIndex >= FLimitations.MaxColCount) or
|
(AFirstColIndex >= FLimitations.MaxColCount) or
|
||||||
@ -2336,6 +2357,9 @@ begin
|
|||||||
then
|
then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
sheet := ASheet as TsWorksheet;
|
||||||
|
|
||||||
containsXF := (ARow <> nil) and (ARow^.FormatIndex > 0);
|
containsXF := (ARow <> nil) and (ARow^.FormatIndex > 0);
|
||||||
|
|
||||||
{ BIFF record header }
|
{ BIFF record header }
|
||||||
@ -2353,12 +2377,12 @@ begin
|
|||||||
auto := true;
|
auto := true;
|
||||||
{ Row height (in twips, 1/20 point) and info on custom row height }
|
{ Row height (in twips, 1/20 point) and info on custom row height }
|
||||||
if (ARow = nil) or (ARow^.RowHeightType = rhtDefault) then
|
if (ARow = nil) or (ARow^.RowHeightType = rhtDefault) then
|
||||||
rowheight := PtsToTwips(ASheet.ReadDefaultRowHeight(suPoints))
|
rowheight := PtsToTwips(sheet.ReadDefaultRowHeight(suPoints))
|
||||||
else
|
else
|
||||||
if (ARow^.Height = 0) then
|
if (ARow^.Height = 0) then
|
||||||
rowheight := 0
|
rowheight := 0
|
||||||
else begin
|
else begin
|
||||||
rowheight := PtsToTwips(FWorkbook.ConvertUnits(ARow^.Height, FWorkbook.Units, suPoints));
|
rowheight := PtsToTwips(book.ConvertUnits(ARow^.Height, book.Units, suPoints));
|
||||||
auto := ARow^.RowHeightType <> rhtCustom;
|
auto := ARow^.RowHeightType <> rhtCustom;
|
||||||
end;
|
end;
|
||||||
w := rowheight and $7FFF;
|
w := rowheight and $7FFF;
|
||||||
|
@ -58,7 +58,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpcanvas, lconvencoding,
|
Classes, SysUtils, fpcanvas, lconvencoding,
|
||||||
fpsTypes, fpspreadsheet,
|
fpsTypes,
|
||||||
xlscommon,
|
xlscommon,
|
||||||
{$ifdef USE_NEW_OLE}
|
{$ifdef USE_NEW_OLE}
|
||||||
fpolebasic,
|
fpolebasic,
|
||||||
@ -83,7 +83,7 @@ type
|
|||||||
procedure ReadRPNSheetIndex(AStream: TStream; out ADocumentURL: String;
|
procedure ReadRPNSheetIndex(AStream: TStream; out ADocumentURL: String;
|
||||||
out ASheet1, ASheet2: Integer); override;
|
out ASheet1, ASheet2: Integer); override;
|
||||||
procedure ReadRSTRING(AStream: TStream);
|
procedure ReadRSTRING(AStream: TStream);
|
||||||
procedure ReadStandardWidth(AStream: TStream; ASheet: TsWorksheet);
|
procedure ReadStandardWidth(AStream: TStream; ASheet: TsBasicWorksheet);
|
||||||
procedure ReadStringRecord(AStream: TStream); override;
|
procedure ReadStringRecord(AStream: TStream); override;
|
||||||
procedure ReadWorkbookGlobals(AStream: TStream); override;
|
procedure ReadWorkbookGlobals(AStream: TStream); override;
|
||||||
procedure ReadWorksheet(AStream: TStream); override;
|
procedure ReadWorksheet(AStream: TStream); override;
|
||||||
@ -100,14 +100,14 @@ type
|
|||||||
protected
|
protected
|
||||||
function FunctionSupported(AExcelCode: Integer; const AFuncName: String): Boolean; override;
|
function FunctionSupported(AExcelCode: Integer; const AFuncName: String): Boolean; override;
|
||||||
procedure InternalWriteToStream(AStream: TStream);
|
procedure InternalWriteToStream(AStream: TStream);
|
||||||
procedure PopulatePalette(AWorkbook: TsWorkbook); override;
|
procedure PopulatePalette(AWorkbook: TsBasicWorkbook); override;
|
||||||
{ Record writing methods }
|
{ Record writing methods }
|
||||||
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
||||||
function WriteBoundsheet(AStream: TStream; AWorkSheet: TsWorksheet): Int64;
|
function WriteBoundsheet(AStream: TStream; AWorkSheet: TsBasicWorksheet): Int64;
|
||||||
procedure WriteDefinedName(AStream: TStream; AWorksheet: TsWorksheet;
|
procedure WriteDefinedName(AStream: TStream; AWorksheet: TsBasicWorksheet;
|
||||||
const AName: String; AIndexToREF, ASheetIndex: Word;
|
const AName: String; AIndexToREF, ASheetIndex: Word;
|
||||||
AKind: TsBIFFExternKind); override;
|
AKind: TsBIFFExternKind); override;
|
||||||
procedure WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteDimensions(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteEOF(AStream: TStream);
|
procedure WriteEOF(AStream: TStream);
|
||||||
procedure WriteFont(AStream: TStream; AFont: TsFont);
|
procedure WriteFont(AStream: TStream; AFont: TsFont);
|
||||||
procedure WriteFonts(AStream: TStream);
|
procedure WriteFonts(AStream: TStream);
|
||||||
@ -117,16 +117,17 @@ type
|
|||||||
procedure WriteIndex(AStream: TStream);
|
procedure WriteIndex(AStream: TStream);
|
||||||
procedure WriteLABEL(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteLABEL(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: string; ACell: PCell); override;
|
const AValue: string; ACell: PCell); override;
|
||||||
procedure WriteLocalLinkTable(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteLocalLinkTable(AStream: TStream;
|
||||||
|
AWorksheet: TsBasicWorksheet);
|
||||||
function WriteRPNSheetIndex(AStream: TStream; ADocumentURL: String;
|
function WriteRPNSheetIndex(AStream: TStream; ADocumentURL: String;
|
||||||
ASheet1, ASheet2: Integer): Word; override;
|
ASheet1, ASheet2: Integer): Word; override;
|
||||||
procedure WriteStringRecord(AStream: TStream; AString: String); override;
|
procedure WriteStringRecord(AStream: TStream; AString: String); override;
|
||||||
procedure WriteStyle(AStream: TStream);
|
procedure WriteStyle(AStream: TStream);
|
||||||
procedure WriteWindow2(AStream: TStream; ASheet: TsWorksheet);
|
procedure WriteWindow2(AStream: TStream; ASheet: TsBasicWorksheet);
|
||||||
procedure WriteXF(AStream: TStream; AFormatRecord: PsCellFormat;
|
procedure WriteXF(AStream: TStream; AFormatRecord: PsCellFormat;
|
||||||
XFType_Prot: Byte = 0); override;
|
XFType_Prot: Byte = 0); override;
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
{ General writing methods }
|
{ General writing methods }
|
||||||
procedure WriteToFile(const AFileName: string;
|
procedure WriteToFile(const AFileName: string;
|
||||||
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); override;
|
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); override;
|
||||||
@ -228,7 +229,8 @@ uses
|
|||||||
LazLogger,
|
LazLogger,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Math,
|
Math,
|
||||||
fpsStrings, fpsReaderWriter, fpsStreams, fpsPalette, fpsNumFormat, xlsconst;
|
fpsStrings, fpspreadsheet, fpsReaderWriter, fpsStreams,
|
||||||
|
fpsPalette, fpsNumFormat, xlsconst;
|
||||||
|
|
||||||
const
|
const
|
||||||
{ Excel record IDs }
|
{ Excel record IDs }
|
||||||
@ -397,7 +399,9 @@ begin
|
|||||||
SetLength(s, len);
|
SetLength(s, len);
|
||||||
AStream.ReadBuffer(s[1], len*SizeOf(AnsiChar));
|
AStream.ReadBuffer(s[1], len*SizeOf(AnsiChar));
|
||||||
|
|
||||||
sheet := FWorkbook.AddWorksheet(ConvertEncoding(s, FCodePage, EncodingUTF8), true);
|
sheet := (FWorkbook as TsWorkbook).AddWorksheet(
|
||||||
|
ConvertEncoding(s, FCodePage, EncodingUTF8), true
|
||||||
|
);
|
||||||
if sheetState <> 0 then
|
if sheetState <> 0 then
|
||||||
sheet.Options := sheet.Options + [soHidden];
|
sheet.Options := sheet.Options + [soHidden];
|
||||||
end;
|
end;
|
||||||
@ -513,7 +517,7 @@ var
|
|||||||
RecordType: Word;
|
RecordType: Word;
|
||||||
CurStreamPos: Int64;
|
CurStreamPos: Int64;
|
||||||
begin
|
begin
|
||||||
FWorksheet := FWorkbook.GetWorksheetByIndex(FCurSheetIndex);
|
FWorksheet := (FWorkbook as TsWorkbook).GetWorksheetByIndex(FCurSheetIndex);
|
||||||
while (not SectionEOF) do
|
while (not SectionEOF) do
|
||||||
begin
|
begin
|
||||||
{ Read the record header }
|
{ Read the record header }
|
||||||
@ -703,15 +707,20 @@ var
|
|||||||
rtfRuns: TBiff5_RichTextFormattingRuns;
|
rtfRuns: TBiff5_RichTextFormattingRuns;
|
||||||
fntIndex: Integer;
|
fntIndex: Integer;
|
||||||
fnt: TsFont;
|
fnt: TsFont;
|
||||||
|
sheet: TsWorksheet;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
sheet := TsWorksheet(FWorksheet);
|
||||||
|
book := TsWorkbook(FWorkbook);
|
||||||
|
|
||||||
ReadRowColXF(AStream, ARow, ACol, XF);
|
ReadRowColXF(AStream, ARow, ACol, XF);
|
||||||
|
|
||||||
{ Create cell }
|
{ Create cell }
|
||||||
if FIsVirtualMode then begin
|
if FIsVirtualMode then begin
|
||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
InitCell(sheet, ARow, ACol, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := sheet.AddCell(ARow, ACol);
|
||||||
|
|
||||||
{ Read data string (Byte string with 16-bit length) }
|
{ Read data string (Byte string with 16-bit length) }
|
||||||
L := WordLEtoN(AStream.ReadWord);
|
L := WordLEtoN(AStream.ReadWord);
|
||||||
@ -720,7 +729,7 @@ begin
|
|||||||
|
|
||||||
{ Save the data string to cell }
|
{ Save the data string to cell }
|
||||||
valueStr := ConvertEncoding(ansistr, FCodePage, encodingUTF8);
|
valueStr := ConvertEncoding(ansistr, FCodePage, encodingUTF8);
|
||||||
FWorksheet.WriteText(cell, valuestr);
|
sheet.WriteText(cell, valuestr);
|
||||||
|
|
||||||
{ Read rich-text formatting runs }
|
{ Read rich-text formatting runs }
|
||||||
B := AStream.ReadByte;
|
B := AStream.ReadByte;
|
||||||
@ -734,9 +743,9 @@ begin
|
|||||||
// in the file is different from the font index stored by the workbook.
|
// in the file is different from the font index stored by the workbook.
|
||||||
fntIndex := rtfRuns[i].FontIndex;
|
fntIndex := rtfRuns[i].FontIndex;
|
||||||
fnt := TsFont(FFontList[fntIndex]);
|
fnt := TsFont(FFontList[fntIndex]);
|
||||||
fntIndex := FWorkbook.FindFont(fnt.FontName, fnt.Size, fnt.Style,fnt.Color, fnt.Position);
|
fntIndex := book.FindFont(fnt.FontName, fnt.Size, fnt.Style,fnt.Color, fnt.Position);
|
||||||
if fntIndex = -1 then
|
if fntIndex = -1 then
|
||||||
fntIndex := FWorkbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := book.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
cell^.RichTextParams[i].FontIndex := fntIndex;
|
cell^.RichTextParams[i].FontIndex := fntIndex;
|
||||||
// Hyperlink index (not used here)
|
// Hyperlink index (not used here)
|
||||||
cell^.RichTextParams[i].HyperlinkIndex := -1;
|
cell^.RichTextParams[i].HyperlinkIndex := -1;
|
||||||
@ -746,20 +755,21 @@ begin
|
|||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
book.OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Reads the default column width that is used when a bit in the GCW bit structure
|
{ Reads the default column width that is used when a bit in the GCW bit structure
|
||||||
is set for the corresponding column. The GCW is ignored here. The column
|
is set for the corresponding column. The GCW is ignored here. The column
|
||||||
width read from the STANDARDWIDTH record overrides the one from the
|
width read from the STANDARDWIDTH record overrides the one from the
|
||||||
DEFCOLWIDTH record. }
|
DEFCOLWIDTH record. }
|
||||||
procedure TsSpreadBIFF5Reader.ReadStandardWidth(AStream: TStream; ASheet: TsWorksheet);
|
procedure TsSpreadBIFF5Reader.ReadStandardWidth(AStream: TStream;
|
||||||
|
ASheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
w: Word;
|
w: Word;
|
||||||
begin
|
begin
|
||||||
// read width in 1/256 of the width of "0" character
|
// read width in 1/256 of the width of "0" character
|
||||||
w := WordLEToN(AStream.ReadWord);
|
w := WordLEToN(AStream.ReadWord);
|
||||||
ASheet.WriteDefaultRowHeight(w / 256, suChars);
|
(ASheet as TsWorksheet).WriteDefaultRowHeight(w / 256, suChars);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Reads a STRING record which contains the result of string formula. }
|
{ Reads a STRING record which contains the result of string formula. }
|
||||||
@ -777,7 +787,9 @@ begin
|
|||||||
FIncompletecell^.UTF8StringValue := ConvertEncoding(s, FCodePage, encodingUTF8);
|
FIncompletecell^.UTF8StringValue := ConvertEncoding(s, FCodePage, encodingUTF8);
|
||||||
FIncompleteCell^.ContentType := cctUTF8String;
|
FIncompleteCell^.ContentType := cctUTF8String;
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
(Workbook as TsWorkbook).OnReadCellData(
|
||||||
|
Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
FIncompleteCell := nil;
|
FIncompleteCell := nil;
|
||||||
@ -823,8 +835,10 @@ var
|
|||||||
dw: DWord;
|
dw: DWord;
|
||||||
fill: Word;
|
fill: Word;
|
||||||
fs: TsFillStyle;
|
fs: TsFillStyle;
|
||||||
// fnt: TsFont;
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
InitFormatRecord(fmt);
|
InitFormatRecord(fmt);
|
||||||
fmt.ID := FCellFormatList.Count;
|
fmt.ID := FCellFormatList.Count;
|
||||||
|
|
||||||
@ -843,8 +857,8 @@ begin
|
|||||||
// "General" (NumFormatIndex = 0) not stored in workbook's NumFormatList
|
// "General" (NumFormatIndex = 0) not stored in workbook's NumFormatList
|
||||||
if (rec.NumFormatIndex > 0) and not SameText(nfs, 'General') then
|
if (rec.NumFormatIndex > 0) and not SameText(nfs, 'General') then
|
||||||
begin
|
begin
|
||||||
fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs);
|
fmt.NumberFormatIndex := book.AddNumberFormat(nfs);
|
||||||
nfParams := Workbook.GetNumberFormat(fmt.NumberFormatIndex);
|
nfParams := book.GetNumberFormat(fmt.NumberFormatIndex);
|
||||||
fmt.NumberFormat := nfParams.NumFormat;
|
fmt.NumberFormat := nfParams.NumFormat;
|
||||||
fmt.NumberFormatStr := nfs;
|
fmt.NumberFormatStr := nfs;
|
||||||
Include(fmt.UsedFormattingFields, uffNumberFormat);
|
Include(fmt.UsedFormattingFields, uffNumberFormat);
|
||||||
@ -1090,7 +1104,7 @@ begin
|
|||||||
if FFontList.Count = 4 then FFontList.Add(nil);
|
if FFontList.Count = 4 then FFontList.Add(nil);
|
||||||
|
|
||||||
if isDefaultFont then
|
if isDefaultFont then
|
||||||
FWorkbook.SetDefaultFont(font.FontName, font.Size);
|
(FWorkbook as TsWorkbook).SetDefaultFont(font.FontName, font.Size);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Read the FORMAT record for formatting numerical data
|
// Read the FORMAT record for formatting numerical data
|
||||||
@ -1149,17 +1163,17 @@ begin
|
|||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := (FWorksheet as TsWorksheet).AddCell(ARow, ACol);
|
||||||
|
|
||||||
{ Save the data }
|
{ Save the data }
|
||||||
valueStr := ConvertEncoding(ansistr, FCodePage, encodingUTF8);
|
valueStr := ConvertEncoding(ansistr, FCodePage, encodingUTF8);
|
||||||
FWorksheet.WriteText(cell, valueStr); //ISO_8859_1ToUTF8(ansistr));
|
(FWorksheet as TsWorksheet).WriteText(cell, valueStr); //ISO_8859_1ToUTF8(ansistr));
|
||||||
|
|
||||||
{ Add attributes }
|
{ Add attributes }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
(Workbook as TsWorkbook).OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1167,7 +1181,7 @@ end;
|
|||||||
{ TsSpreadBIFF5Writer }
|
{ TsSpreadBIFF5Writer }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
constructor TsSpreadBIFF5Writer.Create(AWorkbook: TsWorkbook);
|
constructor TsSpreadBIFF5Writer.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
FDateMode := Excel5Settings.DateMode;
|
FDateMode := Excel5Settings.DateMode;
|
||||||
@ -1192,14 +1206,17 @@ var
|
|||||||
sheetPos: array of Int64;
|
sheetPos: array of Int64;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
pane: Byte;
|
pane: Byte;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
{ Write workbook globals }
|
{ Write workbook globals }
|
||||||
WriteBOF(AStream, INT_BOF_WORKBOOK_GLOBALS);
|
WriteBOF(AStream, INT_BOF_WORKBOOK_GLOBALS);
|
||||||
|
|
||||||
WriteCODEPAGE(AStream, FCodePage);
|
WriteCODEPAGE(AStream, FCodePage);
|
||||||
WriteWindowProtect(AStream, bpLockWindows in Workbook.Protection);
|
WriteWindowProtect(AStream, bpLockWindows in Workbook.Protection);
|
||||||
WritePROTECT(AStream, bpLockStructure in Workbook.Protection);
|
WritePROTECT(AStream, bpLockStructure in Workbook.Protection);
|
||||||
WritePASSWORD(AStream, Workbook.CryptoInfo);
|
WritePASSWORD(AStream, book.CryptoInfo);
|
||||||
WriteGlobalLinkTable(AStream);
|
WriteGlobalLinkTable(AStream);
|
||||||
WriteDefinedNames(AStream);
|
WriteDefinedNames(AStream);
|
||||||
WriteWINDOW1(AStream);
|
WriteWINDOW1(AStream);
|
||||||
@ -1210,17 +1227,17 @@ begin
|
|||||||
WriteStyle(AStream);
|
WriteStyle(AStream);
|
||||||
|
|
||||||
// A BOUNDSHEET for each worksheet
|
// A BOUNDSHEET for each worksheet
|
||||||
SetLength(sheetPos, Workbook.GetWorksheetCount);
|
SetLength(sheetPos, book.GetWorksheetCount);
|
||||||
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
for i := 0 to book.GetWorksheetCount - 1 do
|
||||||
sheetPos[i] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i));
|
sheetPos[i] := WriteBoundsheet(AStream, book.GetWorksheetByIndex(i));
|
||||||
|
|
||||||
WriteEOF(AStream);
|
WriteEOF(AStream);
|
||||||
|
|
||||||
{ Write each worksheet }
|
{ Write each worksheet }
|
||||||
|
|
||||||
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
for i := 0 to book.GetWorksheetCount - 1 do
|
||||||
begin
|
begin
|
||||||
FWorksheet := Workbook.GetWorksheetByIndex(i);
|
FWorksheet := book.GetWorksheetByIndex(i);
|
||||||
|
|
||||||
{ First goes back and writes the position of the BOF of the
|
{ First goes back and writes the position of the BOF of the
|
||||||
sheet on the respective BOUNDSHEET record }
|
sheet on the respective BOUNDSHEET record }
|
||||||
@ -1255,7 +1272,7 @@ begin
|
|||||||
WritePROTECT(AStream, true);
|
WritePROTECT(AStream, true);
|
||||||
// WriteScenarioProtect(AStream);
|
// WriteScenarioProtect(AStream);
|
||||||
WriteObjectProtect(AStream, FWorksheet);
|
WriteObjectProtect(AStream, FWorksheet);
|
||||||
WritePASSWORD(AStream, FWorksheet.CryptoInfo);
|
WritePASSWORD(AStream, TsWorksheet(FWorksheet).CryptoInfo);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
WriteDefaultColWidth(AStream, FWorksheet);
|
WriteDefaultColWidth(AStream, FWorksheet);
|
||||||
@ -1271,7 +1288,7 @@ begin
|
|||||||
WriteVirtualCells(AStream, FWorksheet)
|
WriteVirtualCells(AStream, FWorksheet)
|
||||||
else begin
|
else begin
|
||||||
WriteRows(AStream, FWorksheet);
|
WriteRows(AStream, FWorksheet);
|
||||||
WriteCellsToStream(AStream, FWorksheet.Cells);
|
WriteCellsToStream(AStream, TsWorksheet(FWorksheet).Cells);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
WriteEOF(AStream);
|
WriteEOF(AStream);
|
||||||
@ -1287,7 +1304,7 @@ end;
|
|||||||
BIFF8 begins with the 8 default colors which are duplicated. Then the user
|
BIFF8 begins with the 8 default colors which are duplicated. Then the user
|
||||||
colors follow up to a max of total 64 entries.
|
colors follow up to a max of total 64 entries.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF5Writer.PopulatePalette(AWorkbook: TsWorkbook);
|
procedure TsSpreadBIFF5Writer.PopulatePalette(AWorkbook: TsBasicWorkbook);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
@ -1405,7 +1422,7 @@ end;
|
|||||||
of the BOF of this sheet should be written (4 bytes size).
|
of the BOF of this sheet should be written (4 bytes size).
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsSpreadBIFF5Writer.WriteBoundsheet(AStream: TStream;
|
function TsSpreadBIFF5Writer.WriteBoundsheet(AStream: TStream;
|
||||||
AWorkSheet: TsWorksheet): Int64;
|
AWorkSheet: TsBasicWorksheet): Int64;
|
||||||
var
|
var
|
||||||
len: Byte;
|
len: Byte;
|
||||||
xlsSheetName: ansistring;
|
xlsSheetName: ansistring;
|
||||||
@ -1442,8 +1459,8 @@ end;
|
|||||||
Writes out a DEFINEDNAMES record
|
Writes out a DEFINEDNAMES record
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF5Writer.WriteDefinedName(AStream: TStream;
|
procedure TsSpreadBIFF5Writer.WriteDefinedName(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet; const AName: String; AIndexToREF, ASheetIndex: Word;
|
AWorksheet: TsBasicWorksheet; const AName: String;
|
||||||
AKind: TsBIFFExternKind);
|
AIndexToREF, ASheetIndex: Word; AKind: TsBIFFExternKind);
|
||||||
|
|
||||||
procedure WriteRangeFormula(MemStream: TMemoryStream; ARange: TsCellRange;
|
procedure WriteRangeFormula(MemStream: TMemoryStream; ARange: TsCellRange;
|
||||||
AIndexToREF, ASheetIndex, ACounter: Word);
|
AIndexToREF, ASheetIndex, ACounter: Word);
|
||||||
@ -1503,42 +1520,46 @@ var
|
|||||||
memstream: TMemoryStream;
|
memstream: TMemoryStream;
|
||||||
rng: TsCellRange;
|
rng: TsCellRange;
|
||||||
j: Integer;
|
j: Integer;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
sheet := AWorksheet as TsWorksheet;
|
||||||
|
|
||||||
// Since this is a variable length record we begin by writing the formula
|
// Since this is a variable length record we begin by writing the formula
|
||||||
// to a memory stream
|
// to a memory stream
|
||||||
memstream := TMemoryStream.Create;
|
memstream := TMemoryStream.Create;
|
||||||
try
|
try
|
||||||
case AName of
|
case AName of
|
||||||
#06: begin // Print range
|
#06: begin // Print range
|
||||||
for j := 0 to AWorksheet.PageLayout.NumPrintRanges-1 do
|
for j := 0 to sheet.PageLayout.NumPrintRanges-1 do
|
||||||
begin
|
begin
|
||||||
rng := AWorksheet.PageLayout.PrintRange[j];
|
rng := sheet.PageLayout.PrintRange[j];
|
||||||
WriteRangeFormula(memstream, rng, AIndexToRef, ASheetIndex, j+1);
|
WriteRangeFormula(memstream, rng, AIndexToRef, ASheetIndex, j+1);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
#07: begin
|
#07: begin
|
||||||
j := 1;
|
j := 1;
|
||||||
if AWorksheet.PageLayout.HasRepeatedCols then
|
if sheet.PageLayout.HasRepeatedCols then
|
||||||
begin
|
begin
|
||||||
rng.Col1 := AWorksheet.PageLayout.RepeatedCols.FirstIndex;
|
rng.Col1 := sheet.PageLayout.RepeatedCols.FirstIndex;
|
||||||
rng.Col2 := AWorksheet.PageLayout.RepeatedCols.LastIndex;
|
rng.Col2 := sheet.PageLayout.RepeatedCols.LastIndex;
|
||||||
if rng.Col2 = UNASSIGNED_ROW_COL_INDEX then rng.Col2 := rng.Col1;
|
if rng.Col2 = UNASSIGNED_ROW_COL_INDEX then rng.Col2 := rng.Col1;
|
||||||
rng.Row1 := 0;
|
rng.Row1 := 0;
|
||||||
rng.Row2 := 65535;
|
rng.Row2 := 65535;
|
||||||
WriteRangeFormula(memstream, rng, AIndexToRef, ASheetIndex, j);
|
WriteRangeFormula(memstream, rng, AIndexToRef, ASheetIndex, j);
|
||||||
inc(j);
|
inc(j);
|
||||||
end;
|
end;
|
||||||
if AWorksheet.PageLayout.HasRepeatedRows then
|
if sheet.PageLayout.HasRepeatedRows then
|
||||||
begin
|
begin
|
||||||
rng.Row1 := AWorksheet.PageLayout.RepeatedRows.FirstIndex;
|
rng.Row1 := sheet.PageLayout.RepeatedRows.FirstIndex;
|
||||||
rng.Row2 := AWorksheet.PageLayout.RepeatedRows.LastIndex;
|
rng.Row2 := sheet.PageLayout.RepeatedRows.LastIndex;
|
||||||
if rng.Row2 = UNASSIGNED_ROW_COL_INDEX then rng.Row2 := rng.Row1;
|
if rng.Row2 = UNASSIGNED_ROW_COL_INDEX then rng.Row2 := rng.Row1;
|
||||||
rng.Col1 := 0;
|
rng.Col1 := 0;
|
||||||
rng.Col2 := 255;
|
rng.Col2 := 255;
|
||||||
WriteRangeFormula(memstream, rng, AIndexToRef, ASheetIndex, j);
|
WriteRangeFormula(memstream, rng, AIndexToRef, ASheetIndex, j);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
else raise EFPSpreadsheetWriter.Create('Name not supported');
|
else
|
||||||
|
raise EFPSpreadsheetWriter.Create('Name not supported');
|
||||||
end; // case
|
end; // case
|
||||||
|
|
||||||
{ BIFF record header }
|
{ BIFF record header }
|
||||||
@ -1598,7 +1619,8 @@ end;
|
|||||||
|
|
||||||
See bug 18886: excel5 files are truncated when imported
|
See bug 18886: excel5 files are truncated when imported
|
||||||
--------------------------------------------------------------------------------}
|
--------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF5Writer.WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure TsSpreadBIFF5Writer.WriteDimensions(AStream: TStream;
|
||||||
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
rec: TBIFF5_DimensionsRecord;
|
rec: TBIFF5_DimensionsRecord;
|
||||||
firstCol, lastCol, firstRow, lastRow: Cardinal;
|
firstCol, lastCol, firstRow, lastRow: Cardinal;
|
||||||
@ -1704,8 +1726,8 @@ procedure TsSpreadBiff5Writer.WriteFonts(AStream: TStream);
|
|||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
for i:=0 to Workbook.GetFontCount-1 do
|
for i:=0 to TsWorkbook(Workbook).GetFontCount-1 do
|
||||||
WriteFont(AStream, Workbook.GetFont(i));
|
WriteFont(AStream, TsWorkbook(Workbook).GetFont(i));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -1907,7 +1929,7 @@ end;
|
|||||||
internal 3D references to other sheets
|
internal 3D references to other sheets
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF5Writer.WriteLocalLinkTable(AStream: TStream;
|
procedure TsSpreadBIFF5Writer.WriteLocalLinkTable(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
i, n: Integer;
|
i, n: Integer;
|
||||||
externSheetList: TsBIFFExternSheetList;
|
externSheetList: TsBIFFExternSheetList;
|
||||||
@ -1993,7 +2015,7 @@ begin
|
|||||||
|
|
||||||
externSheetList := FLinkLists.GetLocalLinks(FWorksheet);
|
externSheetList := FLinkLists.GetLocalLinks(FWorksheet);
|
||||||
|
|
||||||
s := FWorkbook.GetWorksheetByIndex(ASheet1).Name;
|
s := (FWorkbook as TsWorkbook).GetWorksheetByIndex(ASheet1).Name;
|
||||||
externSheetIdx := externSheetList.IndexOfSheet(s);
|
externSheetIdx := externSheetList.IndexOfSheet(s);
|
||||||
|
|
||||||
if ASheet2 = -1 then
|
if ASheet2 = -1 then
|
||||||
@ -2065,11 +2087,14 @@ end;
|
|||||||
Writes an Excel 5 WINDOW2 record
|
Writes an Excel 5 WINDOW2 record
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF5Writer.WriteWindow2(AStream: TStream;
|
procedure TsSpreadBIFF5Writer.WriteWindow2(AStream: TStream;
|
||||||
ASheet: TsWorksheet);
|
ASheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
Options: Word;
|
Options: Word;
|
||||||
|
book: TsWorkbook;
|
||||||
actSheet: TsWorksheet;
|
actSheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
{ BIFF Record header }
|
{ BIFF Record header }
|
||||||
WriteBiffHeader(AStream, INT_EXCEL_ID_WINDOW2, 10);
|
WriteBiffHeader(AStream, INT_EXCEL_ID_WINDOW2, 10);
|
||||||
|
|
||||||
@ -2087,13 +2112,15 @@ begin
|
|||||||
Options := Options or MASK_WINDOW2_OPTION_SHOW_GRID_LINES;
|
Options := Options or MASK_WINDOW2_OPTION_SHOW_GRID_LINES;
|
||||||
if (soShowHeaders in ASheet.Options) then
|
if (soShowHeaders in ASheet.Options) then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS;
|
Options := Options or MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS;
|
||||||
if (soHasFrozenPanes in ASheet.Options) and ((ASheet.LeftPaneWidth > 0) or (ASheet.TopPaneHeight > 0)) then
|
if (soHasFrozenPanes in ASheet.Options) and
|
||||||
|
((TsWorksheet(ASheet).LeftPaneWidth > 0) or (TsWorksheet(ASheet).TopPaneHeight > 0))
|
||||||
|
then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_PANES_ARE_FROZEN;
|
Options := Options or MASK_WINDOW2_OPTION_PANES_ARE_FROZEN;
|
||||||
if (ASheet.BiDiMode = bdRTL) then
|
if (TsWorksheet(ASheet).BiDiMode = bdRTL) then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_COLUMNS_RIGHT_TO_LEFT;
|
Options := Options or MASK_WINDOW2_OPTION_COLUMNS_RIGHT_TO_LEFT;
|
||||||
if FWorkbook.ActiveWorksheet <> nil then
|
if book.ActiveWorksheet <> nil then
|
||||||
actSheet := FWorkbook.ActiveWorksheet else
|
actSheet := book.ActiveWorksheet else
|
||||||
actSheet := Fworkbook.GetWorksheetByIndex(0);
|
actSheet := book.GetWorksheetByIndex(0);
|
||||||
if (ASheet = actSheet) then
|
if (ASheet = actSheet) then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_SHEET_ACTIVE or MASK_WINDOW2_OPTION_SHEET_SELECTED;
|
Options := Options or MASK_WINDOW2_OPTION_SHEET_ACTIVE or MASK_WINDOW2_OPTION_SHEET_SELECTED;
|
||||||
|
|
||||||
@ -2160,7 +2187,7 @@ begin
|
|||||||
j := 0;
|
j := 0;
|
||||||
if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields)
|
if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields)
|
||||||
then begin
|
then begin
|
||||||
nfParams := Workbook.GetNumberFormat(AFormatRecord^.NumberFormatIndex);
|
nfParams := TsWorkbook(Workbook).GetNumberFormat(AFormatRecord^.NumberFormatIndex);
|
||||||
nfs := nfParams.NumFormatStr;
|
nfs := nfParams.NumFormatStr;
|
||||||
j := NumFormatList.IndexOf(nfs);
|
j := NumFormatList.IndexOf(nfs);
|
||||||
if j = -1 then j := 0;
|
if j = -1 then j := 0;
|
||||||
|
@ -55,7 +55,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpcanvas, DateUtils, contnrs, lazutf8,
|
Classes, SysUtils, fpcanvas, DateUtils, contnrs, lazutf8,
|
||||||
fpstypes, fpspreadsheet, xlscommon,
|
fpstypes, xlscommon,
|
||||||
{$ifdef USE_NEW_OLE}
|
{$ifdef USE_NEW_OLE}
|
||||||
fpolebasic,
|
fpolebasic,
|
||||||
{$else}
|
{$else}
|
||||||
@ -175,7 +175,7 @@ type
|
|||||||
procedure ReadWorksheet(AStream: TStream); override;
|
procedure ReadWorksheet(AStream: TStream); override;
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure ReadFromStream(AStream: TStream;
|
procedure ReadFromStream(AStream: TStream;
|
||||||
APassword: String = ''; AParams: TsStreamParams = []); override;
|
APassword: String = ''; AParams: TsStreamParams = []); override;
|
||||||
@ -203,19 +203,20 @@ type
|
|||||||
function IndexOfSharedString(const AText: String;
|
function IndexOfSharedString(const AText: String;
|
||||||
const ARichTextParams: TsRichTextParams): Integer;
|
const ARichTextParams: TsRichTextParams): Integer;
|
||||||
procedure InternalWriteToStream(AStream: TStream);
|
procedure InternalWriteToStream(AStream: TStream);
|
||||||
procedure PopulatePalette(AWorkbook: TsWorkbook); override;
|
procedure PopulatePalette(AWorkbook: TsBasicWorkbook); override;
|
||||||
procedure PopulateSharedStringTable(AWorkbook: TsWorkbook);
|
procedure PopulateSharedStringTable(AWorkbook: TsBasicWorkbook);
|
||||||
|
|
||||||
{ Record writing methods }
|
{ Record writing methods }
|
||||||
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
||||||
function WriteBoundsheet(AStream: TStream; AWorksheet: TsWorksheet): Int64;
|
function WriteBoundsheet(AStream: TStream;
|
||||||
|
AWorksheet: TsBasicWorksheet): Int64;
|
||||||
procedure WriteComment(AStream: TStream; ACell: PCell); override;
|
procedure WriteComment(AStream: TStream; ACell: PCell); override;
|
||||||
procedure WriteComments(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteComments(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteDefinedName(AStream: TStream; AWorksheet: TsWorksheet;
|
procedure WriteDefinedName(AStream: TStream; AWorksheet: TsBasicWorksheet;
|
||||||
const AName: String; AIndexToREF, ASheetIndex: Word;
|
const AName: String; AIndexToREF, ASheetIndex: Word;
|
||||||
AKind: TsBIFFExternKind);
|
AKind: TsBIFFExternKind);
|
||||||
procedure WriteDefinedNames(AStream: TStream);
|
procedure WriteDefinedNames(AStream: TStream);
|
||||||
procedure WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteDimensions(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteEOF(AStream: TStream);
|
procedure WriteEOF(AStream: TStream);
|
||||||
procedure WriteEXTERNBOOK(AStream: TStream; AUrl: String);
|
procedure WriteEXTERNBOOK(AStream: TStream; AUrl: String);
|
||||||
procedure WriteEXTERNSHEET(AStream: TStream);
|
procedure WriteEXTERNSHEET(AStream: TStream);
|
||||||
@ -225,14 +226,14 @@ type
|
|||||||
ANumFormatIndex: Integer); override;
|
ANumFormatIndex: Integer); override;
|
||||||
procedure WriteHeaderFooter(AStream: TStream; AIsHeader: Boolean); override;
|
procedure WriteHeaderFooter(AStream: TStream; AIsHeader: Boolean); override;
|
||||||
procedure WriteHyperlink(AStream: TStream; AHyperlink: PsHyperlink;
|
procedure WriteHyperlink(AStream: TStream; AHyperlink: PsHyperlink;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteHyperlinks(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteHyperlinks(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteHyperlinkToolTip(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteHyperlinkToolTip(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const ATooltip: String);
|
const ATooltip: String);
|
||||||
procedure WriteINDEX(AStream: TStream);
|
procedure WriteINDEX(AStream: TStream);
|
||||||
procedure WriteLABEL(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteLABEL(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: string; ACell: PCell); override;
|
const AValue: string; ACell: PCell); override;
|
||||||
procedure WriteMergedCells(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteMergedCells(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteMSODrawing1(AStream: TStream; ANumShapes: Word; AComment: PsComment);
|
procedure WriteMSODrawing1(AStream: TStream; ANumShapes: Word; AComment: PsComment);
|
||||||
procedure WriteMSODrawing2(AStream: TStream; AComment: PsComment; AObjID: Word);
|
procedure WriteMSODrawing2(AStream: TStream; AComment: PsComment; AObjID: Word);
|
||||||
procedure WriteMSODrawing2_Data(AStream: TStream; AComment: PsComment; AShapeID: Word);
|
procedure WriteMSODrawing2_Data(AStream: TStream; AComment: PsComment; AShapeID: Word);
|
||||||
@ -255,11 +256,11 @@ type
|
|||||||
procedure WriteSTRINGRecord(AStream: TStream; AString: string); override;
|
procedure WriteSTRINGRecord(AStream: TStream; AString: string); override;
|
||||||
procedure WriteSTYLE(AStream: TStream);
|
procedure WriteSTYLE(AStream: TStream);
|
||||||
procedure WriteTXO(AStream: TStream; AComment: PsComment);
|
procedure WriteTXO(AStream: TStream; AComment: PsComment);
|
||||||
procedure WriteWINDOW2(AStream: TStream; ASheet: TsWorksheet);
|
procedure WriteWINDOW2(AStream: TStream; ASheet: TsBasicWorksheet);
|
||||||
procedure WriteXF(AStream: TStream; AFormatRecord: PsCellFormat;
|
procedure WriteXF(AStream: TStream; AFormatRecord: PsCellFormat;
|
||||||
XFType_Prot: Byte = 0); override;
|
XFType_Prot: Byte = 0); override;
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
{ General writing methods }
|
{ General writing methods }
|
||||||
procedure WriteToFile(const AFileName: string;
|
procedure WriteToFile(const AFileName: string;
|
||||||
@ -363,7 +364,7 @@ uses
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Math, lconvencoding, LazFileUtils, URIParser,
|
Math, lconvencoding, LazFileUtils, URIParser,
|
||||||
fpsStrings, {%H-}fpsPatches, fpsStreams, fpsReaderWriter, fpsPalette,
|
fpsStrings, {%H-}fpsPatches, fpsStreams, fpsReaderWriter, fpsPalette,
|
||||||
fpsNumFormat, fpsExprParser, xlsEscher;
|
fpspreadsheet, fpsNumFormat, fpsExprParser, xlsEscher;
|
||||||
|
|
||||||
const
|
const
|
||||||
{ Excel record IDs }
|
{ Excel record IDs }
|
||||||
@ -769,7 +770,7 @@ end;
|
|||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
{ TsSpreadBIFF8Reader }
|
{ TsSpreadBIFF8Reader }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
constructor TsSpreadBIFF8Reader.Create(AWorkbook: TsWorkbook);
|
constructor TsSpreadBIFF8Reader.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
InitBIFF8Limitations(FLimitations);
|
InitBIFF8Limitations(FLimitations);
|
||||||
@ -858,7 +859,7 @@ begin
|
|||||||
if TBIFF8Comment(FCommentList[i]).ID = commentID then
|
if TBIFF8Comment(FCommentList[i]).ID = commentID then
|
||||||
begin
|
begin
|
||||||
commentText := TBIFF8Comment(FCommentList[i]).Text;
|
commentText := TBIFF8Comment(FCommentList[i]).Text;
|
||||||
FWorksheet.WriteComment(r, c, commentText);
|
TsWorksheet(FWorksheet).WriteComment(r, c, commentText);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1158,7 +1159,7 @@ var
|
|||||||
RecordType: Word;
|
RecordType: Word;
|
||||||
CurStreamPos: Int64;
|
CurStreamPos: Int64;
|
||||||
begin
|
begin
|
||||||
FWorksheet := FWorkbook.GetWorksheetByIndex(FCurSheetIndex);
|
FWorksheet := (FWorkbook as TsWorkbook).GetWorksheetByIndex(FCurSheetIndex);
|
||||||
while (not SectionEOF) do
|
while (not SectionEOF) do
|
||||||
begin
|
begin
|
||||||
{ Read the record header }
|
{ Read the record header }
|
||||||
@ -1269,7 +1270,7 @@ begin
|
|||||||
{ Read string with flags }
|
{ Read string with flags }
|
||||||
wideName := ReadWideString(AStream, len, rtParams);
|
wideName := ReadWideString(AStream, len, rtParams);
|
||||||
|
|
||||||
sheet := FWorkbook.AddWorksheet(UTF8Encode(widename), true);
|
sheet := (FWorkbook as TsWorkbook).AddWorksheet(UTF8Encode(widename), true);
|
||||||
if sheetState <> 0 then
|
if sheetState <> 0 then
|
||||||
sheet.Options := sheet.Options + [soHidden];
|
sheet.Options := sheet.Options + [soHidden];
|
||||||
end;
|
end;
|
||||||
@ -1357,7 +1358,10 @@ var
|
|||||||
rtParams: TsRichTextParams;
|
rtParams: TsRichTextParams;
|
||||||
fntIndex: Integer;
|
fntIndex: Integer;
|
||||||
fnt: TsFont;
|
fnt: TsFont;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
{ BIFF Record data: Row, Column, XF Index }
|
{ BIFF Record data: Row, Column, XF Index }
|
||||||
ReadRowColXF(AStream, ARow, ACol, XF);
|
ReadRowColXF(AStream, ARow, ACol, XF);
|
||||||
|
|
||||||
@ -1372,9 +1376,9 @@ begin
|
|||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell); // "virtual" cell
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell); // "virtual" cell
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol); // "real" cell
|
cell := (FWorksheet as TsWorksheet).AddCell(ARow, ACol); // "real" cell
|
||||||
|
|
||||||
FWorksheet.WriteText(cell, UTF16ToUTF8(wideStrValue));
|
(FWorksheet as TsWorksheet).WriteText(cell, UTF16ToUTF8(wideStrValue));
|
||||||
|
|
||||||
{ Add attributes }
|
{ Add attributes }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
@ -1389,9 +1393,9 @@ begin
|
|||||||
// Font index of new format - need to adjust index!
|
// Font index of new format - need to adjust index!
|
||||||
fntIndex := rtParams[i].FontIndex;
|
fntIndex := rtParams[i].FontIndex;
|
||||||
fnt := TsFont(FFontList[fntIndex]);
|
fnt := TsFont(FFontList[fntIndex]);
|
||||||
fntIndex := FWorkbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := book.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
if fntIndex = -1 then
|
if fntIndex = -1 then
|
||||||
fntIndex := FWorkbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := book.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
cell^.RichTextParams[i].FontIndex := fntIndex;
|
cell^.RichTextParams[i].FontIndex := fntIndex;
|
||||||
// Hyperlink index, not used here
|
// Hyperlink index, not used here
|
||||||
cell^.RichTextParams[i].HyperlinkIndex := -1;
|
cell^.RichTextParams[i].HyperlinkIndex := -1;
|
||||||
@ -1399,7 +1403,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
book.OnReadCellData(Workbook, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF8Reader.ReadMergedCells(const AStream: TStream);
|
procedure TsSpreadBIFF8Reader.ReadMergedCells(const AStream: TStream);
|
||||||
@ -1416,7 +1420,7 @@ begin
|
|||||||
// Read range
|
// Read range
|
||||||
AStream.ReadBuffer(rng, SizeOf(rng));
|
AStream.ReadBuffer(rng, SizeOf(rng));
|
||||||
// Transfer cell range to worksheet
|
// Transfer cell range to worksheet
|
||||||
FWorksheet.MergeCells(
|
(FWorksheet as TsWorksheet).MergeCells(
|
||||||
WordLEToN(rng.Row1), WordLEToN(rng.Col1),
|
WordLEToN(rng.Row1), WordLEToN(rng.Col1),
|
||||||
WordLEToN(rng.Row2), WordLEToN(rng.Col2)
|
WordLEToN(rng.Row2), WordLEToN(rng.Col2)
|
||||||
);
|
);
|
||||||
@ -1629,7 +1633,10 @@ var
|
|||||||
rtfRuns: TBiff8_RichTextFormattingRuns;
|
rtfRuns: TBiff8_RichTextFormattingRuns;
|
||||||
fntIndex: Integer;
|
fntIndex: Integer;
|
||||||
fnt: TsFont;
|
fnt: TsFont;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
{ BIFF Record data: Row, Column, XF Index }
|
{ BIFF Record data: Row, Column, XF Index }
|
||||||
ReadRowColXF(AStream, ARow, ACol, XF);
|
ReadRowColXF(AStream, ARow, ACol, XF);
|
||||||
|
|
||||||
@ -1644,10 +1651,10 @@ begin
|
|||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell); // "virtual" cell
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell); // "virtual" cell
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol); // "real" cell
|
cell := (FWorksheet as TsWorksheet).AddCell(ARow, ACol); // "real" cell
|
||||||
|
|
||||||
{ Save the data string}
|
{ Save the data string}
|
||||||
FWorksheet.WriteText(cell, UTF16ToUTF8(wideStrValue));
|
(FWorksheet as TsWorksheet).WriteText(cell, UTF16ToUTF8(wideStrValue));
|
||||||
|
|
||||||
{ Read rich-text formatting runs }
|
{ Read rich-text formatting runs }
|
||||||
L := WordLEToN(AStream.ReadWord);
|
L := WordLEToN(AStream.ReadWord);
|
||||||
@ -1660,9 +1667,9 @@ begin
|
|||||||
// necessarily the same as the index used by the workbook!
|
// necessarily the same as the index used by the workbook!
|
||||||
fntIndex := WordLEToN(rtfRuns[j].FontIndex);
|
fntIndex := WordLEToN(rtfRuns[j].FontIndex);
|
||||||
fnt := TsFont(FFontList[fntIndex]);
|
fnt := TsFont(FFontList[fntIndex]);
|
||||||
fntIndex := FWorkbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := book.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
if fntIndex = -1 then
|
if fntIndex = -1 then
|
||||||
fntIndex := FWorkbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := book.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
cell^.RichTextParams[j].FontIndex := fntIndex;
|
cell^.RichTextParams[j].FontIndex := fntIndex;
|
||||||
// Index of the first character using this font: 0-based in file, 1-based in fps
|
// Index of the first character using this font: 0-based in file, 1-based in fps
|
||||||
cell^.RichTextParams[j].FirstIndex := WordLEToN(rtfRuns[j].FirstIndex) + 1;
|
cell^.RichTextParams[j].FirstIndex := WordLEToN(rtfRuns[j].FirstIndex) + 1;
|
||||||
@ -1674,7 +1681,7 @@ begin
|
|||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
book.OnReadCellData(book, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF8Reader.ReadSST(const AStream: TStream);
|
procedure TsSpreadBIFF8Reader.ReadSST(const AStream: TStream);
|
||||||
@ -1773,7 +1780,10 @@ var
|
|||||||
rtParams: TsRichTextParams;
|
rtParams: TsRichTextParams;
|
||||||
fnt: TsFont;
|
fnt: TsFont;
|
||||||
fntIndex: Integer;
|
fntIndex: Integer;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
rec.Row := 0; // to silence the compiler...
|
rec.Row := 0; // to silence the compiler...
|
||||||
|
|
||||||
{ Read entire record, starting at Row }
|
{ Read entire record, starting at Row }
|
||||||
@ -1794,9 +1804,9 @@ begin
|
|||||||
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
InitCell(FWorksheet, ARow, ACol, FVirtualCell);
|
||||||
cell := @FVirtualCell;
|
cell := @FVirtualCell;
|
||||||
end else
|
end else
|
||||||
cell := FWorksheet.AddCell(ARow, ACol);
|
cell := (FWorksheet as TsWorksheet).AddCell(ARow, ACol);
|
||||||
|
|
||||||
FWorksheet.WriteText(cell, FSharedStringTable.Strings[SSTIndex]);
|
(FWorksheet as TsWorksheet).WriteText(cell, FSharedStringTable.Strings[SSTIndex]);
|
||||||
|
|
||||||
{ Add attributes }
|
{ Add attributes }
|
||||||
ApplyCellFormatting(cell, XF);
|
ApplyCellFormatting(cell, XF);
|
||||||
@ -1814,16 +1824,16 @@ begin
|
|||||||
cell^.RichTextParams[i].FirstIndex := rtParams[i].FirstIndex;
|
cell^.RichTextParams[i].FirstIndex := rtParams[i].FirstIndex;
|
||||||
fntIndex := rtParams[i].FontIndex;
|
fntIndex := rtParams[i].FontIndex;
|
||||||
fnt := TsFont(FFontList[fntIndex]);
|
fnt := TsFont(FFontList[fntIndex]);
|
||||||
fntIndex := FWorkbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := book.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
if fntIndex = -1 then
|
if fntIndex = -1 then
|
||||||
fntIndex := FWorkbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
fntIndex := book.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position);
|
||||||
cell^.RichTextParams[i].FontIndex := fntIndex;
|
cell^.RichTextParams[i].FontIndex := fntIndex;
|
||||||
cell^.RichTextParams[i].HyperlinkIndex := -1;
|
cell^.RichTextParams[i].HyperlinkIndex := -1;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
|
book.OnReadCellData(book, ARow, ACol, cell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Helper function for reading a string with 8-bit length. }
|
{ Helper function for reading a string with 8-bit length. }
|
||||||
@ -1841,13 +1851,16 @@ end;
|
|||||||
procedure TsSpreadBIFF8Reader.ReadStringRecord(AStream: TStream);
|
procedure TsSpreadBIFF8Reader.ReadStringRecord(AStream: TStream);
|
||||||
var
|
var
|
||||||
wideStr: WideString;
|
wideStr: WideString;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
wideStr := ReadWideString(AStream, false);
|
wideStr := ReadWideString(AStream, false);
|
||||||
if (FIncompleteCell <> nil) and (wideStr <> '') then begin
|
if (FIncompleteCell <> nil) and (wideStr <> '') then begin
|
||||||
FIncompleteCell^.UTF8StringValue := UTF8Encode(wideStr);
|
FIncompleteCell^.UTF8StringValue := UTF8Encode(wideStr);
|
||||||
FIncompleteCell^.ContentType := cctUTF8String;
|
FIncompleteCell^.ContentType := cctUTF8String;
|
||||||
if FIsVirtualMode then
|
if FIsVirtualMode then
|
||||||
Workbook.OnReadCellData(Workbook, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
book.OnReadCellData(book, FIncompleteCell^.Row, FIncompleteCell^.Col, FIncompleteCell);
|
||||||
end;
|
end;
|
||||||
FIncompleteCell := nil;
|
FIncompleteCell := nil;
|
||||||
end;
|
end;
|
||||||
@ -1875,7 +1888,10 @@ var
|
|||||||
nfs: String;
|
nfs: String;
|
||||||
nfParams: TsNumFormatParams;
|
nfParams: TsNumFormatParams;
|
||||||
iclr: Integer;
|
iclr: Integer;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
InitFormatRecord(fmt);
|
InitFormatRecord(fmt);
|
||||||
fmt.ID := FCellFormatList.Count;
|
fmt.ID := FCellFormatList.Count;
|
||||||
|
|
||||||
@ -1894,8 +1910,8 @@ begin
|
|||||||
// "General" (NumFormatIndex = 0) not stored in workbook's NumFormatList
|
// "General" (NumFormatIndex = 0) not stored in workbook's NumFormatList
|
||||||
if (rec.NumFormatIndex > 0) and not SameText(nfs, 'General') then
|
if (rec.NumFormatIndex > 0) and not SameText(nfs, 'General') then
|
||||||
begin
|
begin
|
||||||
fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs);
|
fmt.NumberFormatIndex := book.AddNumberFormat(nfs);
|
||||||
nfParams := Workbook.GetNumberFormat(fmt.NumberFormatIndex);
|
nfParams := book.GetNumberFormat(fmt.NumberFormatIndex);
|
||||||
if nfParams <> nil then
|
if nfParams <> nil then
|
||||||
begin
|
begin
|
||||||
fmt.NumberFormat := nfParams.NumFormat;
|
fmt.NumberFormat := nfParams.NumFormat;
|
||||||
@ -2265,7 +2281,7 @@ begin
|
|||||||
if FFontList.Count = 4 then FFontList.Add(nil);
|
if FFontList.Count = 4 then FFontList.Add(nil);
|
||||||
|
|
||||||
if isDefaultFont then
|
if isDefaultFont then
|
||||||
Workbook.SetDefaultFont(font.FontName, font.Size);
|
(Workbook as TsWorkbook).SetDefaultFont(font.FontName, font.Size);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -2312,10 +2328,11 @@ begin
|
|||||||
|
|
||||||
len := WordLEToN(AStream.ReadWord);
|
len := WordLEToN(AStream.ReadWord);
|
||||||
s := ReadWideString(AStream, len, rtParams);
|
s := ReadWideString(AStream, len, rtParams);
|
||||||
if AIsHeader then
|
with (FWorksheet as TsWorksheet).Pagelayout do
|
||||||
FWorksheet.PageLayout.Headers[1] := UTF8Encode(s)
|
if AIsHeader then
|
||||||
else
|
Headers[1] := UTF8Encode(s)
|
||||||
FWOrksheet.PageLayout.Footers[1] := UTF8Encode(s);
|
else
|
||||||
|
Footers[1] := UTF8Encode(s);
|
||||||
|
|
||||||
{ Options poDifferentFirst and poDifferentOddEvent are not used, BIFF supports
|
{ Options poDifferentFirst and poDifferentOddEvent are not used, BIFF supports
|
||||||
only common headers/footers }
|
only common headers/footers }
|
||||||
@ -2461,7 +2478,7 @@ begin
|
|||||||
// Add hyperlink(s) to worksheet
|
// Add hyperlink(s) to worksheet
|
||||||
for row := row1 to row2 do
|
for row := row1 to row2 do
|
||||||
for col := col1 to col2 do
|
for col := col1 to col2 do
|
||||||
FWorksheet.WriteHyperlink(row, col, link);
|
TsWorksheet(FWorksheet).WriteHyperlink(row, col, link);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -2476,6 +2493,7 @@ var
|
|||||||
row1, col1, row2, col2: Word;
|
row1, col1, row2, col2: Word;
|
||||||
hyperlink: PsHyperlink;
|
hyperlink: PsHyperlink;
|
||||||
numbytes: Integer;
|
numbytes: Integer;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
{ Record type; this matches the BIFF record type }
|
{ Record type; this matches the BIFF record type }
|
||||||
AStream.ReadWord;
|
AStream.ReadWord;
|
||||||
@ -2494,7 +2512,8 @@ begin
|
|||||||
txt := UTF8Encode(wideStr);
|
txt := UTF8Encode(wideStr);
|
||||||
|
|
||||||
{ Add tooltip to hyperlinks }
|
{ Add tooltip to hyperlinks }
|
||||||
for hyperlink in FWorksheet.Hyperlinks.GetRangeEnumerator(row1, col1, row2, col2) do
|
sheet := FWorksheet as TsWorksheet;
|
||||||
|
for hyperlink in sheet.Hyperlinks.GetRangeEnumerator(row1, col1, row2, col2) do
|
||||||
hyperlink^.ToolTip := txt;
|
hyperlink^.ToolTip := txt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2506,7 +2525,7 @@ end;
|
|||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Constructor of the Excel 8 writer
|
Constructor of the Excel 8 writer
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
constructor TsSpreadBIFF8Writer.Create(AWorkbook: TsWorkbook);
|
constructor TsSpreadBIFF8Writer.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
InitBiff8Limitations(FLimitations);
|
InitBiff8Limitations(FLimitations);
|
||||||
@ -2576,6 +2595,7 @@ procedure TsSpreadBIFF8Writer.CollectExternData;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
book: TsWorkbook;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
writeIt: Boolean;
|
writeIt: Boolean;
|
||||||
@ -2586,9 +2606,11 @@ begin
|
|||||||
FBiff8ExternBooks := TsBIFF8ExternBookList.Create;
|
FBiff8ExternBooks := TsBIFF8ExternBookList.Create;
|
||||||
FBiff8ExternSheets := TsBIFF8ExternSheetList.Create(FBiff8ExternBooks);
|
FBiff8ExternSheets := TsBIFF8ExternSheetList.Create(FBiff8ExternBooks);
|
||||||
|
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
{ Add sheets used in print ranges, repeated cols or repeated rows }
|
{ Add sheets used in print ranges, repeated cols or repeated rows }
|
||||||
for i:=0 to FWorkbook.GetWorksheetCount-1 do begin
|
for i:=0 to book.GetWorksheetCount-1 do begin
|
||||||
sheet := FWorkbook.GetWorksheetByIndex(i);
|
sheet := book.GetWorksheetByIndex(i);
|
||||||
with sheet.PageLayout do
|
with sheet.PageLayout do
|
||||||
writeIt := (NumPrintRanges > 0) or HasRepeatedCols or HasRepeatedRows;
|
writeIt := (NumPrintRanges > 0) or HasRepeatedCols or HasRepeatedRows;
|
||||||
if writeIt then
|
if writeIt then
|
||||||
@ -2596,9 +2618,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ Add sheets related to 3d references of all sheets }
|
{ Add sheets related to 3d references of all sheets }
|
||||||
for i:=0 to FWorkbook.GetWorksheetCount-1 do
|
for i:=0 to book.GetWorksheetCount-1 do
|
||||||
begin
|
begin
|
||||||
sheet := FWorkbook.GetWorksheetByIndex(i);
|
sheet := book.GetWorksheetByIndex(i);
|
||||||
DoCollectForSheet(sheet);
|
DoCollectForSheet(sheet);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2632,7 +2654,7 @@ Begin
|
|||||||
Bit 9: 0 = Print notes as displayed; 1 = Print notes at end of sheet
|
Bit 9: 0 = Print notes as displayed; 1 = Print notes at end of sheet
|
||||||
Bit 11-10: 00 = Print errors as displayed; 1 = Do not print errors
|
Bit 11-10: 00 = Print errors as displayed; 1 = Do not print errors
|
||||||
2 = Print errors as “--”; 3 = Print errors as “#N/A” }
|
2 = Print errors as “--”; 3 = Print errors as “#N/A” }
|
||||||
if poCommentsAtEnd in FWorksheet.PageLayout.Options then
|
if poCommentsAtEnd in (FWorksheet as TsWorksheet).PageLayout.Options then
|
||||||
Result := Result or $0200;
|
Result := Result or $0200;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2671,7 +2693,9 @@ var
|
|||||||
sheetPos: array of Int64;
|
sheetPos: array of Int64;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
pane: Byte;
|
pane: Byte;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
CollectExternData;
|
CollectExternData;
|
||||||
|
|
||||||
{ Write workbook globals }
|
{ Write workbook globals }
|
||||||
@ -2679,7 +2703,7 @@ begin
|
|||||||
WriteCodePage(AStream, 'ucs2le'); // = utf-16
|
WriteCodePage(AStream, 'ucs2le'); // = utf-16
|
||||||
WriteWindowProtect(AStream, bpLockWindows in Workbook.Protection);
|
WriteWindowProtect(AStream, bpLockWindows in Workbook.Protection);
|
||||||
WritePROTECT(AStream, bpLockStructure in Workbook.Protection);
|
WritePROTECT(AStream, bpLockStructure in Workbook.Protection);
|
||||||
WritePASSWORD(AStream, Workbook.CryptoInfo);
|
WritePASSWORD(AStream, book.CryptoInfo);
|
||||||
WriteWINDOW1(AStream);
|
WriteWINDOW1(AStream);
|
||||||
WriteFonts(AStream);
|
WriteFonts(AStream);
|
||||||
WriteNumFormats(AStream);
|
WriteNumFormats(AStream);
|
||||||
@ -2688,9 +2712,9 @@ begin
|
|||||||
WriteStyle(AStream);
|
WriteStyle(AStream);
|
||||||
|
|
||||||
// A BOUNDSHEET for each worksheet
|
// A BOUNDSHEET for each worksheet
|
||||||
SetLength(sheetPos, Workbook.GetWorksheetCount);
|
SetLength(sheetPos, book.GetWorksheetCount);
|
||||||
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
for i := 0 to book.GetWorksheetCount - 1 do
|
||||||
sheetPos[i] := WriteBoundsheet(AStream, Workbook.GetWorksheetByIndex(i));
|
sheetPos[i] := WriteBoundsheet(AStream, book.GetWorksheetByIndex(i));
|
||||||
|
|
||||||
WriteEXTERNBOOK(AStream, '');
|
WriteEXTERNBOOK(AStream, '');
|
||||||
WriteEXTERNSHEET(AStream);
|
WriteEXTERNSHEET(AStream);
|
||||||
@ -2700,9 +2724,9 @@ begin
|
|||||||
WriteEOF(AStream);
|
WriteEOF(AStream);
|
||||||
|
|
||||||
{ Write each worksheet }
|
{ Write each worksheet }
|
||||||
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
for i := 0 to book.GetWorksheetCount - 1 do
|
||||||
begin
|
begin
|
||||||
FWorksheet := Workbook.GetWorksheetByIndex(i);
|
FWorksheet := book.GetWorksheetByIndex(i);
|
||||||
|
|
||||||
{ First goes back and writes the position of the BOF of the
|
{ First goes back and writes the position of the BOF of the
|
||||||
sheet on the respective BOUNDSHEET record }
|
sheet on the respective BOUNDSHEET record }
|
||||||
@ -2734,7 +2758,7 @@ begin
|
|||||||
WritePROTECT(AStream, true);
|
WritePROTECT(AStream, true);
|
||||||
// WriteScenarioProtect(AStream);
|
// WriteScenarioProtect(AStream);
|
||||||
WriteObjectProtect(AStream, FWorksheet);
|
WriteObjectProtect(AStream, FWorksheet);
|
||||||
WritePASSWORD(AStream, FWorksheet.CryptoInfo);
|
WritePASSWORD(AStream, (FWorksheet as TsWorksheet).CryptoInfo);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
WriteDefaultColWidth(AStream, FWorksheet);
|
WriteDefaultColWidth(AStream, FWorksheet);
|
||||||
@ -2745,7 +2769,7 @@ begin
|
|||||||
WriteVirtualCells(AStream, FWorksheet)
|
WriteVirtualCells(AStream, FWorksheet)
|
||||||
else begin
|
else begin
|
||||||
WriteRows(AStream, FWorksheet);
|
WriteRows(AStream, FWorksheet);
|
||||||
WriteCellsToStream(AStream, FWorksheet.Cells);
|
WriteCellsToStream(AStream, (FWorksheet as TsWorksheet).Cells);
|
||||||
WriteComments(AStream, FWorksheet);
|
WriteComments(AStream, FWorksheet);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2770,7 +2794,7 @@ end;
|
|||||||
BIFF8 begins with the 8 default colors which are duplicated. Then the user
|
BIFF8 begins with the 8 default colors which are duplicated. Then the user
|
||||||
colors follow up to a max of total 64 entries.
|
colors follow up to a max of total 64 entries.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF8Writer.PopulatePalette(AWorkbook: TsWorkbook);
|
procedure TsSpreadBIFF8Writer.PopulatePalette(AWorkbook: TsBasicWorkbook);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
@ -2791,18 +2815,19 @@ end;
|
|||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Collects all strings of the workbook in the SharedStringTable
|
Collects all strings of the workbook in the SharedStringTable
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF8Writer.PopulateSharedStringTable(AWorkbook: TsWorkbook);
|
procedure TsSpreadBIFF8Writer.PopulateSharedStringTable(AWorkbook: TsBasicWorkbook);
|
||||||
var
|
var
|
||||||
i, idx: Integer;
|
i, idx: Integer;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
|
book: TsWorkbook absolute AWorkbook;
|
||||||
begin
|
begin
|
||||||
FNumStrings := 0;
|
FNumStrings := 0;
|
||||||
FSharedStringTable := TStringList.Create;
|
FSharedStringTable := TStringList.Create;
|
||||||
|
|
||||||
for i:=0 to AWorkbook.GetWorksheetCount-1 do
|
for i:=0 to book.GetWorksheetCount-1 do
|
||||||
begin
|
begin
|
||||||
sheet := AWorkbook.GetWorksheetByIndex(i);
|
sheet := book.GetWorksheetByIndex(i);
|
||||||
for cell in sheet.Cells do begin
|
for cell in sheet.Cells do begin
|
||||||
if (cell^.ContentType <> cctUTF8String) then
|
if (cell^.ContentType <> cctUTF8String) then
|
||||||
Continue;
|
Continue;
|
||||||
@ -2925,7 +2950,7 @@ end;
|
|||||||
of the BOF of this sheet should be written (4 bytes size).
|
of the BOF of this sheet should be written (4 bytes size).
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsSpreadBIFF8Writer.WriteBoundsheet(AStream: TStream;
|
function TsSpreadBIFF8Writer.WriteBoundsheet(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet): Int64;
|
AWorksheet: TsBasicWorksheet): Int64;
|
||||||
var
|
var
|
||||||
len: Byte;
|
len: Byte;
|
||||||
wideSheetName: WideString;
|
wideSheetName: WideString;
|
||||||
@ -2972,21 +2997,24 @@ end;
|
|||||||
Writes all comments to the worksheet stream
|
Writes all comments to the worksheet stream
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF8Writer.WriteComments(AStream: TStream;
|
procedure TsSpreadBIFF8Writer.WriteComments(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
index: Integer;
|
index: Integer;
|
||||||
comment: PsComment;
|
comment: PsComment;
|
||||||
|
sheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
exit; // Remove after comments can be written correctly
|
exit; // Remove after comments can be written correctly
|
||||||
{$warning TODO: Fix writing of cell comments in BIFF8 (file is readable by OpenOffice, but not by Excel)}
|
{$warning TODO: Fix writing of cell comments in BIFF8 (file is readable by OpenOffice, but not by Excel)}
|
||||||
|
|
||||||
|
sheet := AWorksheet as TsWorksheet;
|
||||||
|
|
||||||
{ At first we have to write all Escher-related records for all comments;
|
{ At first we have to write all Escher-related records for all comments;
|
||||||
MSODRAWING - OBJ - MSODRAWING - TXO }
|
MSODRAWING - OBJ - MSODRAWING - TXO }
|
||||||
index := 1;
|
index := 1;
|
||||||
for comment in AWorksheet.Comments do
|
for comment in sheet.Comments do
|
||||||
begin
|
begin
|
||||||
if index = 1 then
|
if index = 1 then
|
||||||
WriteMSODrawing1(AStream, FWorksheet.Comments.Count, comment)
|
WriteMSODrawing1(AStream, sheet.Comments.Count, comment)
|
||||||
else
|
else
|
||||||
WriteMSODrawing2(AStream, comment, index);
|
WriteMSODrawing2(AStream, comment, index);
|
||||||
WriteOBJ(AStream, index);
|
WriteOBJ(AStream, index);
|
||||||
@ -2997,7 +3025,7 @@ begin
|
|||||||
|
|
||||||
{ The NOTE records for all comments follow subsequently. }
|
{ The NOTE records for all comments follow subsequently. }
|
||||||
index := 1;
|
index := 1;
|
||||||
for comment in AWorksheet.Comments do
|
for comment in sheet.Comments do
|
||||||
begin
|
begin
|
||||||
WriteNOTE(AStream, comment, index);
|
WriteNOTE(AStream, comment, index);
|
||||||
inc(index);
|
inc(index);
|
||||||
@ -3009,8 +3037,8 @@ end;
|
|||||||
Implements only the builtin defined names for print ranges and titles!
|
Implements only the builtin defined names for print ranges and titles!
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF8Writer.WriteDefinedName(AStream: TStream;
|
procedure TsSpreadBIFF8Writer.WriteDefinedName(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet; const AName: String; AIndexToREF, ASheetIndex: Word;
|
AWorksheet: TsBasicWorksheet; const AName: String;
|
||||||
AKind: TsBIFFExternKind);
|
AIndexToREF, ASheetIndex: Word; AKind: TsBIFFExternKind);
|
||||||
|
|
||||||
procedure WriteRangeFormula(MemStream: TMemoryStream; ARange: TsCellRange;
|
procedure WriteRangeFormula(MemStream: TMemoryStream; ARange: TsCellRange;
|
||||||
AIndexToRef, ACounter: Word);
|
AIndexToRef, ACounter: Word);
|
||||||
@ -3042,6 +3070,8 @@ var
|
|||||||
memstream: TMemoryStream;
|
memstream: TMemoryStream;
|
||||||
rng: TsCellRange;
|
rng: TsCellRange;
|
||||||
j: Integer;
|
j: Integer;
|
||||||
|
idx: Integer;
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
// Since this is a variable length record we begin by writing the formula
|
// Since this is a variable length record we begin by writing the formula
|
||||||
@ -3050,28 +3080,28 @@ begin
|
|||||||
try
|
try
|
||||||
case AName of
|
case AName of
|
||||||
#06: begin // Print range
|
#06: begin // Print range
|
||||||
for j := 0 to AWorksheet.PageLayout.NumPrintRanges-1 do
|
for j := 0 to sheet.PageLayout.NumPrintRanges-1 do
|
||||||
begin
|
begin
|
||||||
rng := AWorksheet.PageLayout.PrintRange[j];
|
rng := sheet.PageLayout.PrintRange[j];
|
||||||
WriteRangeFormula(memstream, rng, AIndexToRef, j+1);
|
WriteRangeFormula(memstream, rng, AIndexToRef, j+1);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
#07: begin // Print titles
|
#07: begin // Print titles
|
||||||
j := 1;
|
j := 1;
|
||||||
if AWorksheet.PageLayout.HasRepeatedCols then
|
if sheet.PageLayout.HasRepeatedCols then
|
||||||
begin
|
begin
|
||||||
rng.Col1 := AWorksheet.PageLayout.RepeatedCols.FirstIndex;
|
rng.Col1 := sheet.PageLayout.RepeatedCols.FirstIndex;
|
||||||
rng.Col2 := AWorksheet.PageLayout.RepeatedCols.LastIndex;
|
rng.Col2 := sheet.PageLayout.RepeatedCols.LastIndex;
|
||||||
if rng.Col2 = UNASSIGNED_ROW_COL_INDEX then rng.Col2 := rng.Col1;
|
if rng.Col2 = UNASSIGNED_ROW_COL_INDEX then rng.Col2 := rng.Col1;
|
||||||
rng.Row1 := 0;
|
rng.Row1 := 0;
|
||||||
rng.Row2 := 65535;
|
rng.Row2 := 65535;
|
||||||
WriteRangeFormula(memstream, rng, AIndexToRef, j);
|
WriteRangeFormula(memstream, rng, AIndexToRef, j);
|
||||||
inc(j);
|
inc(j);
|
||||||
end;
|
end;
|
||||||
if AWorksheet.PageLayout.HasRepeatedRows then
|
if sheet.PageLayout.HasRepeatedRows then
|
||||||
begin
|
begin
|
||||||
rng.Row1 := AWorksheet.PageLayout.RepeatedRows.FirstIndex;
|
rng.Row1 := sheet.PageLayout.RepeatedRows.FirstIndex;
|
||||||
rng.Row2 := AWorksheet.PageLayout.RepeatedRows.LastIndex;
|
rng.Row2 := sheet.PageLayout.RepeatedRows.LastIndex;
|
||||||
if rng.Row2 = UNASSIGNED_ROW_COL_INDEX then rng.Row2 := rng.Row1;
|
if rng.Row2 = UNASSIGNED_ROW_COL_INDEX then rng.Row2 := rng.Row1;
|
||||||
rng.Col1 := 0;
|
rng.Col1 := 0;
|
||||||
rng.Col2 := 255;
|
rng.Col2 := 255;
|
||||||
@ -3102,7 +3132,8 @@ begin
|
|||||||
AStream.WriteWord(0);
|
AStream.WriteWord(0);
|
||||||
|
|
||||||
{ Index to sheet (1-based) }
|
{ Index to sheet (1-based) }
|
||||||
AStream.WriteWord(WordToLE(FWorkbook.GetWorksheetIndex(AWorksheet)+1));
|
idx := (FWorkbook as TsWorkbook).GetWorksheetIndex(AWorksheet);
|
||||||
|
AStream.WriteWord(WordToLE(idx+1));
|
||||||
|
|
||||||
{ Length of menu text }
|
{ Length of menu text }
|
||||||
AStream.WriteByte(0);
|
AStream.WriteByte(0);
|
||||||
@ -3134,18 +3165,21 @@ end;
|
|||||||
procedure TsSpreadBIFF8Writer.WriteDefinedNames(AStream: TStream);
|
procedure TsSpreadBIFF8Writer.WriteDefinedNames(AStream: TStream);
|
||||||
var
|
var
|
||||||
bookIdx: Integer;
|
bookIdx: Integer;
|
||||||
|
book: TsWorkbook;
|
||||||
sheet: TsWorksheet;
|
sheet: TsWorksheet;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
if (FBiff8ExternBooks = nil) or (FBiff8ExternSheets = nil) then
|
if (FBiff8ExternBooks = nil) or (FBiff8ExternSheets = nil) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
|
||||||
// Defined names in "internal" book only
|
// Defined names in "internal" book only
|
||||||
bookIdx := FBiff8ExternBooks.IndexOfInternalbook;
|
bookIdx := FBiff8ExternBooks.IndexOfInternalbook;
|
||||||
|
|
||||||
for i:=0 to FWorkbook.GetWorksheetCount-1 do
|
for i:=0 to book.GetWorksheetCount-1 do
|
||||||
begin
|
begin
|
||||||
sheet := FWorkbook.GetWorksheetByIndex(i);
|
sheet := book.GetWorksheetByIndex(i);
|
||||||
if (sheet.PageLayout.NumPrintRanges > 0) or
|
if (sheet.PageLayout.NumPrintRanges > 0) or
|
||||||
sheet.PageLayout.HasRepeatedCols or sheet.PageLayout.HasRepeatedRows then
|
sheet.PageLayout.HasRepeatedCols or sheet.PageLayout.HasRepeatedRows then
|
||||||
begin
|
begin
|
||||||
@ -3170,7 +3204,7 @@ end;
|
|||||||
See bug 18886: excel5 files are truncated when imported
|
See bug 18886: excel5 files are truncated when imported
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF8Writer.WriteDimensions(AStream: TStream;
|
procedure TsSpreadBIFF8Writer.WriteDimensions(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
firstRow, lastRow, firstCol, lastCol: Cardinal;
|
firstRow, lastRow, firstCol, lastCol: Cardinal;
|
||||||
rec: TBIFF8_DimensionsRecord;
|
rec: TBIFF8_DimensionsRecord;
|
||||||
@ -3219,7 +3253,7 @@ begin
|
|||||||
{ Current workbook -- assuming that it has index 0 in list FExternBook8 }
|
{ Current workbook -- assuming that it has index 0 in list FExternBook8 }
|
||||||
if AUrl = '' then begin
|
if AUrl = '' then begin
|
||||||
{ Number of sheets in this workbook }
|
{ Number of sheets in this workbook }
|
||||||
AStream.WriteWord(WordToLE(FWorkbook.GetWorksheetCount));
|
AStream.WriteWord(WordToLE((FWorkbook as TsWorkbook).GetWorksheetCount));
|
||||||
|
|
||||||
{ Relict from BIFF5 }
|
{ Relict from BIFF5 }
|
||||||
AStream.WriteWord(WordToLE($0401));
|
AStream.WriteWord(WordToLE($0401));
|
||||||
@ -3344,9 +3378,11 @@ end;
|
|||||||
procedure TsSpreadBiff8Writer.WriteFonts(AStream: TStream);
|
procedure TsSpreadBiff8Writer.WriteFonts(AStream: TStream);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
for i:=0 to Workbook.GetFontCount-1 do
|
book := FWorkbook as TsWorkbook;
|
||||||
WriteFONT(AStream, Workbook.GetFont(i));
|
for i:=0 to book.GetFontCount-1 do
|
||||||
|
WriteFONT(AStream, book.GetFont(i));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
@ -3407,7 +3443,7 @@ var
|
|||||||
len: Integer;
|
len: Integer;
|
||||||
id: Word;
|
id: Word;
|
||||||
begin
|
begin
|
||||||
with FWorksheet.PageLayout do
|
with (FWorksheet as TsWorksheet).PageLayout do
|
||||||
if AIsHeader then
|
if AIsHeader then
|
||||||
begin
|
begin
|
||||||
if (Headers[HEADER_FOOTER_INDEX_ALL] = '') then
|
if (Headers[HEADER_FOOTER_INDEX_ALL] = '') then
|
||||||
@ -3440,7 +3476,7 @@ end;
|
|||||||
Writes an Excel 8 HYPERLINK record
|
Writes an Excel 8 HYPERLINK record
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF8Writer.WriteHyperlink(AStream: TStream;
|
procedure TsSpreadBIFF8Writer.WriteHyperlink(AStream: TStream;
|
||||||
AHyperlink: PsHyperlink; AWorksheet: TsWorksheet);
|
AHyperlink: PsHyperlink; AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
temp: TStream;
|
temp: TStream;
|
||||||
guid: TGUID;
|
guid: TGUID;
|
||||||
@ -3456,11 +3492,11 @@ var
|
|||||||
isInternal: Boolean;
|
isInternal: Boolean;
|
||||||
dirUpCounter: Integer;
|
dirUpCounter: Integer;
|
||||||
begin
|
begin
|
||||||
cell := AWorksheet.FindCell(AHyperlink^.Row, AHyperlink^.Col);
|
cell := (AWorksheet as TsWorksheet).FindCell(AHyperlink^.Row, AHyperlink^.Col);
|
||||||
if (cell = nil) or (AHyperlink^.Target='') then
|
if (cell = nil) or (AHyperlink^.Target='') then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
descr := AWorksheet.ReadAsText(cell); // Hyperlink description
|
descr := (AWorksheet as TsWorksheet).ReadAsText(cell); // Hyperlink description
|
||||||
SplitHyperlink(AHyperlink^.Target, target, bookmark);
|
SplitHyperlink(AHyperlink^.Target, target, bookmark);
|
||||||
u := ParseURI(AHyperlink^.Target);
|
u := ParseURI(AHyperlink^.Target);
|
||||||
isInternal := (target = '') and (bookmark <> '');
|
isInternal := (target = '') and (bookmark <> '');
|
||||||
@ -3597,11 +3633,11 @@ end;
|
|||||||
Writes all hyperlinks
|
Writes all hyperlinks
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF8Writer.WriteHyperlinks(AStream: TStream;
|
procedure TsSpreadBIFF8Writer.WriteHyperlinks(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
hyperlink: PsHyperlink;
|
hyperlink: PsHyperlink;
|
||||||
begin
|
begin
|
||||||
for hyperlink in AWorksheet.Hyperlinks do begin
|
for hyperlink in (AWorksheet as TsWorksheet).Hyperlinks do begin
|
||||||
{ Write HYPERLINK record }
|
{ Write HYPERLINK record }
|
||||||
WriteHyperlink(AStream, hyperlink, AWorksheet);
|
WriteHyperlink(AStream, hyperlink, AWorksheet);
|
||||||
{ Write HYPERLINK TOOLTIP record }
|
{ Write HYPERLINK TOOLTIP record }
|
||||||
@ -3787,18 +3823,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadBIFF8Writer.WriteMergedCells(AStream: TStream;
|
procedure TsSpreadBIFF8Writer.WriteMergedCells(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
const
|
const
|
||||||
MAX_PER_RECORD = 1026;
|
MAX_PER_RECORD = 1026;
|
||||||
var
|
var
|
||||||
n0, n: Integer;
|
n0, n: Integer;
|
||||||
rng: PsCellRange;
|
rng: PsCellRange;
|
||||||
newRecord: Boolean;
|
newRecord: Boolean;
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
begin
|
begin
|
||||||
n0 := AWorksheet.MergedCells.Count;
|
n0 := sheet.MergedCells.Count;
|
||||||
n := Min(n0, MAX_PER_RECORD);
|
n := Min(n0, MAX_PER_RECORD);
|
||||||
newRecord := true;
|
newRecord := true;
|
||||||
for rng in AWorksheet.MergedCells do
|
for rng in sheet.MergedCells do
|
||||||
begin
|
begin
|
||||||
if newRecord then
|
if newRecord then
|
||||||
begin
|
begin
|
||||||
@ -4781,11 +4818,15 @@ end;
|
|||||||
sheets.
|
sheets.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
procedure TsSpreadBIFF8Writer.WriteWINDOW2(AStream: TStream;
|
procedure TsSpreadBIFF8Writer.WriteWINDOW2(AStream: TStream;
|
||||||
ASheet: TsWorksheet);
|
ASheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
Options: Word;
|
Options: Word;
|
||||||
actSheet: TsWorksheet;
|
book: TsWorkbook;
|
||||||
|
sheet, actSheet: TsWorksheet;
|
||||||
begin
|
begin
|
||||||
|
book := FWorkbook as TsWorkbook;
|
||||||
|
sheet := ASheet as TsWorksheet;
|
||||||
|
|
||||||
{ BIFF Record header }
|
{ BIFF Record header }
|
||||||
WriteBiffHeader(AStream, INT_EXCEL_ID_WINDOW2, 18);
|
WriteBiffHeader(AStream, INT_EXCEL_ID_WINDOW2, 18);
|
||||||
|
|
||||||
@ -4800,18 +4841,18 @@ begin
|
|||||||
{ Bug 0026386 -> every sheet must be selected/active, otherwise Excel cannot print
|
{ Bug 0026386 -> every sheet must be selected/active, otherwise Excel cannot print
|
||||||
---> wp: after changes for issue 0028452: this is not necessary any more. }
|
---> wp: after changes for issue 0028452: this is not necessary any more. }
|
||||||
|
|
||||||
if (soShowGridLines in ASheet.Options) then
|
if (soShowGridLines in sheet.Options) then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_SHOW_GRID_LINES;
|
Options := Options or MASK_WINDOW2_OPTION_SHOW_GRID_LINES;
|
||||||
if (soShowHeaders in ASheet.Options) then
|
if (soShowHeaders in sheet.Options) then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS;
|
Options := Options or MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS;
|
||||||
if (soHasFrozenPanes in ASheet.Options) and ((ASheet.LeftPaneWidth > 0) or (ASheet.TopPaneHeight > 0)) then
|
if (soHasFrozenPanes in sheet.Options) and ((sheet.LeftPaneWidth > 0) or (sheet.TopPaneHeight > 0)) then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_PANES_ARE_FROZEN;
|
Options := Options or MASK_WINDOW2_OPTION_PANES_ARE_FROZEN;
|
||||||
if FWorkbook.ActiveWorksheet <> nil then
|
if book.ActiveWorksheet <> nil then
|
||||||
actSheet := FWorkbook.ActiveWorksheet else
|
actSheet := book.ActiveWorksheet else
|
||||||
actSheet := Fworkbook.GetWorksheetByIndex(0);
|
actSheet := book.GetWorksheetByIndex(0);
|
||||||
if (ASheet = actSheet) then
|
if (sheet = actSheet) then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_SHEET_ACTIVE or MASK_WINDOW2_OPTION_SHEET_SELECTED;
|
Options := Options or MASK_WINDOW2_OPTION_SHEET_ACTIVE or MASK_WINDOW2_OPTION_SHEET_SELECTED;
|
||||||
if (ASheet.BiDiMode = bdRTL) then
|
if (sheet.BiDiMode = bdRTL) then
|
||||||
Options := Options or MASK_WINDOW2_OPTION_COLUMNS_RIGHT_TO_LEFT;
|
Options := Options or MASK_WINDOW2_OPTION_COLUMNS_RIGHT_TO_LEFT;
|
||||||
AStream.WriteWord(WordToLE(Options));
|
AStream.WriteWord(WordToLE(Options));
|
||||||
|
|
||||||
@ -4870,7 +4911,7 @@ begin
|
|||||||
j := 0;
|
j := 0;
|
||||||
if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields)
|
if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields)
|
||||||
then begin
|
then begin
|
||||||
nfParams := Workbook.GetNumberFormat(AFormatRecord^.NumberFormatIndex);
|
nfParams := (Workbook as TsWorkbook).GetNumberFormat(AFormatRecord^.NumberFormatIndex);
|
||||||
if nfParams <> nil then
|
if nfParams <> nil then
|
||||||
begin
|
begin
|
||||||
nfs := nfParams.NumFormatStr;
|
nfs := nfParams.NumFormatStr;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
laz2_xmlread, laz2_DOM,
|
laz2_xmlread, laz2_DOM,
|
||||||
fpsTypes, fpspreadsheet, fpsReaderWriter, xlsCommon;
|
fpsTypes, fpsReaderWriter, xlsCommon;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -35,21 +35,21 @@ type
|
|||||||
FPointSeparatorSettings: TFormatSettings;
|
FPointSeparatorSettings: TFormatSettings;
|
||||||
function GetCommentStr(ACell: PCell): String;
|
function GetCommentStr(ACell: PCell): String;
|
||||||
function GetFormulaStr(ACell: PCell): String;
|
function GetFormulaStr(ACell: PCell): String;
|
||||||
function GetFrozenPanesStr(AWorksheet: TsWorksheet; AIndent: String): String;
|
function GetFrozenPanesStr(AWorksheet: TsBasicWorksheet; AIndent: String): String;
|
||||||
function GetHyperlinkStr(ACell: PCell): String;
|
function GetHyperlinkStr(ACell: PCell): String;
|
||||||
function GetIndexStr(AIndex: Integer): String;
|
function GetIndexStr(AIndex: Integer): String;
|
||||||
function GetLayoutStr(AWorksheet: TsWorksheet): String;
|
function GetLayoutStr(AWorksheet: TsBasicWorksheet): String;
|
||||||
function GetMergeStr(ACell: PCell): String;
|
function GetMergeStr(ACell: PCell): String;
|
||||||
function GetPageFooterStr(AWorksheet: TsWorksheet): String;
|
function GetPageFooterStr(AWorksheet: TsBasicWorksheet): String;
|
||||||
function GetPageHeaderStr(AWorksheet: TsWorksheet): String;
|
function GetPageHeaderStr(AWorksheet: TsBasicWorksheet): String;
|
||||||
function GetPageMarginStr(AWorksheet: TsWorksheet): String;
|
function GetPageMarginStr(AWorksheet: TsBasicWorksheet): String;
|
||||||
function GetStyleStr(AFormatIndex: Integer): String;
|
function GetStyleStr(AFormatIndex: Integer): String;
|
||||||
procedure WriteExcelWorkbook(AStream: TStream);
|
procedure WriteExcelWorkbook(AStream: TStream);
|
||||||
procedure WriteStyle(AStream: TStream; AIndex: Integer);
|
procedure WriteStyle(AStream: TStream; AIndex: Integer);
|
||||||
procedure WriteStyles(AStream: TStream);
|
procedure WriteStyles(AStream: TStream);
|
||||||
procedure WriteTable(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteTable(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteWorksheet(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteWorksheet(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteWorksheetOptions(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure WriteWorksheetOptions(AStream: TStream; AWorksheet: TsBasicWorksheet);
|
||||||
procedure WriteWorksheets(AStream: TStream);
|
procedure WriteWorksheets(AStream: TStream);
|
||||||
|
|
||||||
protected
|
protected
|
||||||
@ -68,7 +68,7 @@ type
|
|||||||
const AValue: double; ACell: PCell); override;
|
const AValue: double; ACell: PCell); override;
|
||||||
|
|
||||||
public
|
public
|
||||||
constructor Create(AWorkbook: TsWorkbook); override;
|
constructor Create(AWorkbook: TsBasicWorkbook); override;
|
||||||
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
|
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
@ -90,7 +90,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
StrUtils, Math,
|
StrUtils, Math,
|
||||||
fpsStrings, fpsUtils, fpsNumFormat, fpsXmlCommon, fpsHTMLUtils;
|
fpsStrings, fpspreadsheet, fpsUtils, fpsNumFormat, fpsXmlCommon, fpsHTMLUtils;
|
||||||
|
|
||||||
const
|
const
|
||||||
FMT_OFFSET = 61;
|
FMT_OFFSET = 61;
|
||||||
@ -164,7 +164,7 @@ end;
|
|||||||
Defines the date mode and the limitations of the file format.
|
Defines the date mode and the limitations of the file format.
|
||||||
Initializes the format settings to be used when writing to xml.
|
Initializes the format settings to be used when writing to xml.
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
constructor TsSpreadExcelXMLWriter.Create(AWorkbook: TsWorkbook);
|
constructor TsSpreadExcelXMLWriter.Create(AWorkbook: TsBasicWorkbook);
|
||||||
begin
|
begin
|
||||||
inherited Create(AWorkbook);
|
inherited Create(AWorkbook);
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ var
|
|||||||
comment: PsComment;
|
comment: PsComment;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
comment := FWorksheet.FindComment(ACell);
|
comment := (FWorksheet as TsWorksheet).FindComment(ACell);
|
||||||
if Assigned(comment) then
|
if Assigned(comment) then
|
||||||
Result := INDENT1 + '<Comment><Data>' + comment^.Text + '</Data></Comment>' + LF + CELL_INDENT;
|
Result := INDENT1 + '<Comment><Data>' + comment^.Text + '</Data></Comment>' + LF + CELL_INDENT;
|
||||||
// If there will be some rich-text-like formatting in the future, use
|
// If there will be some rich-text-like formatting in the future, use
|
||||||
@ -197,40 +197,41 @@ function TsSpreadExcelXMLWriter.GetFormulaStr(ACell: PCell): String;
|
|||||||
begin
|
begin
|
||||||
if HasFormula(ACell) then
|
if HasFormula(ACell) then
|
||||||
begin
|
begin
|
||||||
Result := UTF8TextToXMLText(FWorksheet.ConvertFormulaDialect(ACell, fdExcelR1C1));
|
Result := UTF8TextToXMLText((FWorksheet as TsWorksheet).ConvertFormulaDialect(ACell, fdExcelR1C1));
|
||||||
Result := ' ss:Formula="=' + Result + '"';
|
Result := ' ss:Formula="=' + Result + '"';
|
||||||
end else
|
end else
|
||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSpreadExcelXMLWriter.GetFrozenPanesStr(AWorksheet: TsWorksheet;
|
function TsSpreadExcelXMLWriter.GetFrozenPanesStr(AWorksheet: TsBasicWorksheet;
|
||||||
AIndent: String): String;
|
AIndent: String): String;
|
||||||
var
|
var
|
||||||
activePane: Integer;
|
activePane: Integer;
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
begin
|
begin
|
||||||
if (soHasFrozenPanes in AWorksheet.Options) then
|
if (soHasFrozenPanes in sheet.Options) then
|
||||||
begin
|
begin
|
||||||
Result := AIndent +
|
Result := AIndent +
|
||||||
'<FreezePanes/>' + LF + AIndent +
|
'<FreezePanes/>' + LF + AIndent +
|
||||||
'<FrozenNoSplit/>' + LF;
|
'<FrozenNoSplit/>' + LF;
|
||||||
|
|
||||||
if FWorksheet.LeftPaneWidth > 0 then
|
if sheet.LeftPaneWidth > 0 then
|
||||||
Result := Result + AIndent +
|
Result := Result + AIndent +
|
||||||
'<SplitVertical>1</SplitVertical>' + LF + AIndent +
|
'<SplitVertical>1</SplitVertical>' + LF + AIndent +
|
||||||
'<LeftColumnRightPane>' + IntToStr(FWorksheet.LeftPaneWidth) + '</LeftColumnRightPane>' + LF;
|
'<LeftColumnRightPane>' + IntToStr(sheet.LeftPaneWidth) + '</LeftColumnRightPane>' + LF;
|
||||||
|
|
||||||
if FWorksheet.TopPaneHeight > 0 then
|
if sheet.TopPaneHeight > 0 then
|
||||||
Result := Result + AIndent +
|
Result := Result + AIndent +
|
||||||
'<SplitHorizontal>1</SplitHorizontal>' + LF + AIndent +
|
'<SplitHorizontal>1</SplitHorizontal>' + LF + AIndent +
|
||||||
'<TopRowBottomPane>' + IntToStr(FWorksheet.TopPaneHeight) + '</TopRowBottomPane>' + LF;
|
'<TopRowBottomPane>' + IntToStr(sheet.TopPaneHeight) + '</TopRowBottomPane>' + LF;
|
||||||
|
|
||||||
if (FWorksheet.LeftPaneWidth = 0) and (FWorkSheet.TopPaneHeight = 0) then
|
if (sheet.LeftPaneWidth = 0) and (sheet.TopPaneHeight = 0) then
|
||||||
activePane := 3
|
activePane := 3
|
||||||
else
|
else
|
||||||
if (FWorksheet.LeftPaneWidth = 0) then
|
if (sheet.LeftPaneWidth = 0) then
|
||||||
activePane := 2
|
activePane := 2
|
||||||
else
|
else
|
||||||
if (FWorksheet.TopPaneHeight = 0) then
|
if (sheet.TopPaneHeight = 0) then
|
||||||
activePane := 1
|
activePane := 1
|
||||||
else
|
else
|
||||||
activePane := 0;
|
activePane := 0;
|
||||||
@ -245,7 +246,7 @@ var
|
|||||||
hyperlink: PsHyperlink;
|
hyperlink: PsHyperlink;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
hyperlink := FWorksheet.FindHyperlink(ACell);
|
hyperlink := (FWorksheet as TsWorksheet).FindHyperlink(ACell);
|
||||||
if Assigned(hyperlink) then
|
if Assigned(hyperlink) then
|
||||||
Result := ' ss:HRef="' + hyperlink^.Target + '"';
|
Result := ' ss:HRef="' + hyperlink^.Target + '"';
|
||||||
end;
|
end;
|
||||||
@ -255,17 +256,19 @@ begin
|
|||||||
Result := Format(' ss:Index="%d"', [AIndex]);
|
Result := Format(' ss:Index="%d"', [AIndex]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSpreadExcelXMLWriter.GetLayoutStr(AWorksheet: TsWorksheet): String;
|
function TsSpreadExcelXMLWriter.GetLayoutStr(AWorksheet: TsBasicWorksheet): String;
|
||||||
|
var
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
if AWorksheet.PageLayout.Orientation = spoLandscape then
|
if sheet.PageLayout.Orientation = spoLandscape then
|
||||||
Result := Result + ' x:Orientation="Landscape"';
|
Result := Result + ' x:Orientation="Landscape"';
|
||||||
if (poHorCentered in AWorksheet.PageLayout.Options) then
|
if (poHorCentered in sheet.PageLayout.Options) then
|
||||||
Result := Result + ' x:CenterHorizontal="1"';
|
Result := Result + ' x:CenterHorizontal="1"';
|
||||||
if (poVertCentered in AWorksheet.PageLayout.Options) then
|
if (poVertCentered in sheet.PageLayout.Options) then
|
||||||
Result := Result + ' x:CenterVertical="1"';
|
Result := Result + ' x:CenterVertical="1"';
|
||||||
if (poUseStartPageNumber in AWorksheet.PageLayout.Options) then
|
if (poUseStartPageNumber in sheet.PageLayout.Options) then
|
||||||
Result := Result + ' x:StartPageNumber="' + IntToStr(AWorksheet.PageLayout.StartPageNumber) + '"';
|
Result := Result + ' x:StartPageNumber="' + IntToStr(sheet.PageLayout.StartPageNumber) + '"';
|
||||||
Result := '<Layout' + Result + '/>';
|
Result := '<Layout' + Result + '/>';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -274,8 +277,8 @@ var
|
|||||||
r1, c1, r2, c2: Cardinal;
|
r1, c1, r2, c2: Cardinal;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
if FWorksheet.IsMerged(ACell) then begin
|
if (FWorksheet as TsWorksheet).IsMerged(ACell) then begin
|
||||||
FWorksheet.FindMergedRange(ACell, r1, c1, r2, c2);
|
(FWorksheet as TsWorksheet).FindMergedRange(ACell, r1, c1, r2, c2);
|
||||||
if c2 > c1 then
|
if c2 > c1 then
|
||||||
Result := Result + Format(' ss:MergeAcross="%d"', [c2-c1]);
|
Result := Result + Format(' ss:MergeAcross="%d"', [c2-c1]);
|
||||||
if r2 > r1 then
|
if r2 > r1 then
|
||||||
@ -283,29 +286,38 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSpreadExcelXMLWriter.GetPageFooterStr(AWorksheet: TsWorksheet): String;
|
function TsSpreadExcelXMLWriter.GetPageFooterStr(
|
||||||
|
AWorksheet: TsBasicWorksheet): String;
|
||||||
|
var
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
begin
|
begin
|
||||||
Result := Format('x:Margin="%g"', [mmToIn(AWorksheet.PageLayout.FooterMargin)], FPointSeparatorSettings);
|
Result := Format('x:Margin="%g"', [mmToIn(sheet.PageLayout.FooterMargin)], FPointSeparatorSettings);
|
||||||
if (AWorksheet.PageLayout.Footers[HEADER_FOOTER_INDEX_ALL] <> '') then
|
if (sheet.PageLayout.Footers[HEADER_FOOTER_INDEX_ALL] <> '') then
|
||||||
Result := Result + ' x:Data="' + UTF8TextToXMLText(AWorksheet.PageLayout.Footers[HEADER_FOOTER_INDEX_ALL], true) + '"';
|
Result := Result + ' x:Data="' + UTF8TextToXMLText(sheet.PageLayout.Footers[HEADER_FOOTER_INDEX_ALL], true) + '"';
|
||||||
Result := '<Footer ' + result + '/>';
|
Result := '<Footer ' + result + '/>';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSpreadExcelXMLWriter.GetPageHeaderStr(AWorksheet: TsWorksheet): String;
|
function TsSpreadExcelXMLWriter.GetPageHeaderStr(
|
||||||
|
AWorksheet: TsBasicWorksheet): String;
|
||||||
|
var
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
begin
|
begin
|
||||||
Result := Format('x:Margin="%g"', [mmToIn(AWorksheet.PageLayout.HeaderMargin)], FPointSeparatorSettings);
|
Result := Format('x:Margin="%g"', [mmToIn(sheet.PageLayout.HeaderMargin)], FPointSeparatorSettings);
|
||||||
if (AWorksheet.PageLayout.Headers[HEADER_FOOTER_INDEX_ALL] <> '') then
|
if (sheet.PageLayout.Headers[HEADER_FOOTER_INDEX_ALL] <> '') then
|
||||||
Result := Result + ' x:Data="' + UTF8TextToXMLText(AWorksheet.PageLayout.Headers[HEADER_FOOTER_INDEX_ALL], true) + '"';
|
Result := Result + ' x:Data="' + UTF8TextToXMLText(sheet.PageLayout.Headers[HEADER_FOOTER_INDEX_ALL], true) + '"';
|
||||||
Result := '<Header ' + Result + '/>';
|
Result := '<Header ' + Result + '/>';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TsSpreadExcelXMLWriter.GetPageMarginStr(AWorksheet: TsWorksheet): String;
|
function TsSpreadExcelXMLWriter.GetPageMarginStr(
|
||||||
|
AWorksheet: TsBasicWorksheet): String;
|
||||||
|
var
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
begin
|
begin
|
||||||
Result := Format('x:Bottom="%g" x:Left="%g" x:Right="%g" x:Top="%g"', [
|
Result := Format('x:Bottom="%g" x:Left="%g" x:Right="%g" x:Top="%g"', [
|
||||||
mmToIn(AWorksheet.PageLayout.BottomMargin),
|
mmToIn(sheet.PageLayout.BottomMargin),
|
||||||
mmToIn(AWorksheet.PageLayout.LeftMargin),
|
mmToIn(sheet.PageLayout.LeftMargin),
|
||||||
mmToIn(AWorksheet.PageLayout.RightMargin),
|
mmToIn(sheet.PageLayout.RightMargin),
|
||||||
mmToIn(AWorksheet.PageLayout.TopMargin)
|
mmToIn(sheet.PageLayout.TopMargin)
|
||||||
], FPointSeparatorSettings);
|
], FPointSeparatorSettings);
|
||||||
Result := '<PageMargins ' + Result + '/>';
|
Result := '<PageMargins ' + Result + '/>';
|
||||||
end;
|
end;
|
||||||
@ -366,7 +378,7 @@ begin
|
|||||||
WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue, ACell);
|
WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.UTF8StringValue, ACell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FWorksheet.ReadComment(ACell) <> '' then
|
if (FWorksheet as TsWorksheet).ReadComment(ACell) <> '' then
|
||||||
WriteComment(AStream, ACell);
|
WriteComment(AStream, ACell);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -380,11 +392,11 @@ var
|
|||||||
begin
|
begin
|
||||||
Unused(ARow, ACol);
|
Unused(ARow, ACol);
|
||||||
ExcelDate := AValue;
|
ExcelDate := AValue;
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(ACell^.FormatIndex);
|
fmt := (FWorkbook as TsWorkbook).GetPointerToCellFormat(ACell^.FormatIndex);
|
||||||
// Times have an offset of 1 day!
|
// Times have an offset of 1 day!
|
||||||
if (fmt <> nil) and (uffNumberFormat in fmt^.UsedFormattingFields) then
|
if (fmt <> nil) and (uffNumberFormat in fmt^.UsedFormattingFields) then
|
||||||
begin
|
begin
|
||||||
nfp := FWorkbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
nfp := (FWorkbook as TsWorkbook).GetNumberFormat(fmt^.NumberFormatIndex);
|
||||||
if IsTimeIntervalFormat(nfp) or IsTimeFormat(nfp) then
|
if IsTimeIntervalFormat(nfp) or IsTimeFormat(nfp) then
|
||||||
case FDateMode of
|
case FDateMode of
|
||||||
dm1900: ExcelDate := AValue + DATEMODE_1900_BASE;
|
dm1900: ExcelDate := AValue + DATEMODE_1900_BASE;
|
||||||
@ -461,8 +473,8 @@ begin
|
|||||||
if Length(ACell^.RichTextParams) > 0 then
|
if Length(ACell^.RichTextParams) > 0 then
|
||||||
begin
|
begin
|
||||||
RichTextToHTML(
|
RichTextToHTML(
|
||||||
FWorkbook,
|
FWorkbook as TsWorkbook,
|
||||||
FWorksheet.ReadCellFont(ACell),
|
(FWorksheet as TsWorksheet).ReadCellFont(ACell),
|
||||||
AValue,
|
AValue,
|
||||||
ACell^.RichTextParams,
|
ACell^.RichTextParams,
|
||||||
valueStr, // html-formatted rich text
|
valueStr, // html-formatted rich text
|
||||||
@ -531,8 +543,10 @@ var
|
|||||||
fill: TsFillPattern;
|
fill: TsFillPattern;
|
||||||
cb: TsCellBorder;
|
cb: TsCellBorder;
|
||||||
cbs: TsCellBorderStyle;
|
cbs: TsCellBorderStyle;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
deffnt := FWorkbook.GetDefaultFont;
|
book := FWorkbook as TsWorkbook;
|
||||||
|
deffnt := book.GetDefaultFont;
|
||||||
if AIndex = 0 then
|
if AIndex = 0 then
|
||||||
begin
|
begin
|
||||||
AppendToStream(AStream, Format(INDENT2 +
|
AppendToStream(AStream, Format(INDENT2 +
|
||||||
@ -551,7 +565,7 @@ begin
|
|||||||
AppendToStream(AStream, Format(INDENT2 +
|
AppendToStream(AStream, Format(INDENT2 +
|
||||||
'<Style ss:ID="s%d">' + LF, [AIndex + FMT_OFFSET]));
|
'<Style ss:ID="s%d">' + LF, [AIndex + FMT_OFFSET]));
|
||||||
|
|
||||||
fmt := FWorkbook.GetPointerToCellFormat(AIndex);
|
fmt := book.GetPointerToCellFormat(AIndex);
|
||||||
|
|
||||||
// Horizontal alignment
|
// Horizontal alignment
|
||||||
fmtHor := '';
|
fmtHor := '';
|
||||||
@ -600,7 +614,7 @@ begin
|
|||||||
// Font
|
// Font
|
||||||
if (uffFont in fmt^.UsedFormattingFields) then
|
if (uffFont in fmt^.UsedFormattingFields) then
|
||||||
begin
|
begin
|
||||||
fnt := FWorkbook.GetFont(fmt^.FontIndex);
|
fnt := book.GetFont(fmt^.FontIndex);
|
||||||
s := '';
|
s := '';
|
||||||
if fnt.FontName <> deffnt.FontName then
|
if fnt.FontName <> deffnt.FontName then
|
||||||
s := s + Format('ss:FontName="%s" ', [fnt.FontName]);
|
s := s + Format('ss:FontName="%s" ', [fnt.FontName]);
|
||||||
@ -624,7 +638,7 @@ begin
|
|||||||
// Number Format
|
// Number Format
|
||||||
if (uffNumberFormat in fmt^.UsedFormattingFields) then
|
if (uffNumberFormat in fmt^.UsedFormattingFields) then
|
||||||
begin
|
begin
|
||||||
nfp := FWorkbook.GetNumberFormat(fmt^.NumberFormatIndex);
|
nfp := book.GetNumberFormat(fmt^.NumberFormatIndex);
|
||||||
AppendToStream(AStream, Format(INDENT3 +
|
AppendToStream(AStream, Format(INDENT3 +
|
||||||
'<NumberFormat ss:Format="%s"/>' + LF, [UTF8TextToXMLText(nfp.NumFormatStr)]));
|
'<NumberFormat ss:Format="%s"/>' + LF, [UTF8TextToXMLText(nfp.NumFormatStr)]));
|
||||||
end;
|
end;
|
||||||
@ -685,12 +699,14 @@ var
|
|||||||
begin
|
begin
|
||||||
AppendToStream(AStream, INDENT1 +
|
AppendToStream(AStream, INDENT1 +
|
||||||
'<Styles>' + LF);
|
'<Styles>' + LF);
|
||||||
for i:=0 to FWorkbook.GetNumCellFormats-1 do WriteStyle(AStream, i);
|
for i:=0 to (FWorkbook as TsWorkbook).GetNumCellFormats-1 do
|
||||||
|
WriteStyle(AStream, i);
|
||||||
AppendToStream(AStream, INDENT1 +
|
AppendToStream(AStream, INDENT1 +
|
||||||
'</Styles>' + LF);
|
'</Styles>' + LF);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadExcelXMLWriter.WriteTable(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure TsSpreadExcelXMLWriter.WriteTable(AStream: TStream;
|
||||||
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
c, c1, c2: Cardinal;
|
c, c1, c2: Cardinal;
|
||||||
r, r1, r2: Cardinal;
|
r, r1, r2: Cardinal;
|
||||||
@ -700,27 +716,28 @@ var
|
|||||||
styleStr: String;
|
styleStr: String;
|
||||||
col: PCol;
|
col: PCol;
|
||||||
row: PRow;
|
row: PRow;
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
begin
|
begin
|
||||||
r1 := 0;
|
r1 := 0;
|
||||||
c1 := 0;
|
c1 := 0;
|
||||||
r2 := AWorksheet.GetLastRowIndex;
|
r2 := sheet.GetLastRowIndex;
|
||||||
c2 := AWorksheet.GetLastColIndex;
|
c2 := sheet.GetLastColIndex;
|
||||||
AppendToStream(AStream, TABLE_INDENT + Format(
|
AppendToStream(AStream, TABLE_INDENT + Format(
|
||||||
'<Table ss:ExpandedColumnCount="%d" ss:ExpandedRowCount="%d" ' +
|
'<Table ss:ExpandedColumnCount="%d" ss:ExpandedRowCount="%d" ' +
|
||||||
'x:FullColumns="1" x:FullRows="1" ' +
|
'x:FullColumns="1" x:FullRows="1" ' +
|
||||||
'ss:DefaultColumnWidth="%.2f" ' +
|
'ss:DefaultColumnWidth="%.2f" ' +
|
||||||
'ss:DefaultRowHeight="%.2f">' + LF,
|
'ss:DefaultRowHeight="%.2f">' + LF,
|
||||||
[
|
[
|
||||||
AWorksheet.GetLastColIndex + 1, AWorksheet.GetLastRowIndex + 1,
|
sheet.GetLastColIndex + 1, sheet.GetLastRowIndex + 1,
|
||||||
AWorksheet.ReadDefaultColWidth(suPoints),
|
sheet.ReadDefaultColWidth(suPoints),
|
||||||
AWorksheet.ReadDefaultRowHeight(suPoints)
|
sheet.ReadDefaultRowHeight(suPoints)
|
||||||
],
|
],
|
||||||
FPointSeparatorSettings
|
FPointSeparatorSettings
|
||||||
));
|
));
|
||||||
|
|
||||||
for c := c1 to c2 do
|
for c := c1 to c2 do
|
||||||
begin
|
begin
|
||||||
col := FWorksheet.FindCol(c);
|
col := sheet.FindCol(c);
|
||||||
styleStr := '';
|
styleStr := '';
|
||||||
colWidthStr := '';
|
colWidthStr := '';
|
||||||
if Assigned(col) then
|
if Assigned(col) then
|
||||||
@ -728,7 +745,7 @@ begin
|
|||||||
// column width is needed in pts.
|
// column width is needed in pts.
|
||||||
if col^.ColWidthType = cwtCustom then
|
if col^.ColWidthType = cwtCustom then
|
||||||
colwidthStr := Format(' ss:Width="%0.2f" ss:AutoFitWidth="0"',
|
colwidthStr := Format(' ss:Width="%0.2f" ss:AutoFitWidth="0"',
|
||||||
[FWorkbook.ConvertUnits(col^.Width, FWorkbook.Units, suPoints)],
|
[(FWorkbook as TsWorkbook).ConvertUnits(col^.Width, FWorkbook.Units, suPoints)],
|
||||||
FPointSeparatorSettings);
|
FPointSeparatorSettings);
|
||||||
// column style
|
// column style
|
||||||
if col^.FormatIndex > 0 then
|
if col^.FormatIndex > 0 then
|
||||||
@ -740,13 +757,13 @@ begin
|
|||||||
|
|
||||||
for r := r1 to r2 do
|
for r := r1 to r2 do
|
||||||
begin
|
begin
|
||||||
row := FWorksheet.FindRow(r);
|
row := sheet.FindRow(r);
|
||||||
styleStr := '';
|
styleStr := '';
|
||||||
// Row height is needed in pts.
|
// Row height is needed in pts.
|
||||||
if Assigned(row) then
|
if Assigned(row) then
|
||||||
begin
|
begin
|
||||||
rowheightStr := Format(' ss:Height="%.2f"',
|
rowheightStr := Format(' ss:Height="%.2f"',
|
||||||
[FWorkbook.ConvertUnits(row^.Height, FWorkbook.Units, suPoints)],
|
[(FWorkbook as TsWorkbook).ConvertUnits(row^.Height, FWorkbook.Units, suPoints)],
|
||||||
FPointSeparatorSettings
|
FPointSeparatorSettings
|
||||||
);
|
);
|
||||||
if row^.RowHeightType = rhtCustom then
|
if row^.RowHeightType = rhtCustom then
|
||||||
@ -760,10 +777,10 @@ begin
|
|||||||
'<Row %s%s>' + LF, [rowheightStr, styleStr]));
|
'<Row %s%s>' + LF, [rowheightStr, styleStr]));
|
||||||
for c := c1 to c2 do
|
for c := c1 to c2 do
|
||||||
begin
|
begin
|
||||||
cell := AWorksheet.FindCell(r, c);
|
cell := sheet.FindCell(r, c);
|
||||||
if cell <> nil then
|
if cell <> nil then
|
||||||
begin
|
begin
|
||||||
if FWorksheet.IsMerged(cell) and not FWorksheet.IsMergeBase(cell) then
|
if sheet.IsMerged(cell) and not sheet.IsMergeBase(cell) then
|
||||||
Continue;
|
Continue;
|
||||||
WriteCellToStream(AStream, cell);
|
WriteCellToStream(AStream, cell);
|
||||||
end;
|
end;
|
||||||
@ -804,7 +821,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadExcelXMLWriter.WriteWorksheet(AStream: TStream;
|
procedure TsSpreadExcelXMLWriter.WriteWorksheet(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
protectedStr: String;
|
protectedStr: String;
|
||||||
begin
|
begin
|
||||||
@ -827,7 +844,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsSpreadExcelXMLWriter.WriteWorksheetOptions(AStream: TStream;
|
procedure TsSpreadExcelXMLWriter.WriteWorksheetOptions(AStream: TStream;
|
||||||
AWorksheet: TsWorksheet);
|
AWorksheet: TsBasicWorksheet);
|
||||||
var
|
var
|
||||||
footerStr, headerStr: String;
|
footerStr, headerStr: String;
|
||||||
hideGridStr: String;
|
hideGridStr: String;
|
||||||
@ -837,6 +854,7 @@ var
|
|||||||
marginStr: String;
|
marginStr: String;
|
||||||
selectedStr: String;
|
selectedStr: String;
|
||||||
protectStr: String;
|
protectStr: String;
|
||||||
|
sheet: TsWorksheet absolute AWorksheet;
|
||||||
begin
|
begin
|
||||||
// Orientation, some PageLayout.Options
|
// Orientation, some PageLayout.Options
|
||||||
layoutStr := GetLayoutStr(AWorksheet);
|
layoutStr := GetLayoutStr(AWorksheet);
|
||||||
@ -864,7 +882,7 @@ begin
|
|||||||
hideHeadersStr := INDENT3 + '<DoNotDisplayHeadings/>' + LF else
|
hideHeadersStr := INDENT3 + '<DoNotDisplayHeadings/>' + LF else
|
||||||
hideHeadersStr := '';
|
hideHeadersStr := '';
|
||||||
|
|
||||||
if FWorkbook.ActiveWorksheet = AWorksheet then
|
if (FWorkbook as TsWorkbook).ActiveWorksheet = AWorksheet then
|
||||||
selectedStr := INDENT3 + '<Selected/>' + LF else
|
selectedStr := INDENT3 + '<Selected/>' + LF else
|
||||||
selectedStr := '';
|
selectedStr := '';
|
||||||
|
|
||||||
@ -899,9 +917,11 @@ end;
|
|||||||
procedure TsSpreadExcelXMLWriter.WriteWorksheets(AStream: TStream);
|
procedure TsSpreadExcelXMLWriter.WriteWorksheets(AStream: TStream);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
book: TsWorkbook;
|
||||||
begin
|
begin
|
||||||
for i:=0 to FWorkbook.GetWorksheetCount-1 do
|
book := FWorkbook as TsWorkbook;
|
||||||
WriteWorksheet(AStream, FWorkbook.GetWorksheetByIndex(i));
|
for i:=0 to book.GetWorksheetCount-1 do
|
||||||
|
WriteWorksheet(AStream, book.GetWorksheetByIndex(i));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user