fpspreadsheet: Simpler access to clipboard.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4372 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2015-10-06 12:01:35 +00:00
parent 0bfd16da59
commit 535273462f
14 changed files with 212 additions and 576 deletions

View File

@@ -22,10 +22,9 @@ type
procedure ReadNumber(AStream: TStream); override;
public
constructor Create(AWorkbook: TsWorkbook); override;
procedure ReadFromClipboardStream(AStream: TStream); override;
procedure ReadFromFile(AFileName: String); override;
procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStrings(AStrings: TStrings); override;
procedure ReadFromFile(AFileName: String; AParams: TsStreamParams = []); override;
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); override;
procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
end;
TsCSVWriter = class(TsCustomSpreadWriter)
@@ -51,9 +50,8 @@ type
public
constructor Create(AWorkbook: TsWorkbook); override;
procedure WriteToClipboardStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStrings(AStrings: TStrings; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
end;
TsCSVLineEnding = (leSystem, leCRLF, leCR, leLF);
@@ -201,23 +199,22 @@ begin
Unused(AStream);
end;
procedure TsCSVReader.ReadFromClipboardStream(AStream: TStream);
begin
ReadFromStream(AStream);
end;
procedure TsCSVReader.ReadFromFile(AFileName: String);
procedure TsCSVReader.ReadFromFile(AFileName: String;
AParams: TsStreamParams = []);
begin
FWorksheetName := ChangeFileExt(ExtractFileName(AFileName), '');
inherited;
inherited ReadFromFile(AFilename, AParams);
end;
procedure TsCSVReader.ReadFromStream(AStream: TStream);
procedure TsCSVReader.ReadFromStream(AStream: TStream;
AParams: TsStreamParams = []);
var
Parser: TCSVParser;
s: String;
encoding: String;
begin
Unused(AParams);
// Try to determine encoding of the input file
SetLength(s, Min(1000, AStream.Size));
AStream.ReadBuffer(s[1], Length(s));
@@ -249,13 +246,14 @@ begin
end;
end;
procedure TsCSVReader.ReadFromStrings(AStrings: TStrings);
procedure TsCSVReader.ReadFromStrings(AStrings: TStrings;
AParams: TsStreamParams = []);
var
Stream: TStringStream;
begin
Stream := TStringStream.Create(AStrings.Text);
try
ReadFromStream(Stream);
ReadFromStream(Stream, AParams);
finally
Stream.Free;
end;
@@ -415,31 +413,26 @@ begin
end;
end;
procedure TsCSVWriter.WriteToClipboardStream(AStream: TStream;
AParam: Integer = 0);
begin
FClipboardMode := true;
WriteToStream(AStream, AParam);
end;
procedure TsCSVWriter.WriteToStream(AStream: TStream; AParam: Integer = 0);
procedure TsCSVWriter.WriteToStream(AStream: TStream;
AParams: TsStreamParams = []);
var
n: Integer;
begin
Unused(AParam);
FClipboardMode := (spClipboard in AParams);
if (CSVParams.SheetIndex >= 0) and (CSVParams.SheetIndex < FWorkbook.GetWorksheetCount)
then n := CSVParams.SheetIndex
else n := 0;
WriteSheet(AStream, FWorkbook.GetWorksheetByIndex(n));
end;
procedure TsCSVWriter.WriteToStrings(AStrings: TStrings; AParam: Integer = 0);
procedure TsCSVWriter.WriteToStrings(AStrings: TStrings;
AParams: TsStreamParams = []);
var
Stream: TStream;
begin
Stream := TStringStream.Create('');
try
WriteToStream(Stream, AParam);
WriteToStream(Stream, AParams);
Stream.Position := 0;
AStrings.LoadFromStream(Stream);
finally

View File

@@ -28,6 +28,7 @@ type
FColSpan, FRowSpan: Integer;
FHRef: String;
FFontStack: TsIntegerStack;
FWindowsClipboardMode: Boolean;
procedure ReadBackgroundColor;
procedure ReadBorder;
procedure ReadEncoding;
@@ -56,14 +57,14 @@ type
public
constructor Create(AWorkbook: TsWorkbook); override;
destructor Destroy; override;
procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStrings(AStrings: TStrings); override;
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); override;
procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
end;
TsHTMLWriter = class(TsCustomSpreadWriter)
private
FPointSeparatorSettings: TFormatSettings;
FParam: Integer;
FWindowsClipboardMode: Boolean;
FStartHtmlPos: Int64;
FEndHtmlPos: Int64;
FStartFragmentPos: Int64;
@@ -87,6 +88,7 @@ type
procedure WriteWorksheet(AStream: TStream; ASheet: TsWorksheet);
protected
procedure InternalWriteToStream(AStream: TStream);
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
ACell: PCell); override;
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
@@ -105,9 +107,8 @@ type
public
constructor Create(AWorkbook: TsWorkbook); override;
destructor Destroy; override;
procedure WriteToClipboardStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStrings(AStrings: TStrings; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
end;
TsHTMLParams = record
@@ -1041,14 +1042,15 @@ begin
SetLength(FCurrRichTextParams, 0);
end;
procedure TsHTMLReader.ReadFromStream(AStream: TStream);
procedure TsHTMLReader.ReadFromStream(AStream: TStream;
AParams: TsStreamParams = []);
var
list: TStringList;
begin
list := TStringList.Create;
try
list.LoadFromStream(AStream);
ReadFromStrings(list);
ReadFromStrings(list, AParams);
if FWorkbook.GetWorksheetCount = 0 then
begin
FWorkbook.AddErrorMsg('Requested table not found, or no tables in html file');
@@ -1059,8 +1061,11 @@ begin
end;
end;
procedure TsHTMLReader.ReadFromStrings(AStrings: TStrings);
procedure TsHTMLReader.ReadFromStrings(AStrings: TStrings;
AParams: TsStreamParams = []);
begin
FWindowsClipboardMode := (spWindowsClipboardHTML in AParams);
// Create html parser
FreeAndNil(parser);
parser := THTMLParser.Create(AStrings.Text);
@@ -1429,6 +1434,28 @@ begin
Result := 'white-space:nowrap;';
end;
procedure TsHTMLWriter.InternalWriteToStream(AStream: TStream);
begin
FWorkbook.UpdateCaches;
AppendToStream(AStream,
'<!DOCTYPE html>');
FStartHTMLPos := AStream.Position;
AppendToStream(AStream,
'<html>' +
'<head>'+
'<meta charset="utf-8">');
WriteStyles(AStream);
AppendToStream(AStream,
'</head>');
WriteBody(AStream);
AppendToStream(AStream,
'</html>');
FEndHTMLPos := AStream.Position;
end;
function TsHTMLWriter.IsHyperlinkTarget(ACell: PCell; out ABookmark: String): Boolean;
var
sheet: TsWorksheet;
@@ -1474,7 +1501,7 @@ var
begin
AppendToStream(AStream,
'<body>');
if (FParam = PARAM_WINDOWS_CLIPBOARD_HTML) or (HTMLParams.SheetIndex < 0) then // active sheet
if FWindowsClipboardMode or (HTMLParams.SheetIndex < 0) then // active sheet
begin
if FWorkbook.ActiveWorksheet = nil then
FWorkbook.SelectWorksheet(FWorkbook.GetWorksheetByIndex(0));
@@ -1675,64 +1702,30 @@ begin
'</style>' + LineEnding);
end;
procedure TsHTMLWriter.WriteToClipboardStream(AStream: TStream;
AParam: Integer = 0);
procedure TsHTMLWriter.WriteToStream(AStream: TStream; AParams: TsStreamParams = []);
begin
if AParam = PARAM_WINDOWS_CLIPBOARD_HTML then
FWindowsClipboardMode := (spWindowsClipboardHTML in AParams);
if FWindowsClipboardMode then
begin
AppendToStream(AStream, Format(
NATIVE_HEADER, [0, 0, 0, 0])); // value will be replaced at end
WriteToStream(AStream, AParam);
InternalWriteToStream(AStream);
AStream.Position := 0;
AppendToStream(AStream, Format(
NATIVE_HEADER, [FStartHTMLPos, FEndHTMLPos, FStartFragmentPos, FEndFragmentPos]));
end else
WriteToStream(AStream, AParam);
{
{$IFDEF MSWINDOWS}
AppendToStream(AStream, Format(
NATIVE_HEADER, [0, 0, 0, 0])); // value will be replaced at end
WriteToStream(AStream, AParams);
AStream.Position := 0;
AppendToStream(AStream, Format(
NATIVE_HEADER, [FStartHTMLPos, FEndHTMLPos, FStartFragmentPos, FEndFragmentPos]));
{$ELSE}
WriteToStream(AStream, AParams);
{$ENDIF}
}
InternalWriteToStream(AStream);
end;
procedure TsHTMLWriter.WriteToStream(AStream: TStream; AParam: Integer = 0);
begin
FParam := AParam;
FWorkbook.UpdateCaches;
AppendToStream(AStream,
'<!DOCTYPE html>');
FStartHTMLPos := AStream.Position;
AppendToStream(AStream,
'<html>' +
'<head>'+
'<meta charset="utf-8">');
WriteStyles(AStream);
AppendToStream(AStream,
'</head>');
WriteBody(AStream);
AppendToStream(AStream,
'</html>');
FEndHTMLPos := AStream.Position;
end;
procedure TsHTMLWriter.WriteToStrings(AStrings: TStrings; AParam: Integer = 0);
procedure TsHTMLWriter.WriteToStrings(AStrings: TStrings;
AParams: TsStreamParams = []);
var
Stream: TStream;
begin
Stream := TStringStream.Create('');
try
WriteToStream(Stream, AParam);
WriteToStream(Stream, AParams);
Stream.Position := 0;
AStrings.LoadFromStream(Stream);
finally
@@ -1783,7 +1776,7 @@ begin
'<div>' + LineEnding +
'<table style="' + style + '">' + LineEnding);
if (FParam = PARAM_WINDOWS_CLIPBOARD_HTML) then
if FWindowsClipboardMode then
begin
AppendToStream(AStream, START_FRAGMENT);
FStartFragmentPos := AStream.Position;
@@ -1896,7 +1889,7 @@ begin
'</tr>' + LineEnding);
end;
if (FParam = PARAM_WINDOWS_CLIPBOARD_HTML) then
if FWindowsClipboardMode then
begin
AppendToStream(AStream, END_FRAGMENT);
FEndFragmentPos := AStream.Position;

View File

@@ -142,7 +142,7 @@ type
destructor Destroy; override;
{ General reading methods }
procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
{ TsSpreadOpenDocWriter }
@@ -229,7 +229,7 @@ type
{ General writing methods }
procedure WriteStringToFile(AString, AFileName: string);
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
{ procedure WriteStarObjectDescriptorToStream(AStream: TStream); }
@@ -2058,7 +2058,8 @@ begin
Workbook.OnReadCellData(Workbook, ARow, ACol, cell);
end;
procedure TsSpreadOpenDocReader.ReadFromStream(AStream: TStream);
procedure TsSpreadOpenDocReader.ReadFromStream(AStream: TStream;
AParams: TsStreamParams = []);
var
Doc : TXMLDocument;
BodyNode, SpreadSheetNode, TableNode: TDOMNode;
@@ -2081,6 +2082,8 @@ var
end;
begin
Unused(AParams);
Doc := nil;
try
// process the styles.xml file
@@ -4787,8 +4790,8 @@ var
S : String;
begin
TheStream := TFileStream.Create(AFileName, fmCreate);
S:=AString;
TheStream.WriteBuffer(Pointer(S)^,Length(S));
S := AString;
TheStream.WriteBuffer(Pointer(S)^, Length(S));
TheStream.Free;
end;
(*
@@ -4818,9 +4821,9 @@ begin
end; *)
procedure TsSpreadOpenDocWriter.WriteToStream(AStream: TStream;
AParam: Integer = 0);
AParams: TsStreamParams = []);
begin
Unused(AParam);
Unused(AParams);
InternalWriteToStream(AStream);
end;

View File

@@ -659,19 +659,22 @@ type
function CreateSpreadReader(AFormat: TsSpreadsheetFormat;
AClipboardMode: Boolean = false): TsBasicSpreadReader;
function CreateSpreadWriter(AFormat: TsSpreadsheetFormat;
AClipboardMode: Boolean = false): TsBasicSpreadWriter;
procedure ReadFromFile(AFileName: string; AFormat: TsSpreadsheetFormat); overload;
procedure ReadFromFile(AFileName: string); overload;
procedure ReadFromFileIgnoringExtension(AFileName: string);
AParams: TsStreamParams = []): TsBasicSpreadWriter;
procedure ReadFromFile(AFileName: string; AFormat: TsSpreadsheetFormat;
AParams: TsStreamParams = []); overload;
procedure ReadFromFile(AFileName: string;
AParams: TsStreamParams = []); overload;
procedure ReadFromFileIgnoringExtension(AFileName: string;
AParams: TsStreamParams = []);
procedure ReadFromStream(AStream: TStream; AFormat: TsSpreadsheetFormat;
AClipboardMode: Boolean = false);
AParams: TsStreamParams = []);
procedure WriteToFile(const AFileName: string;
const AFormat: TsSpreadsheetFormat;
const AOverwriteExisting: Boolean = False; AParam: Integer = 0); overload;
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); overload;
procedure WriteToFile(const AFileName: String;
const AOverwriteExisting: Boolean = False; AParam: Integer = 0); overload;
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); overload;
procedure WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat;
AClipboardMode: Boolean = false; AParam: Integer = 0);
AParams: TsStreamParams = []);
{ Worksheet list handling methods }
function AddWorksheet(AName: string;
@@ -732,9 +735,10 @@ type
{ Clipboard }
procedure CopyToClipboardStream(AStream: TStream; AFormat: TsSpreadsheetFormat;
AParam: Integer = 0);
AParams: TsStreamParams = []);
procedure PasteFromClipboardStream(AStream: TStream; AFormat: TsSpreadsheetFormat;
AOperation: TsCopyOperation; ATransposed: Boolean = false);
AOperation: TsCopyOperation; AParams: TsStreamParams = [];
ATransposed: Boolean = false);
(*
{ Color handling }
function FPSColorToHexString(AColor: TsColor; ARGBColor: TFPColor): String;
@@ -825,10 +829,9 @@ type
TsBasicSpreadReader = class(TsBasicSpreadReaderWriter)
public
{ General writing methods }
procedure ReadFromClipboardStream(AStream: TStream); virtual; abstract;
procedure ReadFromFile(AFileName: string); virtual; abstract;
procedure ReadFromStream(AStream: TStream); virtual; abstract;
procedure ReadFromStrings(AStrings: TStrings); virtual; abstract;
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 }
@@ -837,11 +840,10 @@ type
{ Helpers }
procedure CheckLimitations; virtual;
{ General writing methods }
procedure WriteToClipboardStream(AStream: TStream; AParam: Integer = 0); virtual; abstract;
procedure WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean = False; AParam: Integer = 0); virtual; abstract;
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); virtual; abstract;
procedure WriteToStrings(AStrings: TStrings; AParam: Integer = 0); virtual; abstract;
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 }
@@ -6673,7 +6675,7 @@ end;
write the given file format.
-------------------------------------------------------------------------------}
function TsWorkbook.CreateSpreadWriter(AFormat: TsSpreadsheetFormat;
AClipboardMode: Boolean = false): TsBasicSpreadWriter;
AParams: TsStreamParams): TsBasicSpreadWriter;
var
i: Integer;
begin
@@ -6681,7 +6683,7 @@ begin
for i := 0 to High(GsSpreadFormats) do
if (GsSpreadFormats[i].Format = AFormat) and
((not AClipboardMode) or GsSpreadFormats[i].CanWriteToClipboard) then
(not (spClipboard in AParams) or GsSpreadFormats[i].CanWriteToClipboard) then
begin
Result := GsSpreadFormats[i].WriterClass.Create(self);
Break;
@@ -6726,7 +6728,7 @@ end;
@param AFormat File format assumed
-------------------------------------------------------------------------------}
procedure TsWorkbook.ReadFromFile(AFileName: string;
AFormat: TsSpreadsheetFormat);
AFormat: TsSpreadsheetFormat; AParams: TsStreamParams = []);
var
AReader: TsBasicSpreadReader;
ok: Boolean;
@@ -6742,7 +6744,7 @@ begin
FReadWriteFlag := rwfRead;
inc(FLockCount); // This locks various notifications from being sent
try
AReader.ReadFromFile(AFileName);
AReader.ReadFromFile(AFileName, AParams);
ok := true;
UpdateCaches;
if (boAutoCalc in Options) then
@@ -6764,7 +6766,7 @@ end;
the extension. In the case of the ambiguous xls extension, it will simply
assume that it is BIFF8. Note that it could be BIFF2 or 5 as well.
-------------------------------------------------------------------------------}
procedure TsWorkbook.ReadFromFile(AFileName: string); overload;
procedure TsWorkbook.ReadFromFile(AFileName: string; AParams: TsStreamParams = []);
var
SheetType: TsSpreadsheetFormat;
valid: Boolean;
@@ -6793,7 +6795,7 @@ begin
while True do
begin
try
ReadFromFile(AFileName, SheetType);
ReadFromFile(AFileName, SheetType, AParams);
valid := True;
except
on E: Exception do
@@ -6812,7 +6814,7 @@ begin
if (not valid) and (lException <> nil) then raise lException;
end
else
ReadFromFile(AFileName, SheetType);
ReadFromFile(AFileName, SheetType, AParams);
end else
raise Exception.CreateFmt(rsNoValidSpreadsheetFile, [AFileName]);
end;
@@ -6820,7 +6822,8 @@ end;
{@@ ----------------------------------------------------------------------------
Reads the document from a file, but ignores the extension.
-------------------------------------------------------------------------------}
procedure TsWorkbook.ReadFromFileIgnoringExtension(AFileName: string);
procedure TsWorkbook.ReadFromFileIgnoringExtension(AFileName: string;
AParams: TsStreamParams = []);
var
SheetType: TsSpreadsheetFormat;
lException: Exception;
@@ -6831,7 +6834,7 @@ begin
begin
try
Dec(SheetType);
ReadFromFile(AFileName, SheetType);
ReadFromFile(AFileName, SheetType, AParams);
lException := nil;
except
on E: Exception do { do nothing } ;
@@ -6845,10 +6848,10 @@ end;
@param AStream Stream being read
@param AFormat File format assumed.
@param AClipboardMode The calling method has read the stream from the clipboard.
@param AParams Optional parameters to control stream access.
-------------------------------------------------------------------------------}
procedure TsWorkbook.ReadFromStream(AStream: TStream;
AFormat: TsSpreadsheetFormat; AClipboardMode: Boolean = false);
AFormat: TsSpreadsheetFormat; AParams: TsStreamParams = []);
var
AReader: TsBasicSpreadReader;
ok: Boolean;
@@ -6860,9 +6863,7 @@ begin
try
ok := false;
AStream.Position := 0;
if AClipboardMode then
AReader.ReadFromClipboardStream(AStream) else
AReader.ReadFromStream(AStream);
AReader.ReadFromStream(AStream, AParams);
ok := true;
finally
dec(FLockCount);
@@ -6897,11 +6898,11 @@ end;
@param AOverwriteExisting If the file is already existing it will be
overwritten in case of AOverwriteExisting = true.
If false an exception will be raised.
@param AParam Optional parameter to control writer-specific details.
@param AParams Optional parameters to control stream access.
-------------------------------------------------------------------------------}
procedure TsWorkbook.WriteToFile(const AFileName: string;
const AFormat: TsSpreadsheetFormat; const AOverwriteExisting: Boolean = False;
AParam: Integer = 0);
AParams: TsStreamParams = []);
var
AWriter: TsBasicSpreadWriter;
begin
@@ -6912,7 +6913,7 @@ begin
PrepareBeforeSaving;
AWriter.CheckLimitations;
FReadWriteFlag := rwfWrite;
AWriter.WriteToFile(AFileName, AOverwriteExisting, AParam);
AWriter.WriteToFile(AFileName, AOverwriteExisting, AParams);
finally
FReadWriteFlag := rwfNormal;
AWriter.Free;
@@ -6927,17 +6928,17 @@ end;
@param AOverwriteExisting If the file already exists it will be overwritten
of AOverwriteExisting is true. In case of false, an
exception will be raised.
@param AParam Optional parameter to control writer-specific details
@param AParams Optional parameters to control stream access
-------------------------------------------------------------------------------}
procedure TsWorkbook.WriteToFile(const AFileName: String;
const AOverwriteExisting: Boolean; AParam: Integer = 0);
const AOverwriteExisting: Boolean; AParams: TsStreamParams = []);
var
SheetType: TsSpreadsheetFormat;
valid: Boolean;
begin
valid := GetFormatFromFileName(AFileName, SheetType);
if valid then
WriteToFile(AFileName, SheetType, AOverwriteExisting, AParam)
WriteToFile(AFileName, SheetType, AOverwriteExisting, AParams)
else
raise Exception.Create(Format(rsInvalidExtension, [
ExtractFileExt(AFileName)
@@ -6950,23 +6951,21 @@ end;
@param AStream Instance of the stream being written to
@param AFormat File format to be written.
@param AClipboardMode Stream will be used by calling method for clipboard access
@param AParam An optional parameter which controls writing of
details. The HTML writer, for example, can be forced
to write a valid html document in Windows.
@param AParams Optional parameters to control stream access
The HTML writer, for example, can be forced to write
a valid html document in Windows.
-------------------------------------------------------------------------------}
procedure TsWorkbook.WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat;
AClipboardMode: Boolean = false; AParam: Integer = 0);
AParams: TsStreamParams = []);
var
AWriter: TsBasicSpreadWriter;
begin
AWriter := CreateSpreadWriter(AFormat, AClipboardMode);
AWriter := CreateSpreadWriter(AFormat, AParams);
try
PrepareBeforeSaving;
AWriter.CheckLimitations;
FReadWriteFlag := rwfWrite;
if AClipboardMode then
AWriter.WriteToClipboardStream(AStream, AParam) else
AWriter.WriteToStream(AStream, AParam);
AWriter.WriteToStream(AStream, AParams);
finally
FReadWriteFlag := rwfNormal;
AWriter.Free;
@@ -7790,7 +7789,7 @@ end;
fpspreadsheet does not "know" the system's clipboard.
-------------------------------------------------------------------------------}
procedure TsWorkbook.CopyToClipboardStream(AStream: TStream;
AFormat: TsSpreadsheetFormat; AParam: Integer = 0);
AFormat: TsSpreadsheetFormat; AParams: TsStreamParams = []);
var
clipbook: TsWorkbook;
clipsheet: TsWorksheet;
@@ -7825,9 +7824,9 @@ begin
clipsheet.SetSelection(ActiveWorksheet.GetSelection);
clipsheet.SelectCell(ActiveWorksheet.ActiveCellRow, ActiveWorksheet.ActiveCellCol);
// Write this workbook to a stream. Set the parameter ClipboardMode
// to TRUE to use the dedicated clipboard routine if needed.
clipbook.WriteToStream(AStream, AFormat, true, AParam);
// Write this workbook to a stream. Set the parameter spClipboard to
// indicate that this should be the special clipboard version of the stream.
clipbook.WriteToStream(AStream, AFormat, AParams + [spClipboard]);
// The calling routine which copies the stream to the clipboard requires
// the stream to be at its beginning.
@@ -7845,7 +7844,7 @@ end;
-------------------------------------------------------------------------------}
procedure TsWorkbook.PasteFromClipboardStream(AStream: TStream;
AFormat: TsSpreadsheetFormat; AOperation: TsCopyOperation;
ATransposed: Boolean = false);
AParams: TsStreamParams = []; ATransposed: Boolean = false);
var
clipbook: TsWorkbook;
clipsheet: TsWorksheet;
@@ -7872,7 +7871,7 @@ begin
// Read stream into this temporary workbook
// Set last parameter (ClipboardMode) to TRUE to activate special format
// treatment for clipboard, if needed.
clipbook.ReadFromStream(AStream, AFormat, true);
clipbook.ReadFromStream(AStream, AFormat, AParams + [spClipboard]);
clipsheet := clipbook.GetWorksheetByIndex(0);
// Find offset of active cell to left/top cell in temporary sheet
dr := LongInt(ActiveWorksheet.ActiveCellRow) - clipsheet.GetFirstRowIndex(true);

View File

@@ -1140,11 +1140,11 @@ var
savedCSVParams: TsCSVParams;
procedure CopyToClipboard(AStream: TStream; AFileFormat: TsSpreadsheetFormat;
AClipboardFormat: Integer; AParam: Integer = 0);
AClipboardFormat: Integer; AParams: TsStreamParams = []);
begin
if AClipboardFormat = 0 then
exit;
FWorkbook.CopyToClipboardStream(AStream, AFileFormat, AParam);
FWorkbook.CopyToClipboardStream(AStream, AFileFormat, AParams);
Clipboard.AddFormat(AClipboardFormat, AStream);
(AStream as TMemoryStream).Clear;
end;
@@ -1180,7 +1180,7 @@ begin
// Then write Windows HTML format
{$IFDEF MSWINDOWS}
CopyToClipboard(stream, sfHTML, cfHtmlFormat, PARAM_WINDOWS_CLIPBOARD_HTML);
CopyToClipboard(stream, sfHTML, cfHtmlFormat, [spWindowsClipboardHTML]);
{$ENDIF}
// Write standard html format (MIME-type "text/html")
@@ -1234,9 +1234,11 @@ procedure TsWorkbookSource.PasteCellsFromClipboard(AItem: TsCopyOperation;
var
fmt: TsSpreadsheetFormat;
stream: TStream;
params: TsStreamParams;
begin
stream := TMemoryStream.Create;
try
params := [spClipboard];
// Check whether the clipboard content is suitable for fpspreadsheet
{if Clipboard.GetFormat(cfOpenDocumentFormat, stream) then
fmt := sfOpenDocument
@@ -1245,7 +1247,10 @@ begin
fmt := sfExcel8
else if Clipboard.GetFormat(cfBiff5Format, stream) then
fmt := sfExcel5
else if Clipboard.GetFormat(cfHTMLFormat, stream) or Clipboard.GetFormat(cfTextHTMLFormat, stream) then
else if Clipboard.GetFormat(cfHTMLFormat, stream) then begin
fmt := sfHTML;
params := params + [spWindowsClipboardHTML];
end else if Clipboard.GetFormat(cfTextHTMLFormat, stream) then
fmt := sfHTML
else if Clipboard.GetFormat(cfCSVFormat, stream) then
fmt := sfCSV
@@ -1259,7 +1264,7 @@ begin
// Paste stream into workbook
stream.Position := 0;
FWorkbook.PasteFromClipboardStream(stream, fmt, AItem, ATransposed);
FWorkbook.PasteFromClipboardStream(stream, fmt, AItem, params, ATransposed);
// To do: XML format, ods format
finally

View File

@@ -65,9 +65,9 @@ type
destructor Destroy; override;
{ General writing methods }
procedure ReadFromFile(AFileName: string); override;
procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStrings(AStrings: TStrings); override;
procedure ReadFromFile(AFileName: string; AParams: TsStreamParams = []); override;
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); override;
procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
{@@ List of number formats found in the workbook. }
property NumFormatList: TStringList read FNumFormatList;
@@ -128,9 +128,9 @@ type
{ General writing methods }
procedure WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean = False; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStrings(AStrings: TStrings; AParam: Integer = 0); override;
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
{@@ List of number formats found in the workbook. }
property NumFormatList: TStringList read FNumFormatList;
@@ -301,7 +301,8 @@ end;
@param AFileName The input file name.
@see TsWorkbook
-------------------------------------------------------------------------------}
procedure TsCustomSpreadReader.ReadFromFile(AFileName: string);
procedure TsCustomSpreadReader.ReadFromFile(AFileName: string;
AParams: TsStreamParams = []);
var
stream, fs: TStream;
begin
@@ -323,7 +324,7 @@ begin
end;
try
ReadFromStream(stream);
ReadFromStream(stream, AParams);
finally
stream.Free;
end;
@@ -341,7 +342,8 @@ end;
@param AData Workbook which is filled by the data from the stream.
-------------------------------------------------------------------------------}
procedure TsCustomSpreadReader.ReadFromStream(AStream: TStream);
procedure TsCustomSpreadReader.ReadFromStream(AStream: TStream;
AParams: TsStreamParams = []);
var
AStringStream: TStringStream;
AStrings: TStringList;
@@ -352,7 +354,7 @@ begin
AStringStream.CopyFrom(AStream, AStream.Size);
AStringStream.Seek(0, soFromBeginning);
AStrings.Text := AStringStream.DataString;
ReadFromStrings(AStrings);
ReadFromStrings(AStrings, AParams);
finally
AStringStream.Free;
AStrings.Free;
@@ -363,9 +365,10 @@ end;
Reads workbook data from a string list. This abstract implementation does
nothing and raises an exception. Must be overridden, like for wikitables.
-------------------------------------------------------------------------------}
procedure TsCustomSpreadReader.ReadFromStrings(AStrings: TStrings);
procedure TsCustomSpreadReader.ReadFromStrings(AStrings: TStrings;
AParams: TsStreamParams = []);
begin
Unused(AStrings);
Unused(AStrings, AParams);
raise Exception.Create(rsUnsupportedReadFormat);
end;
@@ -610,13 +613,12 @@ end;
@param AFileName The output file name.
@param AOverwriteExisting If the file already exists it will be replaced.
@param AParam Optional parameter to control writer-specific details
(see PARAM_XXXX declarations)
@param AParams Optional parameters to control stream access
@see TsWorkbook
-------------------------------------------------------------------------------}
procedure TsCustomSpreadWriter.WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean = False; AParam: Integer = 0);
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []);
var
OutputFile: TStream;
lMode: Word;
@@ -635,7 +637,7 @@ begin
OutputFile := TMemoryStream.Create;
try
WriteToStream(OutputFile, AParam);
WriteToStream(OutputFile, AParams);
if OutputFile is TMemoryStream then
(OutputFile as TMemoryStream).SaveToFile(AFileName);
finally
@@ -650,17 +652,16 @@ end;
Must be overriden in descendent classes for all other cases.
@param AStream Stream to which the workbook is written
@param AParam Optional parameter to control writer-specific details
@param AParams Optional parameters to control stream access
-------------------------------------------------------------------------------}
procedure TsCustomSpreadWriter.WriteToStream(AStream: TStream;
AParam: Integer = 0);
AParams: TsStreamParams = []);
var
list: TStringList;
begin
Unused(AParam);
list := TStringList.Create;
try
WriteToStrings(list);
WriteToStrings(list, AParams);
list.SaveToStream(AStream);
finally
list.Free;
@@ -672,13 +673,11 @@ end;
be overridden by descendants. See wikitables.
-------------------------------------------------------------------------------}
procedure TsCustomSpreadWriter.WriteToStrings(AStrings: TStrings;
AParam: Integer = 0);
AParams: TsStreamParams = []);
begin
Unused(AStrings, AParam);
Unused(AStrings, AParams);
raise Exception.Create(rsUnsupportedWriteFormat);
end;
end.

View File

@@ -733,11 +733,9 @@ type
{@@ Identifier for a copy operation }
TsCopyOperation = (coNone, coCopyFormat, coCopyValue, coCopyFormula, coCopyCell);
// Parameter declarations for TWriter.WriteStream/WriteClipboardStream
const
{@@ Parameter for HTML writer to create a HTML document for the clipboard
according to Windows specification }
PARAM_WINDOWS_CLIPBOARD_HTML = 1;
{@@ Parameters for stream access }
TsStreamParam = (spClipboard, spWindowsClipboardHTML);
TsStreamParams = set of TsStreamParam;
implementation

View File

@@ -69,7 +69,7 @@ type
public
SubFormat: TsSpreadsheetFormat;
{ General reading methods }
procedure ReadFromStrings(AStrings: TStrings); override;
procedure ReadFromStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
end;
{ TsWikiTable_PipesReader }
@@ -82,11 +82,11 @@ type
{ TsWikiTableWriter }
TsWikiTableWriter = class(TsCustomSpreadWriter)
protected
procedure WriteToStrings_WikiMedia(AStrings: TStrings);
public
SubFormat: TsSpreadsheetFormat;
{ General writing methods }
procedure WriteToStrings(AStrings: TStrings; AParams: Integer = 0); override;
procedure WriteToStrings_WikiMedia(AStrings: TStrings);
procedure WriteToStrings(AStrings: TStrings; AParams: TsStreamParams = []); override;
end;
{ TsWikiTable_WikiMediaWriter }
@@ -295,8 +295,10 @@ end;
{ TsWikiTableReader }
procedure TsWikiTableReader.ReadFromStrings(AStrings: TStrings);
procedure TsWikiTableReader.ReadFromStrings(AStrings: TStrings;
AParams: TsStreamParams = []);
begin
Unused(AParams);
case SubFormat of
sfWikiTable_Pipes: ReadFromStrings_Pipes(AStrings);
end;
@@ -344,7 +346,7 @@ end;
{ TsWikiTableWriter }
procedure TsWikiTableWriter.WriteToStrings(AStrings: TStrings;
AParams: Integer = 0);
AParams: TsStreamParams = []);
begin
Unused(AParams);
case SubFormat of

View File

@@ -73,7 +73,7 @@ type
public
constructor Create(AWorkbook: TsWorkbook); override;
{ General reading methods }
procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
@@ -126,7 +126,7 @@ type
XFType_Prot: Byte = 0); override;
public
constructor Create(AWorkbook: TsWorkbook); override;
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
TExcel2Settings = record
@@ -457,12 +457,14 @@ begin
end;
procedure TsSpreadBIFF2Reader.ReadFromStream(AStream: TStream);
procedure TsSpreadBIFF2Reader.ReadFromStream(AStream: TStream;
AParams: TsStreamParams = []);
var
BIFF2EOF: Boolean;
RecordType: Word;
CurStreamPos: Int64;
begin
Unused(AParams);
BIFF2EOF := False;
{ In BIFF2 files there is only one worksheet, let's create it }
@@ -1284,11 +1286,11 @@ end;
so only the first one will be written.
-------------------------------------------------------------------------------}
procedure TsSpreadBIFF2Writer.WriteToStream(AStream: TStream;
AParam: Integer = 0);
AParams: TsStreamParams = []);
var
pane: Byte;
begin
Unused(AParam);
Unused(AParams);
FWorksheet := Workbook.GetWorksheetByIndex(FSheetIndex);
if FWorksheet = nil then

View File

@@ -89,7 +89,7 @@ type
public
{ General reading methods }
// procedure ReadFromFile(AFileName: string); override;
procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
{ TsSpreadBIFF5Writer }
@@ -118,8 +118,8 @@ type
constructor Create(AWorkbook: TsWorkbook); override;
{ General writing methods }
procedure WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean = False; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
TExcel5Settings = record
@@ -791,12 +791,15 @@ begin
FCellFormatList.Add(fmt);
end;
procedure TsSpreadBIFF5Reader.ReadFromStream(AStream: TStream);
procedure TsSpreadBIFF5Reader.ReadFromStream(AStream: TStream;
AParams: TsStreamParams = []);
var
OLEStream: TMemoryStream;
OLEStorage: TOLEStorage;
OLEDocument: TOLEDocument;
begin
Unused(AParams);
OLEStream := TMemoryStream.Create;
try
OLEStorage := TOLEStorage.Create;
@@ -813,106 +816,6 @@ begin
end;
end;
(*
procedure TsSpreadBIFF5Reader.ReadFromStream(AStream: TStream);
var
BIFF5EOF: Boolean;
OLEStream: TMemoryStream;
OLEStorage: TOLEStorage;
OLEDocument: TOLEDocument;
begin
OLEStream := TMemoryStream.Create;
try
OLEStorage := TOLEStorage.Create;
try
// Only one stream is necessary for any number of worksheets
OLEDocument.Stream := OLEStream;
OLEStorage.ReadOLEStream(AStream, OLEDocument);
finally
OLEStorage.Free;
end;
// Check if the operation succeeded
if OLEStream.Size = 0 then
raise Exception.Create('[TsSpreadBIFF5Reader.ReadFromFile] Reading of OLE document failed');
// Rewind the stream and read from it
OLEStream.Position := 0;
{Initializations }
FWorksheetNames := TStringList.Create;
try
FCurrentWirksheet := 0;
BIFF5EOF := false;
{ Read workbook globals }
ReadWorkbookGlobals(OLEStream);
{ Check for the end of the file }
if OLEStream.Position >= AStream.Size then
BIFF5EOF := true;
{ Now read all worksheets }
while not BIFF5EOF do
begin
ReadWorksheet(OLEStream);
// Check for the end of the fild
if OLEStream.Position >= OLEStream.Size then
BIFF5EOF := true;
// Final preparations
inc(FCurrentWorksheet);
// It can happen in files written by Office97 that the OLE directory is
// at the end of the file.
if FCurrentWorksheet = FWorksheetNames.Count then
BIFF5EOF := true;
end;
finally
{ Finalization }
FreeAndNil(FWorksheetNames);
end;
finally
OLEStream.Free;
end;
end;
*)
(*
begin
{ Initializations }
FWorksheetNames := TStringList.Create;
FWorksheetNames.Clear;
FCurrentWorksheet := 0;
BIFF5EOF := False;
{ Read workbook globals }
ReadWorkbookGlobals(AStream);
{ Check for the end of the file }
if AStream.Position >= AStream.Size then BIFF5EOF := True;
{ Now read all worksheets }
while (not BIFF5EOF) do
begin
ReadWorksheet(AStream);
// Check for the end of the file
if AStream.Position >= AStream.Size then BIFF5EOF := True;
// Final preparations
Inc(FCurrentWorksheet);
if FCurrentWorksheet = FWorksheetNames.Count then BIFF5EOF := True;
// It can happen in files written by Office97 that the OLE directory is
// at the end of the file.
end;
{ Finalization }
FWorksheetNames.Free;
end;
*)
procedure TsSpreadBIFF5Reader.ReadFont(const AStream: TStream);
var
{%H-}lCodePage: Word;
@@ -1172,13 +1075,13 @@ end;
2 - Write the memory stream data to disk using COM functions
-------------------------------------------------------------------------------}
procedure TsSpreadBIFF5Writer.WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean; AParam: Integer = 0);
const AOverwriteExisting: Boolean; AParams: TsStreamParams = []);
var
stream: TStream;
OutputStorage: TOLEStorage;
OLEDocument: TOLEDocument;
begin
Unused(AParam);
Unused(AParams);
if (boBufStream in Workbook.Options) then
stream := TBufStream.Create else
@@ -1203,13 +1106,13 @@ end;
envelope of the document.
-------------------------------------------------------------------------------}
procedure TsSpreadBIFF5Writer.WriteToStream(AStream: TStream;
AParam: Integer = 0);
AParams: TsStreamParams = []);
var
OutputStorage: TOLEStorage;
OLEDocument: TOLEDocument;
stream: TStream;
begin
Unused(AParam);
Unused(AParams);
if (boBufStream in Workbook.Options) then
stream := TBufStream.Create else
stream := TMemoryStream.Create;

View File

@@ -116,7 +116,7 @@ type
procedure ReadXF(const AStream: TStream);
public
destructor Destroy; override;
procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
{ TsSpreadBIFF8Writer }
@@ -170,8 +170,8 @@ type
constructor Create(AWorkbook: TsWorkbook); override;
{ General writing methods }
procedure WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean = False; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
const AOverwriteExisting: Boolean = False; AParams: TsStreamParams = []); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
TExcel8Settings = record
@@ -906,54 +906,15 @@ function TsSpreadBIFF8Reader.ReadString(const AStream: TStream;
begin
Result := UTF16ToUTF8(ReadWideString(AStream, ALength, ARichTextParams));
end;
(*
procedure TsSpreadBIFF8Reader.ReadFromFile(AFileName: String);
var
FileStream: TFileStream;
begin
FileStream := TFileStream.Create(AFilename, fmOpenRead or fmShareDenyNone);
try
ReadFromStream(FileStream);
finally
FileStream.Free;
end;
end;
procedure TsSpreadBIFF8Reader.ReadFromFile(AFileName: string);
var
MemStream: TMemoryStream;
OLEStorage: TOLEStorage;
OLEDocument: TOLEDocument;
begin
MemStream := TMemoryStream.Create;
OLEStorage := TOLEStorage.Create;
try
// Only one stream is necessary for any number of worksheets
OLEDocument.Stream := MemStream;
OLEStorage.ReadOLEFile(AFileName, OLEDocument, 'Workbook');
// Can't be shared with BIFF5 because of the parameter "Workbook" !!!)
// Check if the operation succeded
if MemStream.Size = 0 then raise Exception.Create('[TsSpreadBIFF8Reader.ReadFromFile] Reading of OLE document failed');
// Rewind the stream and read from it
MemStream.Position := 0;
ReadFromStream(MemStream);
// Uncomment to verify if the data was correctly optained from the OLE file
// MemStream.SaveToFile(SysUtils.ChangeFileExt(AFileName, 'bin.xls'));
finally
MemStream.Free;
OLEStorage.Free;
end;
end;
*)
procedure TsSpreadBIFF8Reader.ReadFromStream(AStream: TStream);
procedure TsSpreadBIFF8Reader.ReadFromStream(AStream: TStream;
AParams: TsStreamParams = []);
var
OLEStream: TMemoryStream;
OLEStorage: TOLEStorage;
OLEDocument: TOLEDocument;
begin
Unused(AParams);
OLEStream := TMemoryStream.Create;
try
// Only one stream is necessary for any number of worksheets
@@ -2078,13 +2039,13 @@ end;
2 - Write the memory stream data to disk using COM functions
-------------------------------------------------------------------------------}
procedure TsSpreadBIFF8Writer.WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean; AParam: Integer = 0);
const AOverwriteExisting: Boolean; AParams: TsStreamParams = []);
var
Stream: TStream;
OutputStorage: TOLEStorage;
OLEDocument: TOLEDocument;
begin
Unused(AParam);
Unused(AParams);
if (boBufStream in Workbook.Options) then begin
Stream := TBufStream.Create
end else
@@ -2109,13 +2070,13 @@ end;
envelope of the document.
-------------------------------------------------------------------------------}
procedure TsSpreadBIFF8Writer.WriteToStream(AStream: TStream;
AParam: Integer = 0);
AParams: TsStreamParams = []);
var
OutputStorage: TOLEStorage;
OLEDocument: TOLEDocument;
stream: TStream;
begin
Unused(AParam);
Unused(AParams);
if (boBufStream in Workbook.Options) then
stream := TBufStream.Create else

View File

@@ -453,7 +453,6 @@ type
public
constructor Create(AWorkbook: TsWorkbook); override;
destructor Destroy; override;
procedure ReadFromClipboardStream(AStream: TStream); override;
end;
@@ -574,7 +573,6 @@ type
constructor Create(AWorkbook: TsWorkbook); override;
destructor Destroy; override;
procedure CheckLimitations; override;
procedure WriteToClipboardStream(AStream: TStream; AParam: Integer = 0); override;
end;
procedure AddBuiltinBiffFormats(AList: TStringList;
@@ -1336,16 +1334,6 @@ begin
FWorksheet.DefaultRowHeight := h - ROW_HEIGHT_CORRECTION;
end;
{@@ ----------------------------------------------------------------------------
Public specialized stream reading method for clipboard access.
For BIFF file format, data are stored in the clipboard in the same way as in
a regular stream/file.
-------------------------------------------------------------------------------}
procedure TsSpreadBIFFReader.ReadFromClipboardStream(AStream: TStream);
begin
ReadFromStream(AStream);
end;
{@@ ----------------------------------------------------------------------------
Reads the (number) FORMAT record for formatting numerical data
To be overridden by descendants.
@@ -4002,12 +3990,6 @@ begin
AStream.WriteWord(WordToLE(w));
end;
procedure TsSpreadBIFFWriter.WriteToClipboardStream(AStream: TStream;
AParam: Integer = 0);
begin
WriteToStream(AStream, AParam);
end;
procedure TsSpreadBIFFWriter.WriteVirtualCells(AStream: TStream);
var
r,c: Cardinal;

View File

@@ -69,8 +69,7 @@ type
public
constructor Create(AWorkbook: TsWorkbook); override;
// procedure WriteToFile(const AFileName: string; const AOverwriteExisting: Boolean = False); override;
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
@@ -736,40 +735,14 @@ begin
AppendToStream(AStream, TABLE_INDENT +
'</Table>' + LF);
end;
(*
{@@ ----------------------------------------------------------------------------
Writes an ExcelXML document to the file
-------------------------------------------------------------------------------}
procedure TsSpreadExcelXMLWriter.WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean);
var
stream: TStream;
mode: word;
begin
mode := fmCreate or fmShareDenyNone;
if AOverwriteExisting
then mode := mode or fmOpenWrite;
if (boBufStream in Workbook.Options) then
stream := TBufStream.Create(AFileName, mode)
else
stream := TFileStream.Create(AFileName, mode);
try
WriteToStream(stream);
finally
FreeAndNil(stream);
end;
end;
*)
{@@ ----------------------------------------------------------------------------
Writes an ExcelXML document to a stream
-------------------------------------------------------------------------------}
procedure TsSpreadExcelXMLWriter.WriteToStream(AStream: TStream;
AParam: Integer = 0);
AParams: TsStreamParams = []);
begin
Unused(AParam);
Unused(AParams);
AppendToStream(AStream,
'<?xml version="1.0"?>' + LF +

View File

@@ -99,8 +99,7 @@ type
public
constructor Create(AWorkbook: TsWorkbook); override;
destructor Destroy; override;
// procedure ReadFromFile(AFileName: string); override;
procedure ReadFromStream(AStream: TStream); override;
procedure ReadFromStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
{ TsSpreadOOXMLWriter }
@@ -189,11 +188,7 @@ type
constructor Create(AWorkbook: TsWorkbook); override;
{ General writing methods }
procedure WriteStringToFile(AFileName, AString: string);
{
procedure WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean = False; AParam: Integer = 0); override;
}
procedure WriteToStream(AStream: TStream; AParam: Integer = 0); override;
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
end;
@@ -1882,157 +1877,9 @@ begin
FixCols(AWorksheet);
FixRows(AWorksheet);
end;
(*
{ In principle, this method could be simplified by calling ReadFromStream which
is essentially a duplication of ReadFromFile. But ReadFromStream leads to
worse memory usage. --> KEEP READFROMFILE INTACT }
procedure TsSpreadOOXMLReader.ReadFromFile(AFilename: String);
var
Doc : TXMLDocument;
FilePath : string;
UnZip : TUnZipper;
FileList : TStringList;
SheetList: TStringList;
i: Integer;
fn: String;
fn_comments: String;
actSheetIndex: Integer;
begin
//unzip "content.xml" of "AFileName" to folder "FilePath"
FilePath := GetUniqueTempDir(false);
UnZip := TUnZipper.Create;
FileList := TStringList.Create;
try
FileList.Add(OOXML_PATH_XL_STYLES); // styles
FileList.Add(OOXML_PATH_XL_STRINGS); // sharedstrings
FileList.Add(OOXML_PATH_XL_WORKBOOK); // workbook
FileList.Add(OOXML_PATH_XL_THEME); // theme
UnZip.OutputPath := FilePath;
Unzip.UnZipFiles(AFileName,FileList);
finally
FreeAndNil(FileList);
FreeAndNil(UnZip);
end; //try
Doc := nil;
SheetList := TStringList.Create;
try
// Retrieve theme colors
if FileExists(FilePath + OOXML_PATH_XL_THEME) then begin
ReadXMLFile(Doc, FilePath + OOXML_PATH_XL_THEME);
DeleteFile(FilePath + OOXML_PATH_XL_THEME);
ReadThemeElements(Doc.DocumentElement.FindNode('a:themeElements'));
FreeAndNil(Doc);
end;
// process the workbook.xml file
if not FileExists(FilePath + OOXML_PATH_XL_WORKBOOK) then
raise Exception.CreateFmt(rsDefectiveInternalStructure, ['xlsx']);
ReadXMLFile(Doc, FilePath + OOXML_PATH_XL_WORKBOOK);
DeleteFile(FilePath + OOXML_PATH_XL_WORKBOOK);
ReadFileVersion(Doc.DocumentElement.FindNode('fileVersion'));
ReadDateMode(Doc.DocumentElement.FindNode('workbookPr'));
ReadSheetList(Doc.DocumentElement.FindNode('sheets'), SheetList);
ReadActiveSheet(Doc.DocumentElement.FindNode('bookViews'), actSheetIndex);
FreeAndNil(Doc);
// process the styles.xml file
if FileExists(FilePath + OOXML_PATH_XL_STYLES) then begin // should always exist, just to make sure...
ReadXMLFile(Doc, FilePath + OOXML_PATH_XL_STYLES);
DeleteFile(FilePath + OOXML_PATH_XL_STYLES);
ReadPalette(Doc.DocumentElement.FindNode('colors'));
ReadFonts(Doc.DocumentElement.FindNode('fonts'));
ReadFills(Doc.DocumentElement.FindNode('fills'));
ReadBorders(Doc.DocumentElement.FindNode('borders'));
ReadNumFormats(Doc.DocumentElement.FindNode('numFmts'));
ReadCellXfs(Doc.DocumentElement.FindNode('cellXfs'));
FreeAndNil(Doc);
end;
// process the sharedstrings.xml file
if FileExists(FilePath + OOXML_PATH_XL_STRINGS) then begin
ReadXMLFile(Doc, FilePath + OOXML_PATH_XL_STRINGS);
DeleteFile(FilePath + OOXML_PATH_XL_STRINGS);
ReadSharedStrings(Doc.DocumentElement.FindNode('si'));
FreeAndNil(Doc);
end;
// read worksheets
for i:=0 to SheetList.Count-1 do begin
// Create worksheet
FWorksheet := FWorkbook.AddWorksheet(SheetList[i], true);
// unzip sheet file
fn := OOXML_PATH_XL_WORKSHEETS + Format('sheet%d.xml', [i+1]);
UnzipFile(AFileName, fn, FilePath);
ReadXMLFile(Doc, FilePath + fn);
DeleteFile(FilePath + fn);
// Sheet data, formats, etc.
ReadSheetViews(Doc.DocumentElement.FindNode('sheetViews'), FWorksheet);
ReadSheetFormatPr(Doc.DocumentElement.FindNode('sheetFormatPr'), FWorksheet);
ReadCols(Doc.DocumentElement.FindNode('cols'), FWorksheet);
ReadWorksheet(Doc.DocumentElement.FindNode('sheetData'), FWorksheet);
ReadMergedCells(Doc.DocumentElement.FindNode('mergeCells'), FWorksheet);
ReadHyperlinks(Doc.DocumentElement.FindNode('hyperlinks'));
ReadPrintOptions(Doc.DocumentElement.FindNode('printOptions'), FWorksheet);
ReadPageMargins(Doc.DocumentElement.FindNode('pageMargins'), FWorksheet);
ReadPageSetup(Doc.DocumentElement.FindNode('pageSetup'), FWorksheet);
ReadHeaderFooter(Doc.DocumentElement.FindNode('headerFooter'), FWorksheet);
FreeAndNil(Doc);
// Comments:
// The comments are stored in separate "comments<n>.xml" files (n = 1, 2, ...)
// The relationship which comment belongs to which sheet file must be
// retrieved from the "sheet<n>.xml.rels" file (n = 1, 2, ...).
// The rels file contains also the second part of the hyperlink data.
fn := OOXML_PATH_XL_WORKSHEETS_RELS + Format('sheet%d.xml.rels', [i+1]);
UnzipFile(AFilename, fn, FilePath);
if FileExists(FilePath + fn) then begin
// find exact name of comments<n>.xml file
ReadXMLFile(Doc, FilePath + fn);
DeleteFile(FilePath + fn);
fn_comments := FindCommentsFileName(Doc.DocumentElement.FindNode('Relationship'));
ReadHyperlinks(Doc.DocumentElement.FindNode('Relationship'));
FreeAndNil(Doc);
end else
if (SheetList.Count = 1) then
// if the wookbook has only 1 sheet then the sheet.xml.rels file is missing
fn_comments := 'comments1.xml'
else
// this sheet does not have any cell comments
fn_comments := '';
//continue;
// Extract texts from the comments file found and apply to worksheet.
if fn_comments <> '' then
begin
fn := OOXML_PATH_XL + fn_comments;
UnzipFile(AFileName, fn, FilePath);
if FileExists(FilePath + fn) then begin
ReadXMLFile(Doc, FilePath + fn);
DeleteFile(FilePath + fn);
ReadComments(Doc.DocumentElement.FindNode('commentList'), FWorksheet);
FreeAndNil(Doc);
end;
end;
// Add hyperlinks to cells
ApplyHyperlinks(FWorksheet);
// Active worksheet
if i = actSheetIndex then
FWorkbook.SelectWorksheet(FWorksheet);
end; // for
finally
RemoveDir(FilePath);
SheetList.Free;
FreeAndNil(Doc);
end;
end;
*)
procedure TsSpreadOOXMLReader.ReadFromStream(AStream: TStream);
procedure TsSpreadOOXMLReader.ReadFromStream(AStream: TStream;
AParams: TsStreamParams = []);
var
Doc : TXMLDocument;
RelsNode: TDOMNode;
@@ -2055,6 +1902,7 @@ var
end;
begin
Unused(AParams);
Doc := nil;
SheetList := TStringList.Create;
try
@@ -3719,41 +3567,16 @@ begin
end;
end;
(*
{@@ ----------------------------------------------------------------------------
Writes an OOXML document to the file
-------------------------------------------------------------------------------}
procedure TsSpreadOOXMLWriter.WriteToFile(const AFileName: string;
const AOverwriteExisting: Boolean; AParam: Integer = 0);
var
lStream: TStream;
lMode: word;
begin
if AOverwriteExisting
then lMode := fmCreate or fmOpenWrite
else lMode := fmCreate;
if (boBufStream in Workbook.Options) then
lStream := TBufStream.Create(AFileName, lMode)
else
lStream := TFileStream.Create(AFileName, lMode);
try
WriteToStream(lStream, AParam);
finally
FreeAndNil(lStream);
end;
end;
*)
{@@ ----------------------------------------------------------------------------
Writes an OOXML document to a stream
-------------------------------------------------------------------------------}
procedure TsSpreadOOXMLWriter.WriteToStream(AStream: TStream;
AParam: Integer = 0);
AParams: TsStreamParams = []);
var
FZip: TZipper;
i: Integer;
begin
Unused(AParam);
Unused(AParams);
{ Analyze the workbook and collect all information needed }
ListAllNumFormats;