You've already forked lazarus-ccr
fpspreadsheet:
- Move BasicReader/Writer from fpspreadsheet.pas to fpsReaderWriter.pas in order to fix circular unit dependence introduced in prev commit. - Remove usage of temp file in xlsx and ods stream writers (see forum forum.lazarus.freepascal.org/index.php/topic,30606.msg194818.html). git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4398 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -3703,7 +3703,7 @@ begin
|
|||||||
{ Now compress the files }
|
{ Now compress the files }
|
||||||
FZip := TZipper.Create;
|
FZip := TZipper.Create;
|
||||||
try
|
try
|
||||||
FZip.FileName := '__temp__.tmp';
|
// FZip.FileName := '__temp__.tmp';
|
||||||
|
|
||||||
FZip.Entries.AddFileEntry(FSMeta, OPENDOC_PATH_META);
|
FZip.Entries.AddFileEntry(FSMeta, OPENDOC_PATH_META);
|
||||||
FZip.Entries.AddFileEntry(FSSettings, OPENDOC_PATH_SETTINGS);
|
FZip.Entries.AddFileEntry(FSSettings, OPENDOC_PATH_SETTINGS);
|
||||||
|
@ -40,8 +40,6 @@ type
|
|||||||
{ Forward declarations }
|
{ Forward declarations }
|
||||||
TsWorksheet = class;
|
TsWorksheet = class;
|
||||||
TsWorkbook = class;
|
TsWorkbook = class;
|
||||||
TsBasicSpreadReader = class;
|
|
||||||
TsBasicSpreadWriter = class;
|
|
||||||
|
|
||||||
{**
|
{**
|
||||||
Type: TRow -- record containing information about a spreadsheet row
|
Type: TRow -- record containing information about a spreadsheet row
|
||||||
@ -637,17 +635,11 @@ type
|
|||||||
FCellFormatList: TsCellFormatList;
|
FCellFormatList: TsCellFormatList;
|
||||||
|
|
||||||
{ Internal methods }
|
{ Internal methods }
|
||||||
function CreateSpreadReader(AFormatID: TsSpreadFormatID;
|
|
||||||
AParams: TsStreamParams = []): TsBasicSpreadReader;
|
|
||||||
function CreateSpreadWriter(AFormatID: TsSpreadFormatID;
|
|
||||||
AParams: TsStreamParams = []): TsBasicSpreadWriter;
|
|
||||||
|
|
||||||
class function GetFormatFromFileHeader(const AFileName: TFileName;
|
class function GetFormatFromFileHeader(const AFileName: TFileName;
|
||||||
out AFormatID: TsSpreadFormatID): Boolean; overload;
|
out AFormatID: TsSpreadFormatID): Boolean; overload;
|
||||||
class function GetFormatFromFileHeader(AStream: TStream;
|
class function GetFormatFromFileHeader(AStream: TStream;
|
||||||
out AFormatID: TsSpreadFormatID): Boolean; overload;
|
out AFormatID: TsSpreadFormatID): Boolean; overload;
|
||||||
|
|
||||||
procedure GetLastRowColIndex(out ALastRow, ALastCol: Cardinal);
|
|
||||||
procedure PrepareBeforeReading;
|
procedure PrepareBeforeReading;
|
||||||
procedure PrepareBeforeSaving;
|
procedure PrepareBeforeSaving;
|
||||||
procedure ReCalc;
|
procedure ReCalc;
|
||||||
@ -775,6 +767,7 @@ type
|
|||||||
procedure EnableNotifications;
|
procedure EnableNotifications;
|
||||||
function NotificationsEnabled: Boolean;
|
function NotificationsEnabled: Boolean;
|
||||||
procedure UpdateCaches;
|
procedure UpdateCaches;
|
||||||
|
procedure GetLastRowColIndex(out ALastRow, ALastCol: Cardinal);
|
||||||
|
|
||||||
{ Error messages }
|
{ Error messages }
|
||||||
procedure AddErrorMsg(const AMsg: String); overload;
|
procedure AddErrorMsg(const AMsg: String); overload;
|
||||||
@ -819,49 +812,6 @@ type
|
|||||||
property OnReadCellData: TsWorkbookReadCellDataEvent read FOnReadCellData write FOnReadCellData;
|
property OnReadCellData: TsWorkbookReadCellDataEvent read FOnReadCellData write FOnReadCellData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TsBasicSpreadReaderWriter }
|
|
||||||
TsBasicSpreadReaderWriter = class
|
|
||||||
protected
|
|
||||||
{@@ Instance of the workbook which is currently being read or written. }
|
|
||||||
FWorkbook: TsWorkbook;
|
|
||||||
{@@ Instance of the worksheet which is currently being read or written. }
|
|
||||||
FWorksheet: TsWorksheet;
|
|
||||||
{@@ Limitations for the specific data file format }
|
|
||||||
FLimitations: TsSpreadsheetFormatLimitations;
|
|
||||||
public
|
|
||||||
constructor Create(AWorkbook: TsWorkbook); virtual; // to allow descendents to override it
|
|
||||||
function Limitations: TsSpreadsheetFormatLimitations;
|
|
||||||
{@@ Instance of the workbook which is currently being read/written. }
|
|
||||||
property Workbook: TsWorkbook read FWorkbook;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TsBasicSpreadReader }
|
|
||||||
TsBasicSpreadReader = class(TsBasicSpreadReaderWriter)
|
|
||||||
public
|
|
||||||
{ General writing methods }
|
|
||||||
procedure ReadFromFile(AFileName: string; AParams: TsStreamParams = []); virtual; abstract;
|
|
||||||
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); virtual; abstract;
|
|
||||||
procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); virtual; abstract;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TsBasicSpreadWriter }
|
|
||||||
TsBasicSpreadWriter = class(TsBasicSpreadReaderWriter)
|
|
||||||
public
|
|
||||||
{ Helpers }
|
|
||||||
procedure CheckLimitations; virtual;
|
|
||||||
{ General writing methods }
|
|
||||||
procedure WriteToFile(const AFileName: string;
|
|
||||||
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); virtual; abstract;
|
|
||||||
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); virtual; abstract;
|
|
||||||
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); virtual; abstract;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ TsSpreadReader class reference type }
|
|
||||||
TsSpreadReaderClass = class of TsBasicSpreadReader;
|
|
||||||
|
|
||||||
{@@ TsSpreadWriter class reference type }
|
|
||||||
TsSpreadWriterClass = class of TsBasicSpreadWriter;
|
|
||||||
|
|
||||||
procedure CopyCellFormat(AFromCell, AToCell: PCell);
|
procedure CopyCellFormat(AFromCell, AToCell: PCell);
|
||||||
|
|
||||||
|
|
||||||
@ -870,7 +820,7 @@ implementation
|
|||||||
uses
|
uses
|
||||||
Math, StrUtils, DateUtils, TypInfo, lazutf8, lazFileUtils, URIParser,
|
Math, StrUtils, DateUtils, TypInfo, lazutf8, lazFileUtils, URIParser,
|
||||||
fpsStrings, uvirtuallayer_ole,
|
fpsStrings, uvirtuallayer_ole,
|
||||||
fpsUtils, fpsHTMLUtils, fpsRegFileFormats, fpsreaderwriter,
|
fpsUtils, fpsHTMLUtils, fpsRegFileFormats, fpsReaderWriter,
|
||||||
fpsCurrency, fpsExprParser, fpsNumFormatParser;
|
fpsCurrency, fpsExprParser, fpsNumFormatParser;
|
||||||
|
|
||||||
(*
|
(*
|
||||||
@ -906,6 +856,67 @@ const
|
|||||||
DEF_FONT_AUTOMATIC_COLORVALUE = $000000;
|
DEF_FONT_AUTOMATIC_COLORVALUE = $000000;
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Convenience method which creates the correct reader object for a given
|
||||||
|
spreadsheet format.
|
||||||
|
|
||||||
|
@param AWorkbook Workbook to be written
|
||||||
|
@param AFormatID Identifier of the file format which is assumed when reading
|
||||||
|
a document into the workbook. An exception is raised when
|
||||||
|
the document has a different format.
|
||||||
|
|
||||||
|
@param AParams Optional parameters to control stream access. If contains
|
||||||
|
the element spClipboard the reader knows that access is to
|
||||||
|
the clipboard, and it can read a special clipboard version
|
||||||
|
of the data.
|
||||||
|
|
||||||
|
@return An instance of a TsBasicSpreadReader descendent which is able to
|
||||||
|
read the given file format.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function CreateSpreadReader(AWorkbook: TsWorkbook; AFormatID: TsSpreadFormatID;
|
||||||
|
AParams: TsStreamParams = []): TsBasicSpreadReader;
|
||||||
|
var
|
||||||
|
readerClass: TsSpreadReaderClass;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
readerClass := GetSpreadReaderClass(AFormatID);
|
||||||
|
|
||||||
|
if readerClass <> nil
|
||||||
|
then Result := readerClass.Create(AWorkbook);
|
||||||
|
|
||||||
|
if Result = nil then
|
||||||
|
raise Exception.Create(rsUnsupportedReadFormat);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Convenience method which creates the correct writer object for a given
|
||||||
|
spreadsheet format.
|
||||||
|
|
||||||
|
@param AWorkbook Workbook to be written
|
||||||
|
@param AFormatID Identifier of the file format which is used for writing the
|
||||||
|
workbook
|
||||||
|
@param AParams Optional parameters to control stream access. If contains
|
||||||
|
the element spClipboard then the writer can write a
|
||||||
|
dedicated clipboard version of the stream if required.
|
||||||
|
@return An instance of a TsBasicSpreadWriter descendant which is able to
|
||||||
|
write the given file format.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
|
||||||
|
function CreateSpreadWriter(AWorkbook: TsWorkbook; AFormatID: TsSpreadFormatID;
|
||||||
|
AParams: TsStreamParams = []): TsBasicSpreadWriter;
|
||||||
|
var
|
||||||
|
writerClass: TsSpreadWriterClass;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
writerClass := GetSpreadWriterClass(AFormatID);
|
||||||
|
|
||||||
|
if writerClass <> nil then
|
||||||
|
Result := writerClass.Create(AWorkbook);
|
||||||
|
|
||||||
|
if Result = nil then
|
||||||
|
raise Exception.Create(rsUnsupportedWriteFormat);
|
||||||
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Copies the format of a cell to another one.
|
Copies the format of a cell to another one.
|
||||||
|
|
||||||
@ -6640,65 +6651,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Convenience method which creates the correct reader object for a given
|
|
||||||
spreadsheet format.
|
|
||||||
|
|
||||||
@param AFormatID Identifier of the file format which is assumed when reading
|
|
||||||
a document into the workbook. An exception is raised when
|
|
||||||
the document has a different format.
|
|
||||||
|
|
||||||
@param AParams Optional parameters to control stream access. If contains
|
|
||||||
the element spClipboard the reader knows that access is to
|
|
||||||
the clipboard, and it can read a special clipboard version
|
|
||||||
of the data.
|
|
||||||
|
|
||||||
@return An instance of a TsCustomSpreadReader descendent which is able to
|
|
||||||
read the given file format.
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function TsWorkbook.CreateSpreadReader(AFormatID: TsSpreadFormatID;
|
|
||||||
AParams: TsStreamParams = []): TsBasicSpreadReader;
|
|
||||||
var
|
|
||||||
readerClass: TsSpreadReaderClass;
|
|
||||||
begin
|
|
||||||
Result := nil;
|
|
||||||
readerClass := GetSpreadReaderClass(AFormatID);
|
|
||||||
|
|
||||||
if readerClass <> nil
|
|
||||||
then Result := readerClass.Create(self);
|
|
||||||
|
|
||||||
if Result = nil then
|
|
||||||
raise Exception.Create(rsUnsupportedReadFormat);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Convenience method which creates the correct writer object for a given
|
|
||||||
spreadsheet format.
|
|
||||||
|
|
||||||
@param AFormatID Identifier of the file format which is used for writing the
|
|
||||||
workbook
|
|
||||||
@param AParams Optional parameters to control stream access. If contains
|
|
||||||
the element spClipboard then the writer can write a
|
|
||||||
dedicated clipboard version of the stream if required.
|
|
||||||
|
|
||||||
@return An instance of a TsCustomSpreadWriter descendent which is able to
|
|
||||||
write the given file format.
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function TsWorkbook.CreateSpreadWriter(AFormatID: TsSpreadFormatID;
|
|
||||||
AParams: TsStreamParams): TsBasicSpreadWriter;
|
|
||||||
var
|
|
||||||
writerClass: TsSpreadWriterClass;
|
|
||||||
begin
|
|
||||||
Result := nil;
|
|
||||||
writerClass := GetSpreadWriterClass(AFormatID);
|
|
||||||
|
|
||||||
if writerClass <> nil then
|
|
||||||
Result := writerClass.Create(self);
|
|
||||||
|
|
||||||
if Result = nil then
|
|
||||||
raise Exception.Create(rsUnsupportedWriteFormat);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Determines the maximum index of used columns and rows in all sheets of this
|
Determines the maximum index of used columns and rows in all sheets of this
|
||||||
workbook. Respects VirtualMode.
|
workbook. Respects VirtualMode.
|
||||||
@ -6761,7 +6713,7 @@ begin
|
|||||||
if not FileExists(AFileName) then
|
if not FileExists(AFileName) then
|
||||||
raise Exception.CreateFmt(rsFileNotFound, [AFileName]);
|
raise Exception.CreateFmt(rsFileNotFound, [AFileName]);
|
||||||
|
|
||||||
AReader := CreateSpreadReader(AFormatID);
|
AReader := CreateSpreadReader(self, AFormatID);
|
||||||
try
|
try
|
||||||
FFileName := AFileName;
|
FFileName := AFileName;
|
||||||
PrepareBeforeReading;
|
PrepareBeforeReading;
|
||||||
@ -6842,119 +6794,6 @@ begin
|
|||||||
if not success then
|
if not success then
|
||||||
raise Exception.CreateFmt(rsNoValidSpreadsheetFile, [AFileName]);
|
raise Exception.CreateFmt(rsNoValidSpreadsheetFile, [AFileName]);
|
||||||
end;
|
end;
|
||||||
(*
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
on E: Exception do
|
|
||||||
begin
|
|
||||||
|
|
||||||
while True do
|
|
||||||
begin
|
|
||||||
try
|
|
||||||
ReadFromFile(AFileName, SheetType, AParams);
|
|
||||||
canLoad := True;
|
|
||||||
except
|
|
||||||
on E: Exception do
|
|
||||||
begin
|
|
||||||
if SheetType = _sfExcel8 then lException := E;
|
|
||||||
canLoad := False
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
if canLoad or (SheetType = _sfExcel2) then Break;
|
|
||||||
SheetType := Pred(SheetType);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// A failed attempt to read a file should bring an exception, so re-raise
|
|
||||||
// the exception if necessary. We re-raise the exception brought by Excel 8,
|
|
||||||
// since this is the most common format
|
|
||||||
if (not canLoad) and (lException <> nil) then raise lException;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
ReadFromFile(AFileName, SheetType, AParams);
|
|
||||||
end else
|
|
||||||
raise Exception.CreateFmt(rsNoValidSpreadsheetFile, [AFileName]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for i:=0 to High(fileformats) do
|
|
||||||
// .xls files can contain several formats. We look into the header first.
|
|
||||||
if ext = STR_EXCEL_EXTENSION then
|
|
||||||
begin
|
|
||||||
canLoad := GetFormatFromFileHeader(AFileName, SheetType);
|
|
||||||
if canLoad then begin
|
|
||||||
// Rearrange the file format list such that the format detected from the
|
|
||||||
// header is first. Must probably the other file formats are not needed,
|
|
||||||
// just to make sure...
|
|
||||||
xlsformats := GetSpreadFormatsFromFileName(AFileName, 'BIFF8');
|
|
||||||
SetLength(fileFormats, Length(xlsformats)+1);
|
|
||||||
fileFormats[0] := sheetType;
|
|
||||||
n := 1;
|
|
||||||
for i := 0 to High(xlsformats) do
|
|
||||||
if xlsformats[i] <> sheetType then
|
|
||||||
begin
|
|
||||||
fileFormats[n] := xlsformats[i];
|
|
||||||
inc(n);
|
|
||||||
end;
|
|
||||||
SetLength(fileformats, n);
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
// In this case the file format could not be identified from the header.
|
|
||||||
// But it is possible that this method fails for valid xls files.
|
|
||||||
// Therefore we open the file explicitly by trial and error using each
|
|
||||||
// xls reader - see below. We begin with BIFF8 which is most often used.
|
|
||||||
// Therefore, we read the file format list with BIFF8 at the first item.
|
|
||||||
fileformats := GetSpreadFormatsFromFileName(AFileName, 'BIFF8');
|
|
||||||
SheetType := fileFormats[0];
|
|
||||||
canLoad := true;
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
SheetType := fileFormats[0];
|
|
||||||
canLoad := (Length(fileFormats) > 0);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if not canLoad then
|
|
||||||
raise Exception.CreateFmt(rsReaderNotFound, [AFileName]);
|
|
||||||
|
|
||||||
// Here is the trial and error loop checking the file formats with the same extension
|
|
||||||
for sf := 0 to High(fileFormats) do begin
|
|
||||||
try
|
|
||||||
ReadFromFile
|
|
||||||
|
|
||||||
if canLoad then
|
|
||||||
begin
|
|
||||||
if SheetType = _sfExcel8 then
|
|
||||||
begin
|
|
||||||
// Here is the trial-and-error loop checking for the various biff formats.
|
|
||||||
while True do
|
|
||||||
begin
|
|
||||||
try
|
|
||||||
ReadFromFile(AFileName, SheetType, AParams);
|
|
||||||
canLoad := True;
|
|
||||||
except
|
|
||||||
on E: Exception do
|
|
||||||
begin
|
|
||||||
if SheetType = _sfExcel8 then lException := E;
|
|
||||||
canLoad := False
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
if canLoad or (SheetType = _sfExcel2) then Break;
|
|
||||||
SheetType := Pred(SheetType);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// A failed attempt to read a file should bring an exception, so re-raise
|
|
||||||
// the exception if necessary. We re-raise the exception brought by Excel 8,
|
|
||||||
// since this is the most common format
|
|
||||||
if (not canLoad) and (lException <> nil) then raise lException;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
ReadFromFile(AFileName, SheetType, AParams);
|
|
||||||
end else
|
|
||||||
raise Exception.CreateFmt(rsNoValidSpreadsheetFile, [AFileName]);
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Reads the document from a file, but ignores the extension.
|
Reads the document from a file, but ignores the extension.
|
||||||
@ -7008,7 +6847,7 @@ var
|
|||||||
AReader: TsBasicSpreadReader;
|
AReader: TsBasicSpreadReader;
|
||||||
ok: Boolean;
|
ok: Boolean;
|
||||||
begin
|
begin
|
||||||
AReader := CreateSpreadReader(AFormatID);
|
AReader := CreateSpreadReader(self, AFormatID);
|
||||||
try
|
try
|
||||||
PrepareBeforeReading;
|
PrepareBeforeReading;
|
||||||
FReadWriteFlag := rwfRead;
|
FReadWriteFlag := rwfRead;
|
||||||
@ -7082,7 +6921,7 @@ procedure TsWorkbook.WriteToFile(const AFileName: string;
|
|||||||
var
|
var
|
||||||
AWriter: TsBasicSpreadWriter;
|
AWriter: TsBasicSpreadWriter;
|
||||||
begin
|
begin
|
||||||
AWriter := CreateSpreadWriter(AFormatID);
|
AWriter := CreateSpreadWriter(self, AFormatID);
|
||||||
try
|
try
|
||||||
FFileName := AFileName;
|
FFileName := AFileName;
|
||||||
FFormatID := AFormatID;
|
FFormatID := AFormatID;
|
||||||
@ -7164,7 +7003,7 @@ procedure TsWorkbook.WriteToStream(AStream: TStream;
|
|||||||
var
|
var
|
||||||
AWriter: TsBasicSpreadWriter;
|
AWriter: TsBasicSpreadWriter;
|
||||||
begin
|
begin
|
||||||
AWriter := CreateSpreadWriter(AFormatID, AParams);
|
AWriter := CreateSpreadWriter(self, AFormatID, AParams);
|
||||||
try
|
try
|
||||||
FFormatID := AFormatID;
|
FFormatID := AFormatID;
|
||||||
PrepareBeforeSaving;
|
PrepareBeforeSaving;
|
||||||
@ -8437,58 +8276,4 @@ begin
|
|||||||
end;
|
end;
|
||||||
*)
|
*)
|
||||||
|
|
||||||
{------------------------------------------------------------------------------}
|
|
||||||
{ TsBasicSpreadReaderWriter }
|
|
||||||
{------------------------------------------------------------------------------}
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Constructor of the reader/writer. Has the workbook to be read/written as a
|
|
||||||
parameter to apply the localization information found in its FormatSettings.
|
|
||||||
|
|
||||||
@param AWorkbook Workbook into which the file is being read or from with the
|
|
||||||
file is written. This parameter is passed from the workbook
|
|
||||||
which creates the reader/writer.
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
constructor TsBasicSpreadReaderWriter.Create(AWorkbook: TsWorkbook);
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
FWorkbook := AWorkbook;
|
|
||||||
{ A good starting point valid for many formats ... }
|
|
||||||
FLimitations.MaxColCount := 256;
|
|
||||||
FLimitations.MaxRowCount := 65536;
|
|
||||||
FLimitations.MaxPaletteSize := MaxInt;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Returns a record containing limitations of the specific file format of the
|
|
||||||
writer.
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function TsBasicSpreadReaderWriter.Limitations: TsSpreadsheetFormatLimitations;
|
|
||||||
begin
|
|
||||||
Result := FLimitations;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------}
|
|
||||||
{ TsBasicSpreadWriter }
|
|
||||||
{------------------------------------------------------------------------------}
|
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
Checks limitations of the writer, e.g max row/column count
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
procedure TsBasicSpreadWriter.CheckLimitations;
|
|
||||||
var
|
|
||||||
lastCol, lastRow: Cardinal;
|
|
||||||
begin
|
|
||||||
Workbook.GetLastRowColIndex(lastRow, lastCol);
|
|
||||||
|
|
||||||
// Check row count
|
|
||||||
if lastRow >= FLimitations.MaxRowCount then
|
|
||||||
Workbook.AddErrorMsg(rsMaxRowsExceeded, [lastRow+1, FLimitations.MaxRowCount]);
|
|
||||||
|
|
||||||
// Check column count
|
|
||||||
if lastCol >= FLimitations.MaxColCount then
|
|
||||||
Workbook.AddErrorMsg(rsMaxColsExceeded, [lastCol+1, FLimitations.MaxColCount]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
end. {** End Unit: fpspreadsheet }
|
end. {** End Unit: fpspreadsheet }
|
||||||
|
@ -23,6 +23,50 @@ uses
|
|||||||
fpsTypes, fpsClasses, fpSpreadsheet;
|
fpsTypes, fpsClasses, fpSpreadsheet;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
{ TsBasicSpreadReaderWriter }
|
||||||
|
TsBasicSpreadReaderWriter = class
|
||||||
|
protected
|
||||||
|
{@@ Instance of the workbook which is currently being read or written. }
|
||||||
|
FWorkbook: TsWorkbook;
|
||||||
|
{@@ Instance of the worksheet which is currently being read or written. }
|
||||||
|
FWorksheet: TsWorksheet;
|
||||||
|
{@@ Limitations for the specific data file format }
|
||||||
|
FLimitations: TsSpreadsheetFormatLimitations;
|
||||||
|
public
|
||||||
|
constructor Create(AWorkbook: TsWorkbook); virtual; // to allow descendents to override it
|
||||||
|
function Limitations: TsSpreadsheetFormatLimitations;
|
||||||
|
{@@ Instance of the workbook which is currently being read/written. }
|
||||||
|
property Workbook: TsWorkbook read FWorkbook;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TsBasicSpreadReader }
|
||||||
|
TsBasicSpreadReader = class(TsBasicSpreadReaderWriter)
|
||||||
|
public
|
||||||
|
{ General writing methods }
|
||||||
|
procedure ReadFromFile(AFileName: string; AParams: TsStreamParams = []); virtual; abstract;
|
||||||
|
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); virtual; abstract;
|
||||||
|
procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); virtual; abstract;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TsBasicSpreadWriter }
|
||||||
|
TsBasicSpreadWriter = class(TsBasicSpreadReaderWriter)
|
||||||
|
public
|
||||||
|
{ Helpers }
|
||||||
|
procedure CheckLimitations; virtual;
|
||||||
|
{ General writing methods }
|
||||||
|
procedure WriteToFile(const AFileName: string;
|
||||||
|
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); virtual; abstract;
|
||||||
|
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); virtual; abstract;
|
||||||
|
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); virtual; abstract;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ TsSpreadReader class reference type }
|
||||||
|
TsSpreadReaderClass = class of TsBasicSpreadReader;
|
||||||
|
|
||||||
|
{@@ TsSpreadWriter class reference type }
|
||||||
|
TsSpreadWriterClass = class of TsBasicSpreadWriter;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
Custom reader of spreadsheet files. "Custom" means that it provides only
|
Custom reader of spreadsheet files. "Custom" means that it provides only
|
||||||
the basic functionality. The main implementation is done in derived classes
|
the basic functionality. The main implementation is done in derived classes
|
||||||
@ -141,12 +185,67 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Math,
|
Math,
|
||||||
fpsStrings, fpsUtils, fpsNumFormat, fpsStreams;
|
fpsStrings, fpsUtils, fpsNumFormat, fpsStreams, fpsRegFileFormats;
|
||||||
|
|
||||||
|
|
||||||
{*******************************************************************************
|
{------------------------------------------------------------------------------}
|
||||||
* TsCustomSpreadReader *
|
{ TsBasicSpreadReaderWriter }
|
||||||
*******************************************************************************}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Constructor of the reader/writer. Has the workbook to be read/written as a
|
||||||
|
parameter to apply the localization information found in its FormatSettings.
|
||||||
|
|
||||||
|
@param AWorkbook Workbook into which the file is being read or from with the
|
||||||
|
file is written. This parameter is passed from the workbook
|
||||||
|
which creates the reader/writer.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
constructor TsBasicSpreadReaderWriter.Create(AWorkbook: TsWorkbook);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FWorkbook := AWorkbook;
|
||||||
|
{ A good starting point valid for many formats ... }
|
||||||
|
FLimitations.MaxColCount := 256;
|
||||||
|
FLimitations.MaxRowCount := 65536;
|
||||||
|
FLimitations.MaxPaletteSize := MaxInt;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Returns a record containing limitations of the specific file format of the
|
||||||
|
writer.
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
function TsBasicSpreadReaderWriter.Limitations: TsSpreadsheetFormatLimitations;
|
||||||
|
begin
|
||||||
|
Result := FLimitations;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------}
|
||||||
|
{ TsBasicSpreadWriter }
|
||||||
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
|
{@@ ----------------------------------------------------------------------------
|
||||||
|
Checks limitations of the writer, e.g max row/column count
|
||||||
|
-------------------------------------------------------------------------------}
|
||||||
|
procedure TsBasicSpreadWriter.CheckLimitations;
|
||||||
|
var
|
||||||
|
lastCol, lastRow: Cardinal;
|
||||||
|
begin
|
||||||
|
Workbook.GetLastRowColIndex(lastRow, lastCol);
|
||||||
|
|
||||||
|
// Check row count
|
||||||
|
if lastRow >= FLimitations.MaxRowCount then
|
||||||
|
Workbook.AddErrorMsg(rsMaxRowsExceeded, [lastRow+1, FLimitations.MaxRowCount]);
|
||||||
|
|
||||||
|
// Check column count
|
||||||
|
if lastCol >= FLimitations.MaxColCount then
|
||||||
|
Workbook.AddErrorMsg(rsMaxColsExceeded, [lastCol+1, FLimitations.MaxColCount]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------}
|
||||||
|
{ TsCustomSpreadReader }
|
||||||
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Constructor of the reader. Has the workbook to be read as a
|
Constructor of the reader. Has the workbook to be read as a
|
||||||
@ -335,9 +434,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*******************************************************************************
|
{------------------------------------------------------------------------------}
|
||||||
* TsCustomSpreadWriter *
|
{ TsCustomSpreadWriter }
|
||||||
*******************************************************************************}
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Constructor of the writer. Has the workbook to be written as a parameter to
|
Constructor of the writer. Has the workbook to be written as a parameter to
|
||||||
@ -388,23 +487,7 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
Result := -1;
|
Result := -1;
|
||||||
end;
|
end;
|
||||||
(*
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
|
||||||
If a color index is greater then the maximum palette color count this
|
|
||||||
color is replaced by the closest palette color.
|
|
||||||
|
|
||||||
The present implementation does not change the color. Must be overridden by
|
|
||||||
writers of formats with limited palette sizes.
|
|
||||||
|
|
||||||
@param AColor Color palette index to be checked
|
|
||||||
@return Closest color to AColor. If AColor belongs to the palette it must
|
|
||||||
be returned unchanged.
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function TsCustomSpreadWriter.FixColor(AColor: TsColor): TsColor;
|
|
||||||
begin
|
|
||||||
Result := AColor;
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
If formatting features of a cell are not supported by the destination file
|
If formatting features of a cell are not supported by the destination file
|
||||||
format of the writer, here is the place to apply replacements.
|
format of the writer, here is the place to apply replacements.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
distribution, for details about the license.
|
distribution, for details about the license.
|
||||||
|
|
||||||
USAGE: Each unit implementing a new spreadsheet format must register the
|
USAGE: Each unit implementing a new spreadsheet format must register the
|
||||||
reader/writer ad some specific data by calling "RegisterSpreadFormat".
|
reader/writer and some specific data by calling "RegisterSpreadFormat".
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
unit fpsRegFileFormats;
|
unit fpsRegFileFormats;
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ unit fpsRegFileFormats;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpstypes, fpspreadsheet;
|
Classes, SysUtils, fpstypes, fpsReaderWriter; //fpspreadsheet;
|
||||||
|
|
||||||
type
|
type
|
||||||
TsSpreadFileAccess = (faRead, faWrite);
|
TsSpreadFileAccess = (faRead, faWrite);
|
||||||
|
@ -3600,7 +3600,7 @@ begin
|
|||||||
{ Now compress the files }
|
{ Now compress the files }
|
||||||
FZip := TZipper.Create;
|
FZip := TZipper.Create;
|
||||||
try
|
try
|
||||||
FZip.FileName := '__temp__.tmp';
|
// FZip.FileName := '__temp__.tmp';
|
||||||
FZip.Entries.AddFileEntry(FSContentTypes, OOXML_PATH_TYPES);
|
FZip.Entries.AddFileEntry(FSContentTypes, OOXML_PATH_TYPES);
|
||||||
FZip.Entries.AddFileEntry(FSRelsRels, OOXML_PATH_RELS_RELS);
|
FZip.Entries.AddFileEntry(FSRelsRels, OOXML_PATH_RELS_RELS);
|
||||||
FZip.Entries.AddFileEntry(FSWorkbookRels, OOXML_PATH_XL_RELS_RELS);
|
FZip.Entries.AddFileEntry(FSWorkbookRels, OOXML_PATH_XL_RELS_RELS);
|
||||||
|
Reference in New Issue
Block a user