Initial commit of fpspreadsheet.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@362 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
a736e0a50d
commit
4f04afdb1c
2
components/fpspreadsheet/builddoc.bat
Executable file
2
components/fpspreadsheet/builddoc.bat
Executable file
@ -0,0 +1,2 @@
|
||||
"C:\Program Files\Doc-O-Matic 6 Express\domexpress.exe" -config "HTML Help" fpspreadsheet.dox-express
|
||||
pause
|
251
components/fpspreadsheet/examples/excel5demo/excel5demo.lpi
Executable file
251
components/fpspreadsheet/examples/excel5demo/excel5demo.lpi
Executable file
@ -0,0 +1,251 @@
|
||||
<?xml version="1.0"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<PathDelim Value="\"/>
|
||||
<Version Value="6"/>
|
||||
<General>
|
||||
<MainUnit Value="0"/>
|
||||
<IconPath Value="./"/>
|
||||
<TargetFileExt Value=".exe"/>
|
||||
<ActiveEditorIndexAtStart Value="1"/>
|
||||
</General>
|
||||
<VersionInfo>
|
||||
<ProjectVersion Value=""/>
|
||||
<Language Value=""/>
|
||||
<CharSet Value=""/>
|
||||
</VersionInfo>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<IgnoreBinaries Value="False"/>
|
||||
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<local>
|
||||
<FormatVersion Value="1"/>
|
||||
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
|
||||
</local>
|
||||
</RunParams>
|
||||
<Units Count="15">
|
||||
<Unit0>
|
||||
<Filename Value="excel5demo.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="excel5demo"/>
|
||||
<CursorPos X="5" Y="12"/>
|
||||
<TopLine Value="1"/>
|
||||
<EditorIndex Value="0"/>
|
||||
<UsageCount Value="49"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<UnitName Value="fpspreadsheet"/>
|
||||
<CursorPos X="32" Y="414"/>
|
||||
<TopLine Value="388"/>
|
||||
<EditorIndex Value="1"/>
|
||||
<UsageCount Value="25"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<UnitName Value="xlsbiff5"/>
|
||||
<CursorPos X="16" Y="320"/>
|
||||
<TopLine Value="300"/>
|
||||
<EditorIndex Value="4"/>
|
||||
<UsageCount Value="25"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="C:\Programas\FPC220\source\packages\base\winunits\activex.pp"/>
|
||||
<UnitName Value="ActiveX"/>
|
||||
<CursorPos X="27" Y="29"/>
|
||||
<TopLine Value="6"/>
|
||||
<UsageCount Value="9"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="..\fpolestorage.pas"/>
|
||||
<UnitName Value="fpolestorage"/>
|
||||
<CursorPos X="1" Y="1"/>
|
||||
<TopLine Value="1"/>
|
||||
<EditorIndex Value="5"/>
|
||||
<UsageCount Value="45"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit4>
|
||||
<Unit5>
|
||||
<Filename Value="C:\Programas\FPC220\source\rtl\inc\objpash.inc"/>
|
||||
<CursorPos X="21" Y="141"/>
|
||||
<TopLine Value="131"/>
|
||||
<UsageCount Value="9"/>
|
||||
</Unit5>
|
||||
<Unit6>
|
||||
<Filename Value="..\xlsbiff2.pas"/>
|
||||
<UnitName Value="xlsbiff2"/>
|
||||
<CursorPos X="20" Y="277"/>
|
||||
<TopLine Value="260"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<UsageCount Value="18"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit6>
|
||||
<Unit7>
|
||||
<Filename Value="C:\Programas\FPC220\source\rtl\objpas\classes\classesh.inc"/>
|
||||
<CursorPos X="22" Y="1602"/>
|
||||
<TopLine Value="1598"/>
|
||||
<UsageCount Value="11"/>
|
||||
</Unit7>
|
||||
<Unit8>
|
||||
<Filename Value="C:\Programas\FPC220\source\rtl\win32\buildrtl.pp"/>
|
||||
<UnitName Value="buildrtl"/>
|
||||
<CursorPos X="29" Y="5"/>
|
||||
<TopLine Value="1"/>
|
||||
<UsageCount Value="9"/>
|
||||
</Unit8>
|
||||
<Unit9>
|
||||
<Filename Value="C:\Programas\FPC220\source\rtl\objpas\fgl.pp"/>
|
||||
<UnitName Value="fgl"/>
|
||||
<CursorPos X="15" Y="86"/>
|
||||
<TopLine Value="55"/>
|
||||
<EditorIndex Value="7"/>
|
||||
<UsageCount Value="18"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit9>
|
||||
<Unit10>
|
||||
<Filename Value="C:\Programas\lazarus\lcl\interfaces\win32\win32wsstdctrls.pp"/>
|
||||
<UnitName Value="Win32WSStdCtrls"/>
|
||||
<CursorPos X="11" Y="737"/>
|
||||
<TopLine Value="713"/>
|
||||
<EditorIndex Value="6"/>
|
||||
<UsageCount Value="14"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit10>
|
||||
<Unit11>
|
||||
<Filename Value="C:\Programas\lazarus\lcl\interfaces\win32\win32wscontrols.pp"/>
|
||||
<UnitName Value="Win32WSControls"/>
|
||||
<CursorPos X="13" Y="206"/>
|
||||
<TopLine Value="199"/>
|
||||
<UsageCount Value="12"/>
|
||||
</Unit11>
|
||||
<Unit12>
|
||||
<Filename Value="C:\Programas\lazarus\components\sqlite\registersqlite3.pas"/>
|
||||
<UnitName Value="registersqlite3"/>
|
||||
<CursorPos X="15" Y="5"/>
|
||||
<TopLine Value="1"/>
|
||||
<UsageCount Value="11"/>
|
||||
</Unit12>
|
||||
<Unit13>
|
||||
<Filename Value="C:\Programas\lazarus\ideintf\componenteditors.pas"/>
|
||||
<UnitName Value="ComponentEditors"/>
|
||||
<CursorPos X="54" Y="353"/>
|
||||
<TopLine Value="330"/>
|
||||
<EditorIndex Value="3"/>
|
||||
<UsageCount Value="12"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit13>
|
||||
<Unit14>
|
||||
<Filename Value="C:\Programas\FPC220\source\rtl\objpas\classes\cregist.inc"/>
|
||||
<CursorPos X="17" Y="124"/>
|
||||
<TopLine Value="121"/>
|
||||
<UsageCount Value="11"/>
|
||||
</Unit14>
|
||||
</Units>
|
||||
<JumpHistory Count="21" HistoryIndex="20">
|
||||
<Position1>
|
||||
<Filename Value="C:\Programas\FPC220\source\rtl\objpas\fgl.pp"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="C:\Programas\lazarus\lcl\interfaces\win32\win32wsstdctrls.pp"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="C:\Programas\lazarus\lcl\interfaces\win32\win32wsstdctrls.pp"/>
|
||||
<Caret Line="737" Column="11" TopLine="713"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="C:\Programas\lazarus\ideintf\componenteditors.pas"/>
|
||||
<Caret Line="353" Column="54" TopLine="330"/>
|
||||
</Position4>
|
||||
<Position5>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="335" Column="1" TopLine="318"/>
|
||||
</Position5>
|
||||
<Position6>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<Caret Line="601" Column="1" TopLine="559"/>
|
||||
</Position6>
|
||||
<Position7>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<Caret Line="1" Column="1" TopLine="1"/>
|
||||
</Position7>
|
||||
<Position8>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<Caret Line="601" Column="1" TopLine="559"/>
|
||||
</Position8>
|
||||
<Position9>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<Caret Line="612" Column="1" TopLine="573"/>
|
||||
</Position9>
|
||||
<Position10>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="61" Column="12" TopLine="44"/>
|
||||
</Position10>
|
||||
<Position11>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="68" Column="17" TopLine="45"/>
|
||||
</Position11>
|
||||
<Position12>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="216" Column="15" TopLine="193"/>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="221" Column="15" TopLine="198"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="334" Column="16" TopLine="311"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="345" Column="37" TopLine="322"/>
|
||||
</Position15>
|
||||
<Position16>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="332" Column="22" TopLine="311"/>
|
||||
</Position16>
|
||||
<Position17>
|
||||
<Filename Value="..\xlsbiff5.pas"/>
|
||||
<Caret Line="351" Column="28" TopLine="298"/>
|
||||
</Position17>
|
||||
<Position18>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<Caret Line="190" Column="13" TopLine="167"/>
|
||||
</Position18>
|
||||
<Position19>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<Caret Line="189" Column="1" TopLine="167"/>
|
||||
</Position19>
|
||||
<Position20>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<Caret Line="594" Column="1" TopLine="552"/>
|
||||
</Position20>
|
||||
<Position21>
|
||||
<Filename Value="..\fpspreadsheet.pas"/>
|
||||
<Caret Line="164" Column="1" TopLine="156"/>
|
||||
</Position21>
|
||||
</JumpHistory>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="5"/>
|
||||
<PathDelim Value="\"/>
|
||||
<SearchPaths>
|
||||
<OtherUnitFiles Value="..\"/>
|
||||
<SrcPath Value="..\"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<Generate Value="Faster"/>
|
||||
</CodeGeneration>
|
||||
<Other>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
</CONFIG>
|
59
components/fpspreadsheet/examples/excel5demo/excel5demo.lpr
Executable file
59
components/fpspreadsheet/examples/excel5demo/excel5demo.lpr
Executable file
@ -0,0 +1,59 @@
|
||||
{
|
||||
excel5demo.dpr
|
||||
|
||||
Demonstrates how to write an Excel 5.x file using the fpspreadsheet library
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
}
|
||||
program excel5demo;
|
||||
|
||||
{$mode delphi}{$H+}
|
||||
|
||||
uses
|
||||
Classes, SysUtils, fpspreadsheet, xlsbiff5;
|
||||
|
||||
var
|
||||
MyWorkbook: TsWorkbook;
|
||||
MyWorksheet: TsWorksheet;
|
||||
MyFormula: TRPNFormula;
|
||||
MyDir: string;
|
||||
begin
|
||||
// Open the output file
|
||||
MyDir := ExtractFilePath(ParamStr(0));
|
||||
|
||||
// Create the spreadsheet
|
||||
MyWorkbook := TsWorkbook.Create;
|
||||
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet');
|
||||
|
||||
// Write some number cells
|
||||
MyWorksheet.WriteNumber(0, 0, 1.0);
|
||||
MyWorksheet.WriteNumber(0, 1, 2.0);
|
||||
MyWorksheet.WriteNumber(0, 2, 3.0);
|
||||
MyWorksheet.WriteNumber(0, 3, 4.0);
|
||||
|
||||
// Write the formula E1 = A1 + B1
|
||||
// or, in RPN: A1, B1, +
|
||||
SetLength(MyFormula, 3);
|
||||
MyFormula[0].TokenID := INT_EXCEL_TOKEN_TREFV; {A1}
|
||||
MyFormula[0].Col := 0;
|
||||
MyFormula[0].Row := 0;
|
||||
MyFormula[1].TokenID := INT_EXCEL_TOKEN_TREFV; {B1}
|
||||
MyFormula[1].Col := 1;
|
||||
MyFormula[1].Row := 0;
|
||||
MyFormula[2].TokenID := INT_EXCEL_TOKEN_TADD; {+}
|
||||
MyWorksheet.WriteRPNFormula(0, 4, MyFormula);
|
||||
|
||||
// Creates a new worksheet
|
||||
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2');
|
||||
|
||||
// Write some string cells
|
||||
MyWorksheet.WriteAnsiText(0, 0, 'First');
|
||||
MyWorksheet.WriteAnsiText(0, 1, 'Second');
|
||||
MyWorksheet.WriteAnsiText(0, 2, 'Third');
|
||||
MyWorksheet.WriteAnsiText(0, 3, 'Fourth');
|
||||
|
||||
// Save the spreadsheet to a file
|
||||
MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel5);
|
||||
MyWorkbook.Free;
|
||||
end.
|
||||
|
78
components/fpspreadsheet/fpolestorage.pas
Executable file
78
components/fpspreadsheet/fpolestorage.pas
Executable file
@ -0,0 +1,78 @@
|
||||
{
|
||||
fpolestorage.pas
|
||||
|
||||
Writes an OLE document
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
}
|
||||
unit fpolestorage;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
{$endif}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
{$ifdef Windows}
|
||||
ActiveX, ComObj,
|
||||
{$endif}
|
||||
Classes, SysUtils;
|
||||
|
||||
type
|
||||
|
||||
{ TOLEStorage }
|
||||
|
||||
TOLEStorage = class
|
||||
private
|
||||
{$ifdef Windows}
|
||||
FStorage: IStorage;
|
||||
FStream: IStream;
|
||||
{$endif}
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure WriteStreamToOLEFile(AFileName: string; AMemStream: TMemoryStream);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TOLEStorage }
|
||||
|
||||
constructor TOLEStorage.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
end;
|
||||
|
||||
destructor TOLEStorage.Destroy;
|
||||
begin
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TOLEStorage.WriteStreamToOLEFile(AFileName: string; AMemStream: TMemoryStream);
|
||||
var
|
||||
cbWritten: Cardinal;
|
||||
begin
|
||||
{$ifdef Windows}
|
||||
{ Initialize the Component Object Model (COM) before calling s functions }
|
||||
OleCheck(CoInitialize(nil));
|
||||
|
||||
{ Create a Storage Object }
|
||||
OleCheck(StgCreateDocfile(PWideChar(WideString(AFileName)),
|
||||
STGM_READWRITE or STGM_FAILIFTHERE or STGM_SHARE_EXCLUSIVE or STGM_DIRECT,
|
||||
0, FStorage));
|
||||
|
||||
{ Create a workbook stream in the storage. A BIFF5 file must
|
||||
have at least a workbook stream. This stream *must* be named 'Book' }
|
||||
OleCheck(FStorage.CreateStream('Book',
|
||||
STGM_READWRITE or STGM_SHARE_EXCLUSIVE or STGM_DIRECT, 0, 0, FStream));
|
||||
|
||||
{ Write all data }
|
||||
FStream.Write(AMemStream.Memory, AMemStream.Size, @cbWritten);
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
end.
|
||||
|
18
components/fpspreadsheet/fpsallformats.pas
Executable file
18
components/fpspreadsheet/fpsallformats.pas
Executable file
@ -0,0 +1,18 @@
|
||||
{
|
||||
fpsallformats.pas
|
||||
|
||||
Unit to quickly add all supported fpspreadsheet formats to the project
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
}
|
||||
unit fpsallformats;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
xlsbiff2, xlsbiff5;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
407
components/fpspreadsheet/fpsopendocument.pas
Executable file
407
components/fpspreadsheet/fpsopendocument.pas
Executable file
@ -0,0 +1,407 @@
|
||||
{
|
||||
fpsopendocument.pas
|
||||
|
||||
Writes an OpenDocument 1.0 Spreadsheet document
|
||||
|
||||
An OpenDocument document is a compressed ZIP file with the following files inside:
|
||||
|
||||
content.xml
|
||||
meta.xml
|
||||
settings.xml
|
||||
styles.xml
|
||||
META-INF\manifest.xml
|
||||
|
||||
Specifications obtained from:
|
||||
|
||||
write url here
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
|
||||
IMPORTANT: This writer doesn't work yet!!! This is just initial code.
|
||||
}
|
||||
unit fpsopendocument;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
{$endif}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, {zipper,}
|
||||
fpspreadsheet;
|
||||
|
||||
type
|
||||
|
||||
{ TsSpreadOpenDocWriter }
|
||||
|
||||
TsSpreadOpenDocWriter = class(TsCustomSpreadWriter)
|
||||
protected
|
||||
// FZip: TZipper;
|
||||
FMetaInfManifest: string;
|
||||
FMeta, FSettings, FStyles: string;
|
||||
FContent: string;
|
||||
public
|
||||
{ General writing methods }
|
||||
procedure WriteStringToFile(AFileName, AString: string);
|
||||
procedure WriteToFile(AFileName: string; AData: TsWorkbook); override;
|
||||
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); override;
|
||||
{ Record writing methods }
|
||||
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override;
|
||||
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
{ OpenDocument general XML constants }
|
||||
XML_HEADER = '<?xml version="1.0" encoding="utf-8" ?>';
|
||||
|
||||
{ OpenDocument Directory structure constants }
|
||||
OOXML_PATH_CONTENT = 'content.xml';
|
||||
OOXML_PATH_META = 'meta.xml';
|
||||
OOXML_PATH_SETTINGS = 'settings.xml';
|
||||
OOXML_PATH_STYLES = 'styles.xml';
|
||||
OPENDOC_PATH_METAINF = 'META-INF\';
|
||||
OPENDOC_PATH_METAINF_MANIFEST = 'META-INF\manifest.xml';
|
||||
|
||||
{ OpenDocument schemas constants }
|
||||
SCHEMAS_XMLNS_OFFICE = 'urn:oasis:names:tc:opendocument:xmlns:office:1.0';
|
||||
SCHEMAS_XMLNS_DCTERMS = 'http://purl.org/dc/terms/';
|
||||
SCHEMAS_XMLNS_META = 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0';
|
||||
SCHEMAS_XMLNS = 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties';
|
||||
SCHEMAS_XMLNS_CONFIG = 'urn:oasis:names:tc:opendocument:xmlns:config:1.0';
|
||||
SCHEMAS_XMLNS_OOO = 'http://openoffice.org/2004/office';
|
||||
SCHEMAS_XMLNS_MANIFEST = 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0';
|
||||
SCHEMAS_XMLNS_FO = 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0';
|
||||
SCHEMAS_XMLNS_STYLE = 'urn:oasis:names:tc:opendocument:xmlns:style:1.0';
|
||||
SCHEMAS_XMLNS_SVG = 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0';
|
||||
SCHEMAS_XMLNS_TABLE = 'urn:oasis:names:tc:opendocument:xmlns:table:1.0';
|
||||
SCHEMAS_XMLNS_TEXT = 'urn:oasis:names:tc:opendocument:xmlns:text:1.0';
|
||||
SCHEMAS_XMLNS_V = 'urn:schemas-microsoft-com:vml';
|
||||
SCHEMAS_XMLNS_NUMBER = 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0';
|
||||
SCHEMAS_XMLNS_CHART = 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0';
|
||||
SCHEMAS_XMLNS_DR3D = 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0';
|
||||
SCHEMAS_XMLNS_MATH = 'http://www.w3.org/1998/Math/MathML';
|
||||
SCHEMAS_XMLNS_FORM = 'urn:oasis:names:tc:opendocument:xmlns:form:1.0';
|
||||
SCHEMAS_XMLNS_SCRIPT = 'urn:oasis:names:tc:opendocument:xmlns:script:1.0';
|
||||
SCHEMAS_XMLNS_OOOW = 'http://openoffice.org/2004/writer';
|
||||
SCHEMAS_XMLNS_OOOC = 'http://openoffice.org/2004/calc';
|
||||
SCHEMAS_XMLNS_DOM = 'http://www.w3.org/2001/xml-events';
|
||||
SCHEMAS_XMLNS_XFORMS = 'http://www.w3.org/2002/xforms';
|
||||
SCHEMAS_XMLNS_XSD = 'http://www.w3.org/2001/XMLSchema';
|
||||
SCHEMAS_XMLNS_XSI = 'http://www.w3.org/2001/XMLSchema-instance';
|
||||
|
||||
{ TsSpreadOpenDocWriter }
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteStringToFile ()
|
||||
*
|
||||
* DESCRIPTION: Writes a string to a file. Helper convenience method.
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOpenDocWriter.WriteStringToFile(AFileName, AString: string);
|
||||
var
|
||||
TheStream : TFileStream;
|
||||
S : String;
|
||||
begin
|
||||
TheStream := TFileStream.Create(AFileName, fmCreate);
|
||||
S:=AString;
|
||||
TheStream.WriteBuffer(Pointer(S)^,Length(S));
|
||||
TheStream.Free;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteToFile ()
|
||||
*
|
||||
* DESCRIPTION: Writes an OOXML document to the disc
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOpenDocWriter.WriteToFile(AFileName: string; AData: TsWorkbook);
|
||||
var
|
||||
TempDir: string;
|
||||
begin
|
||||
{FZip := TZipper.Create;
|
||||
FZip.ZipFiles(AFileName, x);
|
||||
FZip.Free;}
|
||||
|
||||
WriteToStream(nil, AData);
|
||||
|
||||
TempDir := IncludeTrailingBackslash(AFileName);
|
||||
|
||||
{ files on the root path }
|
||||
|
||||
ForceDirectories(TempDir);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_CONTENT, FContent);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_META, FMeta);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_SETTINGS, FSettings);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_STYLES, FStyles);
|
||||
|
||||
{ META-INF directory }
|
||||
|
||||
ForceDirectories(TempDir + OPENDOC_PATH_METAINF);
|
||||
|
||||
WriteStringToFile(TempDir + OPENDOC_PATH_METAINF_MANIFEST, FMetaInfManifest);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteToStream ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 file to a stream
|
||||
*
|
||||
* Excel 2.x files support only one Worksheet per Workbook,
|
||||
* so only the first will be written.
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOpenDocWriter.WriteToStream(AStream: TStream; AData: TsWorkbook);
|
||||
begin
|
||||
// WriteCellsToStream(AStream, AData.GetFirstWorksheet.FCells);
|
||||
|
||||
FMetaInfManifest :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<manifest:manifest xmlns:manifest="' + SCHEMAS_XMLNS_MANIFEST + '">' + LineEnding +
|
||||
' <manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.spreadsheet" manifest:full-path="/" />' + LineEnding +
|
||||
' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml" />' + LineEnding +
|
||||
' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml" />' + LineEnding +
|
||||
' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="meta.xml" />' + LineEnding +
|
||||
' <manifest:file-entry manifest:media-type="text/xml" manifest:full-path="settings.xml" />' + LineEnding +
|
||||
'</manifest:manifest>';
|
||||
|
||||
FMeta :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<office:document-meta xmlns:office="' + SCHEMAS_XMLNS_OFFICE +
|
||||
'" xmlns:dcterms="' + SCHEMAS_XMLNS_DCTERMS +
|
||||
'" xmlns:meta="' + SCHEMAS_XMLNS_META +
|
||||
'" xmlns="' + SCHEMAS_XMLNS +
|
||||
'" xmlns:ex="' + SCHEMAS_XMLNS + '">' + LineEnding +
|
||||
' <office:meta>' + LineEnding +
|
||||
' <meta:generator>FPSpreadsheet Library</meta:generator>' + LineEnding +
|
||||
' <meta:document-statistic />' + LineEnding +
|
||||
' </office:meta>' + LineEnding +
|
||||
'</office:document-meta>';
|
||||
|
||||
FSettings :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<office:document-settings xmlns:office="' + SCHEMAS_XMLNS_OFFICE +
|
||||
'" xmlns:config="' + SCHEMAS_XMLNS_CONFIG +
|
||||
'" xmlns:ooo="' + SCHEMAS_XMLNS_OOO + '">' + LineEnding +
|
||||
'<office:settings>' + LineEnding +
|
||||
' <config:config-item-set config:name="ooo:view-settings">' + LineEnding +
|
||||
' <config:config-item-map-indexed config:name="Views">' + LineEnding +
|
||||
' <config:config-item-map-entry>' + LineEnding +
|
||||
' <config:config-item config:name="ActiveTable" config:type="string">Tabelle1</config:config-item>' + LineEnding +
|
||||
' <config:config-item config:name="ZoomValue" config:type="int">100</config:config-item>' + LineEnding +
|
||||
' <config:config-item config:name="PageViewZoomValue" config:type="int">100</config:config-item>' + LineEnding +
|
||||
' <config:config-item config:name="ShowPageBreakPreview" config:type="boolean">false</config:config-item>' + LineEnding +
|
||||
' <config:config-item config:name="HasColumnRowHeaders" config:type="boolean">true</config:config-item>' + LineEnding +
|
||||
' <config:config-item-map-named config:name="Tables">' + LineEnding +
|
||||
' <config:config-item-map-entry config:name="Tabelle1">' + LineEnding +
|
||||
' <config:config-item config:name="CursorPositionX" config:type="int">3</config:config-item>' + LineEnding +
|
||||
' <config:config-item config:name="CursorPositionY" config:type="int">2</config:config-item>' + LineEnding +
|
||||
' </config:config-item-map-entry>' + LineEnding +
|
||||
' </config:config-item-map-named>' + LineEnding +
|
||||
' </config:config-item-map-entry>' + LineEnding +
|
||||
' </config:config-item-map-indexed>' + LineEnding +
|
||||
' </config:config-item-set>' + LineEnding +
|
||||
' </office:settings>' + LineEnding +
|
||||
'</office:document-settings>';
|
||||
|
||||
FStyles :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<office:document-styles xmlns:office="' + SCHEMAS_XMLNS_OFFICE +
|
||||
'" xmlns:fo="' + SCHEMAS_XMLNS_FO +
|
||||
'" xmlns:style="' + SCHEMAS_XMLNS_STYLE +
|
||||
'" xmlns:svg="' + SCHEMAS_XMLNS_SVG +
|
||||
'" xmlns:table="' + SCHEMAS_XMLNS_TABLE +
|
||||
'" xmlns:text="' + SCHEMAS_XMLNS_TEXT +
|
||||
'" xmlns:v="' + SCHEMAS_XMLNS_V + '">' + LineEnding +
|
||||
'<office:font-face-decls>' + LineEnding +
|
||||
'<style:font-face style:name="Arial" svg:font-family="Arial" />' + LineEnding +
|
||||
'</office:font-face-decls>' + LineEnding +
|
||||
'<office:styles>' + LineEnding +
|
||||
'<style:style style:name="Default" style:family="table-cell">' + LineEnding +
|
||||
'<style:text-properties fo:font-size="10" style:font-name="Arial" />' + LineEnding +
|
||||
'</style:style>' + LineEnding +
|
||||
'</office:styles>' + LineEnding +
|
||||
'<office:automatic-styles>' + LineEnding +
|
||||
'<style:page-layout style:name="pm1">' + LineEnding +
|
||||
'<style:page-layout-properties fo:margin-top="1.25cm" fo:margin-bottom="1.25cm" fo:margin-left="1.905cm" fo:margin-right="1.905cm" />' + LineEnding +
|
||||
'<style:header-style>' + LineEnding +
|
||||
'<style:header-footer-properties fo:min-height="0.751cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-bottom="0.25cm" fo:margin-top="0cm" />' + LineEnding +
|
||||
'</style:header-style>' + LineEnding +
|
||||
'<style:footer-style>' + LineEnding +
|
||||
'<style:header-footer-properties fo:min-height="0.751cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0.25cm" fo:margin-bottom="0cm" />' + LineEnding +
|
||||
'</style:footer-style>' + LineEnding +
|
||||
'</style:page-layout>' + LineEnding +
|
||||
'</office:automatic-styles>' + LineEnding +
|
||||
'<office:master-styles>' + LineEnding +
|
||||
'<style:master-page style:name="Default" style:page-layout-name="pm1">' + LineEnding +
|
||||
'<style:header />' + LineEnding +
|
||||
'<style:header-left style:display="false" />' + LineEnding +
|
||||
'<style:footer />' + LineEnding +
|
||||
'<style:footer-left style:display="false" />' + LineEnding +
|
||||
'</style:master-page>' + LineEnding +
|
||||
'</office:master-styles>' + LineEnding +
|
||||
'</office:document-styles>';
|
||||
|
||||
FContent :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<office:document-content xmlns:office="' + SCHEMAS_XMLNS_OFFICE +
|
||||
'" xmlns:fo="' + SCHEMAS_XMLNS_FO +
|
||||
'" xmlns:style="' + SCHEMAS_XMLNS_STYLE +
|
||||
'" xmlns:text="' + SCHEMAS_XMLNS_TEXT +
|
||||
'" xmlns:table="' + SCHEMAS_XMLNS_TABLE +
|
||||
'" xmlns:svg="' + SCHEMAS_XMLNS_SVG +
|
||||
'" xmlns:number="' + SCHEMAS_XMLNS_NUMBER +
|
||||
'" xmlns:meta="' + SCHEMAS_XMLNS_META +
|
||||
'" xmlns:chart="' + SCHEMAS_XMLNS_CHART +
|
||||
'" xmlns:dr3d="' + SCHEMAS_XMLNS_DR3D +
|
||||
'" xmlns:math="' + SCHEMAS_XMLNS_MATH +
|
||||
'" xmlns:form="' + SCHEMAS_XMLNS_FORM +
|
||||
'" xmlns:script="' + SCHEMAS_XMLNS_SCRIPT +
|
||||
'" xmlns:ooo="' + SCHEMAS_XMLNS_OOO +
|
||||
'" xmlns:ooow="' + SCHEMAS_XMLNS_OOOW +
|
||||
'" xmlns:oooc="' + SCHEMAS_XMLNS_OOOC +
|
||||
'" xmlns:dom="' + SCHEMAS_XMLNS_DOM +
|
||||
'" xmlns:xforms="' + SCHEMAS_XMLNS_XFORMS +
|
||||
'" xmlns:xsd="' + SCHEMAS_XMLNS_XSD +
|
||||
'" xmlns:xsi="' + SCHEMAS_XMLNS_XSI + '">' + LineEnding +
|
||||
'<office:scripts />' + LineEnding +
|
||||
'<office:font-face-decls>' + LineEnding +
|
||||
'<style:font-face style:name="Arial" svg:font-family="Arial" xmlns:v="urn:schemas-microsoft-com:vml" />' + LineEnding +
|
||||
'</office:font-face-decls>' + LineEnding +
|
||||
'<office:automatic-styles>' + LineEnding +
|
||||
'<style:style style:name="ID0EM" style:family="table-column" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding +
|
||||
'<style:table-column-properties fo:break-before="auto" style:column-width="1.961cm" />' + LineEnding +
|
||||
'</style:style>' + LineEnding +
|
||||
'<style:style style:name="ID0EM" style:family="table-row" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding +
|
||||
'<style:table-row-properties fo:break-before="auto" style:row-height="0.45cm" />' + LineEnding +
|
||||
'</style:style>' + LineEnding +
|
||||
'<style:style style:name="ID1E6B" style:family="table-cell" style:parent-style-name="Default" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding +
|
||||
'<style:text-properties fo:font-size="10" style:font-name="Arial" />' + LineEnding +
|
||||
'</style:style>' + LineEnding +
|
||||
'<style:style style:name="ID2EY" style:family="table" style:master-page-name="Default" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding +
|
||||
'<style:table-properties />' + LineEnding +
|
||||
'</style:style>' + LineEnding +
|
||||
'<style:style style:name="scenario" style:family="table" style:master-page-name="Default">' + LineEnding +
|
||||
'<style:table-properties table:display="false" style:writing-mode="lr-tb" />' + LineEnding +
|
||||
'</style:style>' + LineEnding +
|
||||
'</office:automatic-styles>' + LineEnding +
|
||||
'<office:body>' + LineEnding +
|
||||
'<office:spreadsheet>' + LineEnding +
|
||||
'<table:table table:name="Tabelle1" table:style-name="ID2EY">' + LineEnding +
|
||||
'<table:table-column table:style-name="ID0EM" table:number-columns-repeated="256" table:default-cell-style-name="ID1E6B" xmlns:v="urn:schemas-microsoft-com:vml" />' + LineEnding +
|
||||
'<table:table-row table:style-name="ID0EM" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding +
|
||||
'<table:table-cell office:value-type="float" office:value="1">' + LineEnding +
|
||||
'<text:p>1</text:p>' + LineEnding +
|
||||
'</table:table-cell>' + LineEnding +
|
||||
'<table:table-cell office:value-type="float" office:value="2">' + LineEnding +
|
||||
'<text:p>2</text:p>' + LineEnding +
|
||||
'</table:table-cell>' + LineEnding +
|
||||
'<table:table-cell office:value-type="float" office:value="3">' + LineEnding +
|
||||
'<text:p>3</text:p>' + LineEnding +
|
||||
'</table:table-cell>' + LineEnding +
|
||||
'<table:table-cell office:value-type="float" office:value="4">' + LineEnding +
|
||||
'<text:p>4</text:p>' + LineEnding +
|
||||
'</table:table-cell>' + LineEnding +
|
||||
'<table:table-cell table:number-columns-repeated="252" />' + LineEnding +
|
||||
'</table:table-row>' + LineEnding +
|
||||
'<table:table-row table:style-name="ID0EM" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding +
|
||||
'<table:table-cell office:value-type="string">' + LineEnding +
|
||||
'<text:p>First</text:p>' + LineEnding +
|
||||
'</table:table-cell>' + LineEnding +
|
||||
'<table:table-cell office:value-type="string">' + LineEnding +
|
||||
'<text:p>Second</text:p>' + LineEnding +
|
||||
'</table:table-cell>' + LineEnding +
|
||||
'<table:table-cell office:value-type="string">' + LineEnding +
|
||||
'<text:p>Third</text:p>' + LineEnding +
|
||||
'</table:table-cell>' + LineEnding +
|
||||
'<table:table-cell office:value-type="string">' + LineEnding +
|
||||
'<text:p>Fourth</text:p>' + LineEnding +
|
||||
'</table:table-cell>' + LineEnding +
|
||||
'<table:table-cell table:number-columns-repeated="252" />' + LineEnding +
|
||||
'</table:table-row>' + LineEnding +
|
||||
'</table:table>' + LineEnding +
|
||||
'<table:database-ranges />' + LineEnding +
|
||||
'</office:spreadsheet>' + LineEnding +
|
||||
'</office:body>' + LineEnding +
|
||||
'</office:document-content>';
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteLabel ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 LABEL record
|
||||
*
|
||||
* Writes a string to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOpenDocWriter.WriteLabel(AStream: TStream; const ARow,
|
||||
ACol: Word; const AValue: string);
|
||||
var
|
||||
L: Byte;
|
||||
begin
|
||||
L := Length(AValue);
|
||||
|
||||
{ BIFF Record header }
|
||||
// AStream.WriteWord(WordToLE(INT_EXCEL_ID_LABEL));
|
||||
// AStream.WriteWord(WordToLE(8 + L));
|
||||
|
||||
{ BIFF Record data }
|
||||
// AStream.WriteWord(WordToLE(ARow));
|
||||
// AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ String with 8-bit size }
|
||||
AStream.WriteByte(L);
|
||||
AStream.WriteBuffer(AValue[1], L);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteNumber ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 NUMBER record
|
||||
*
|
||||
* Writes a number (64-bit IEE 754 floating point) to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOpenDocWriter.WriteNumber(AStream: TStream; const ARow,
|
||||
ACol: Cardinal; const AValue: double);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
// AStream.WriteWord(WordToLE(INT_EXCEL_ID_NUMBER));
|
||||
// AStream.WriteWord(WordToLE(15));
|
||||
|
||||
{ BIFF Record data }
|
||||
// AStream.WriteWord(WordToLE(ARow));
|
||||
// AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ IEE 754 floating-point value }
|
||||
AStream.WriteBuffer(AValue, 8);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* Initialization section
|
||||
*
|
||||
* Registers this reader / writer on fpSpreadsheet
|
||||
*
|
||||
*******************************************************************}
|
||||
initialization
|
||||
|
||||
RegisterSpreadFormat(TsCustomSpreadReader, TsSpreadOpenDocWriter, sfOpenDocument);
|
||||
|
||||
end.
|
||||
|
BIN
components/fpspreadsheet/fpspreadsheet.chm
Executable file
BIN
components/fpspreadsheet/fpspreadsheet.chm
Executable file
Binary file not shown.
847
components/fpspreadsheet/fpspreadsheet.dox-express
Executable file
847
components/fpspreadsheet/fpspreadsheet.dox-express
Executable file
@ -0,0 +1,847 @@
|
||||
; This is a Doc-O-Matic version 6.1.0.1246 project file.
|
||||
; This file is maintained by Doc-O-Matic, do not edit manually.
|
||||
|
||||
[AutoTexts]
|
||||
Empty=0
|
||||
Saved=1
|
||||
Text0=This is unknown %SYMBOLNAME%.
|
||||
Text1=This is class %SYMBOLNAME%.
|
||||
Text10=This is file %SYMBOLNAME%.
|
||||
Text11=This is record %SYMBOLNAME%.
|
||||
Text12=This is %SYMBOLNAME%.
|
||||
Text13=This is nested type %SYMBOLNAME%.
|
||||
Text14=This is namespace %SYMBOLNAME%.
|
||||
Text2=This is %MEMBERNAME%, a member of class %CLASSNAME%.
|
||||
Text3=This is %MEMBERNAME%, a member of class %CLASSNAME%.
|
||||
Text4=This is %MEMBERNAME%, a member of class %CLASSNAME%.
|
||||
Text5=This is function %SYMBOLNAME%.
|
||||
Text6=This is type %SYMBOLNAME%.
|
||||
Text7=This is variable %SYMBOLNAME%.
|
||||
Text8=This is constant %SYMBOLNAME%.
|
||||
Text9=This is macro %SYMBOLNAME%.
|
||||
|
||||
[Configurations]
|
||||
Count=3
|
||||
Current=0
|
||||
Name0=HTML
|
||||
Name1=HTML Help
|
||||
Name2=Help 2
|
||||
|
||||
[Configurations\Help 2\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\AdditionalFiles]
|
||||
Count=4
|
||||
File0=C:\Program Files\Doc-O-Matic 6 Express\graphics\footer-bkg-whitegradient.gif
|
||||
File1=C:\Program Files\Doc-O-Matic 6 Express\graphics\header-bkg-whitegradient.gif
|
||||
File2=C:\Program Files\Doc-O-Matic 6 Express\graphics\html_fullframegradient.gif
|
||||
File3=C:\Program Files\Doc-O-Matic 6 Express\graphics\html_titlebkg.jpg
|
||||
|
||||
[Configurations\Help 2\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\General]
|
||||
ClearDirectoryBeforeExport=0
|
||||
HelpKind=2
|
||||
OutputDir=C:\Documents and Settings\mf75rt\My Documents\Doc-O-Matic\output
|
||||
TargetBOM=1
|
||||
TargetCodepage=utf-8
|
||||
|
||||
[Configurations\Help 2\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\General Build Options]
|
||||
ShowDocumentation=1
|
||||
|
||||
[Configurations\Help 2\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\HTMLHelp]
|
||||
CompileFullTextSearchInformation=1
|
||||
CreateBinaryIndex=1
|
||||
CreateBinaryTOC=0
|
||||
CreateCHIFile=0
|
||||
CreateHelp2FullTextIndex=1
|
||||
DontIncludeFolders=0
|
||||
Help2AdditionalXMLData=
|
||||
Help2Collection=
|
||||
Help2Compiler=
|
||||
Help2CompileResult=0
|
||||
Help2Dexplore=
|
||||
Help2GenericInfoType=kbRef
|
||||
Help2ID=
|
||||
Help2Locale=kbEnglish
|
||||
Help2Namespace=
|
||||
Help2PluginNamespace=0
|
||||
Help2PluginNamespaceName=MS.VSIPCC+
|
||||
Help2RegisterType=0
|
||||
Help2UnregisterNamespace=1
|
||||
HelpCompiler=
|
||||
HTMLHelp2Filename=
|
||||
HTMLHelpDisplayFontScaleButton=0
|
||||
HTMLHelpFilename=
|
||||
SaveUserPosition=1
|
||||
SupportEnhancedDecompilation=0
|
||||
WindowPosition_Bottom=0
|
||||
WindowPosition_Left=0
|
||||
WindowPosition_Right=0
|
||||
WindowPosition_Top=0
|
||||
|
||||
[Configurations\Help 2\Image Paths]
|
||||
Count=2
|
||||
Path0=C:\Program Files\Doc-O-Matic 6 Express\graphics
|
||||
Path1=C:\Program Files\Doc-O-Matic 6 Express\graphics\en
|
||||
|
||||
[Configurations\Help 2\Output Options]
|
||||
ClassHierarchyLayoutOutputDir=C:\Documents and Settings\mf75rt\My Documents\Doc-O-Matic\graphics
|
||||
|
||||
[Configurations\Help 2\OutputFormat]
|
||||
ID={D3A588E0-9472-11D3-BDD1-0080C8BA053D}
|
||||
|
||||
[Configurations\HTML Help\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\AdditionalFiles]
|
||||
Count=4
|
||||
File0=C:\Program Files\Doc-O-Matic 6 Express\graphics\footer-bkg-whitegradient.gif
|
||||
File1=C:\Program Files\Doc-O-Matic 6 Express\graphics\header-bkg-whitegradient.gif
|
||||
File2=C:\Program Files\Doc-O-Matic 6 Express\graphics\html_fullframegradient.gif
|
||||
File3=C:\Program Files\Doc-O-Matic 6 Express\graphics\html_titlebkg.jpg
|
||||
|
||||
[Configurations\HTML Help\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\General]
|
||||
ClearDirectoryBeforeExport=0
|
||||
HelpKind=1
|
||||
OutputDir=C:\Documents and Settings\mf75rt\My Documents\Doc-O-Matic\output
|
||||
TargetBOM=0
|
||||
TargetCodepage=windows-1252
|
||||
|
||||
[Configurations\HTML Help\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\General Build Options]
|
||||
ShowDocumentation=1
|
||||
|
||||
[Configurations\HTML Help\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\HTMLHelp]
|
||||
CompileFullTextSearchInformation=1
|
||||
CreateBinaryIndex=1
|
||||
CreateBinaryTOC=1
|
||||
CreateCHIFile=0
|
||||
CreateHelp2FullTextIndex=1
|
||||
DontIncludeFolders=0
|
||||
Help2AdditionalXMLData=
|
||||
Help2Collection=
|
||||
Help2Compiler=
|
||||
Help2CompileResult=0
|
||||
Help2Dexplore=
|
||||
Help2GenericInfoType=kbRef
|
||||
Help2ID=
|
||||
Help2Locale=kbEnglish
|
||||
Help2Namespace=
|
||||
Help2PluginNamespace=0
|
||||
Help2PluginNamespaceName=MS.VSIPCC+
|
||||
Help2RegisterType=0
|
||||
Help2UnregisterNamespace=1
|
||||
HelpCompiler=
|
||||
HTMLHelp2Filename=
|
||||
HTMLHelpDisplayFontScaleButton=0
|
||||
HTMLHelpFilename=
|
||||
SaveUserPosition=1
|
||||
SupportEnhancedDecompilation=0
|
||||
WindowPosition_Bottom=0
|
||||
WindowPosition_Left=0
|
||||
WindowPosition_Right=0
|
||||
WindowPosition_Top=0
|
||||
|
||||
[Configurations\HTML Help\Image Paths]
|
||||
Count=2
|
||||
Path0=C:\Program Files\Doc-O-Matic 6 Express\graphics
|
||||
Path1=C:\Program Files\Doc-O-Matic 6 Express\graphics\en
|
||||
|
||||
[Configurations\HTML Help\Output Options]
|
||||
ClassHierarchyLayoutOutputDir=C:\Documents and Settings\mf75rt\My Documents\Doc-O-Matic\graphics
|
||||
|
||||
[Configurations\HTML Help\OutputFormat]
|
||||
ID={D3A588E0-9472-11D3-BDD1-0080C8BA053D}
|
||||
|
||||
[Configurations\HTML\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\AdditionalFiles]
|
||||
Count=4
|
||||
File0=C:\Program Files\Doc-O-Matic 6 Express\graphics\footer-bkg-whitegradient.gif
|
||||
File1=C:\Program Files\Doc-O-Matic 6 Express\graphics\header-bkg-whitegradient.gif
|
||||
File2=C:\Program Files\Doc-O-Matic 6 Express\graphics\html_fullframegradient.gif
|
||||
File3=C:\Program Files\Doc-O-Matic 6 Express\graphics\html_titlebkg.jpg
|
||||
|
||||
[Configurations\HTML\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\General]
|
||||
ClearDirectoryBeforeExport=0
|
||||
HelpKind=0
|
||||
OutputDir=C:\Documents and Settings\mf75rt\My Documents\Doc-O-Matic\output
|
||||
TargetBOM=0
|
||||
TargetCodepage=utf-8
|
||||
|
||||
[Configurations\HTML\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\General Build Options]
|
||||
ShowDocumentation=1
|
||||
|
||||
[Configurations\HTML\{D3A588E0-9472-11D3-BDD1-0080C8BA053D}\HTMLHelp]
|
||||
CompileFullTextSearchInformation=1
|
||||
CreateBinaryIndex=1
|
||||
CreateBinaryTOC=0
|
||||
CreateCHIFile=0
|
||||
CreateHelp2FullTextIndex=1
|
||||
DontIncludeFolders=0
|
||||
Help2AdditionalXMLData=
|
||||
Help2Collection=
|
||||
Help2Compiler=
|
||||
Help2CompileResult=0
|
||||
Help2Dexplore=
|
||||
Help2GenericInfoType=kbRef
|
||||
Help2ID=
|
||||
Help2Locale=kbEnglish
|
||||
Help2Namespace=
|
||||
Help2PluginNamespace=0
|
||||
Help2PluginNamespaceName=MS.VSIPCC+
|
||||
Help2RegisterType=0
|
||||
Help2UnregisterNamespace=1
|
||||
HelpCompiler=
|
||||
HTMLHelp2Filename=
|
||||
HTMLHelpDisplayFontScaleButton=0
|
||||
HTMLHelpFilename=
|
||||
SaveUserPosition=1
|
||||
SupportEnhancedDecompilation=0
|
||||
WindowPosition_Bottom=0
|
||||
WindowPosition_Left=0
|
||||
WindowPosition_Right=0
|
||||
WindowPosition_Top=0
|
||||
|
||||
[Configurations\HTML\Image Paths]
|
||||
Count=2
|
||||
Path0=C:\Program Files\Doc-O-Matic 6 Express\graphics
|
||||
Path1=C:\Program Files\Doc-O-Matic 6 Express\graphics\en
|
||||
|
||||
[Configurations\HTML\Output Options]
|
||||
ClassHierarchyLayoutOutputDir=C:\Documents and Settings\mf75rt\My Documents\Doc-O-Matic\graphics
|
||||
|
||||
[Configurations\HTML\OutputFormat]
|
||||
ID={D3A588E0-9472-11D3-BDD1-0080C8BA053D}
|
||||
|
||||
[General]
|
||||
Author=Felipe Monteiro de Carvalho
|
||||
AuthorEmail=
|
||||
Copyright=Copyright (c) 2008
|
||||
Summary=Free Pascal Spreadsheet Library
|
||||
Title=FPSpreadsheet
|
||||
VersionBuild=0
|
||||
VersionMajor=1
|
||||
VersionMinor=0
|
||||
VersionRelease=0
|
||||
|
||||
[Macro Header Files]
|
||||
Count=0
|
||||
|
||||
[Parsing]
|
||||
AssignedCommentsToFollowingSymbols=1
|
||||
CommentDistance=0
|
||||
DocUseTripleSlashOnly=0
|
||||
HeaderUnderlineCharactersCenter==
|
||||
HeaderUnderlineCharactersJustify=#
|
||||
HeaderUnderlineCharactersLeft=-
|
||||
HeaderUnderlineCharactersRight=~
|
||||
HeadlineDelimiterChars=*#-
|
||||
IgnoredTrimLineCount=1
|
||||
IgnoredTrimLine_0=__________________________________________________
|
||||
InitOptional=0
|
||||
InitSequence=@@
|
||||
ListBulletChars=*+-#
|
||||
NamespaceOption=2
|
||||
ParameterDelimiterChars=:-
|
||||
ParameterDescriptionMode=0
|
||||
ParametersAllowSpaceAsDelimiter=0
|
||||
SectionAllowSpaceAsDelimiter=0
|
||||
SectionDelimiterChars=:*-
|
||||
SupportJavaDoc=1
|
||||
SupportJavaDocBackslashTags=0
|
||||
SupportXMLDoc=0
|
||||
TabExpandCount=4
|
||||
TrailerChars=-+~/#
|
||||
WallCharacters="#$%&'*+-/=@[\]^_`{|}~
|
||||
|
||||
[Project File Info]
|
||||
Version=601
|
||||
|
||||
[Section\0]
|
||||
Count=3
|
||||
Description=Contains a short summary of the purpose of an object. This text usually contains one or two sentenses.
|
||||
DisplayName=Summary
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=4
|
||||
Value0=Summary
|
||||
Value1=Brief
|
||||
Value2=Short
|
||||
XMLDocTags=summary
|
||||
|
||||
[Section\1]
|
||||
Count=2
|
||||
Description=Contains the general description of an object. This text describes the purpose of the item.
|
||||
DisplayName=Description
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=Description
|
||||
Value1=Long
|
||||
XMLDocTags=value
|
||||
|
||||
[Section\10]
|
||||
Count=3
|
||||
Description=Contains text that describes bugs or problems related to the object.
|
||||
DisplayName=Bugs
|
||||
EditorName=
|
||||
JavaDocTags=bug
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=Bugs
|
||||
Value1=Known Bugs
|
||||
Value2=Current Bugs
|
||||
XMLDocTags=
|
||||
|
||||
[Section\11]
|
||||
Count=2
|
||||
Description=Contains documentation parts which should only be available to internal team members and not to the general public.
|
||||
DisplayName=Internal
|
||||
EditorName=
|
||||
JavaDocTags=internal
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=Internal
|
||||
Value1=Special Info
|
||||
XMLDocTags=
|
||||
|
||||
[Section\12]
|
||||
Count=1
|
||||
Description=Contains text that describes which parts of the object are incomplete and need additional work.
|
||||
DisplayName=Todo
|
||||
EditorName=
|
||||
JavaDocTags=todo
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=TODO
|
||||
XMLDocTags=
|
||||
|
||||
[Section\13]
|
||||
Count=3
|
||||
Description=Contains text that describes which exceptions can be raised by a function or method.
|
||||
DisplayName=Exceptions
|
||||
EditorName=
|
||||
JavaDocTags=exception,exceptions,throws,raises
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=12
|
||||
Value0=Exceptions
|
||||
Value1=Throws
|
||||
Value2=Raises
|
||||
XMLDocTags=exception
|
||||
|
||||
[Section\14]
|
||||
Count=2
|
||||
Description=Contains text that describes conditions (for example pre- and postconditions) for a function call.
|
||||
DisplayName=Conditions
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=Conditions
|
||||
Value1=Preconditions
|
||||
XMLDocTags=permission
|
||||
|
||||
[Section\15]
|
||||
Count=2
|
||||
Description=Contains information who the author(s) of a topic are
|
||||
DisplayName=Author
|
||||
EditorName=
|
||||
JavaDocTags=author
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=Author
|
||||
Value1=Authors
|
||||
XMLDocTags=
|
||||
|
||||
[Section\16]
|
||||
Count=1
|
||||
Description=Contains text which describes the history of the object
|
||||
DisplayName=History
|
||||
EditorName=
|
||||
JavaDocTags=since,history
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=History
|
||||
XMLDocTags=
|
||||
|
||||
[Section\17]
|
||||
Count=2
|
||||
Description=Contains version information of the object.
|
||||
DisplayName=Version
|
||||
EditorName=
|
||||
JavaDocTags=version
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=Version
|
||||
Value1=Current Version
|
||||
XMLDocTags=
|
||||
|
||||
[Section\18]
|
||||
Count=1
|
||||
Description=Contains the text for the glossary entry of the topic.
|
||||
DisplayName=Glossary
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=7
|
||||
Value0=Glossary
|
||||
XMLDocTags=
|
||||
|
||||
[Section\19]
|
||||
Count=3
|
||||
Description=Contains the text for the description of the implementation source of functions.
|
||||
DisplayName=Source Description
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=9
|
||||
Value0=Source Description
|
||||
Value1=Implementation Notes
|
||||
Value2=Implementation Description
|
||||
XMLDocTags=
|
||||
|
||||
[Section\2]
|
||||
Count=1
|
||||
Description=Used for one or more short notes on an object.
|
||||
DisplayName=Notes
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=Note
|
||||
XMLDocTags=
|
||||
|
||||
[Section\20]
|
||||
Count=4
|
||||
Description=Like a standard section with the additional possibility to give it an individual name in each topic it is used.
|
||||
DisplayName=Link List
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=10
|
||||
Value0=Link List
|
||||
Value1=Membergroups
|
||||
Value2=Member Groups
|
||||
Value3=Class Group
|
||||
XMLDocTags=
|
||||
|
||||
[Section\21]
|
||||
Count=1
|
||||
Description=Contains the Pascal declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=Pascal
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=21
|
||||
Value0=Pascal Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\22]
|
||||
Count=1
|
||||
Description=Contains the C++ declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=C++
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=22
|
||||
Value0=C++ Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\23]
|
||||
Count=1
|
||||
Description=Contains the C# declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=C#
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=23
|
||||
Value0=C# Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\24]
|
||||
Count=1
|
||||
Description=Contains the Visual Basic declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=Visual Basic
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=24
|
||||
Value0=Visual Basic Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\25]
|
||||
Count=1
|
||||
Description=Contains the Java declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=Java
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=25
|
||||
Value0=Java Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\26]
|
||||
Count=1
|
||||
Description=Contains the IDL declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=IDL
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=26
|
||||
Value0=IDL Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\27]
|
||||
Count=1
|
||||
Description=Contains the JavaScript declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=JavaScript
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=27
|
||||
Value0=JavaScript Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\28]
|
||||
Count=1
|
||||
Description=Contains the MATLAB declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=MATLAB
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=29
|
||||
Value0=MATLAB Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\29]
|
||||
Count=1
|
||||
Description=Contains the PHP declaration syntax. It will be generated automatically if it does not exist in a topic.
|
||||
DisplayName=PHP
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=9
|
||||
Type=30
|
||||
Value0=PHP Syntax
|
||||
XMLDocTags=
|
||||
|
||||
[Section\3]
|
||||
Count=1
|
||||
Description=Used for special remarks on a topic. Contrary to Notes, this text can be fairly long.
|
||||
DisplayName=Remarks
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=0
|
||||
Value0=Remarks
|
||||
XMLDocTags=remarks
|
||||
|
||||
[Section\30]
|
||||
Count=0
|
||||
Description=Automatically filled section that contains a table of members of structs, records, enumerations and unions along with their descriptions.
|
||||
DisplayName=Members
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=13
|
||||
XMLDocTags=
|
||||
|
||||
[Section\31]
|
||||
Count=0
|
||||
Description=Automatically filled section that contains navigation listings for class and namespace members and sub-topics.
|
||||
DisplayName=Navigation
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=14
|
||||
XMLDocTags=
|
||||
|
||||
[Section\32]
|
||||
Count=0
|
||||
Description=Automatically filled section that contains the body source code for functions and files.
|
||||
DisplayName=Body Source
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=16
|
||||
XMLDocTags=
|
||||
|
||||
[Section\33]
|
||||
Count=0
|
||||
Description=Automatically filled section that contains the local class hierarchy for a single class.
|
||||
DisplayName=Class Hierarchy
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=17
|
||||
XMLDocTags=
|
||||
|
||||
[Section\34]
|
||||
Count=0
|
||||
Description=Automatically filled section that contains a link to the file in which a symbol is declared.
|
||||
DisplayName=File
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=18
|
||||
XMLDocTags=
|
||||
|
||||
[Section\35]
|
||||
Count=0
|
||||
Description=Automatically filled section that contains a list of links to pages with more information about the topic that are maintained by Doc-O-Matic
|
||||
DisplayName=Links
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=19
|
||||
XMLDocTags=
|
||||
|
||||
[Section\36]
|
||||
Count=0
|
||||
Description=Automatically filled section that contains the reports assigned to a topic.
|
||||
DisplayName=Reports
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=20
|
||||
XMLDocTags=
|
||||
|
||||
[Section\37]
|
||||
Count=0
|
||||
Description=Automatically filled section that contains an overview for overloaded member functions.
|
||||
DisplayName=Overload List
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=28
|
||||
XMLDocTags=
|
||||
|
||||
[Section\38]
|
||||
Count=1
|
||||
Description=Contains multiple glossary entries of the topic.
|
||||
DisplayName=Multi Item Glossary
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=12
|
||||
Value0=Multi Item Glossary
|
||||
XMLDocTags=
|
||||
|
||||
[Section\39]
|
||||
Count=1
|
||||
Description=Contains a parameter descriptions for generic types.
|
||||
DisplayName=Type Parameters
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=1
|
||||
Value0=Type Parameters
|
||||
XMLDocTags=typeparam
|
||||
|
||||
[Section\4]
|
||||
Count=4
|
||||
Description=Used for detailed descriptions of each parameter of a global or member function.
|
||||
DisplayName=Parameters
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=1
|
||||
Value0=Parameters
|
||||
Value1=Arguments
|
||||
Value2=Inputs
|
||||
Value3=Input
|
||||
XMLDocTags=
|
||||
|
||||
[Section\5]
|
||||
Count=4
|
||||
Description=Used to generally describe the return value of a global or member function.
|
||||
DisplayName=Returns
|
||||
EditorName=
|
||||
JavaDocTags=return,returns
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=2
|
||||
Value0=Returns
|
||||
Value1=Return Value
|
||||
Value2=Result
|
||||
Value3=Output
|
||||
XMLDocTags=returns
|
||||
|
||||
[Section\6]
|
||||
Count=2
|
||||
Description=Used to describe all possible return values in detail in form of a value-description list.
|
||||
DisplayName=Return Values
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=11
|
||||
Value0=Return Value List
|
||||
Value1=Return Value Details
|
||||
XMLDocTags=
|
||||
|
||||
[Section\7]
|
||||
Count=3
|
||||
Description=Used for one or more usage examples of the object being described.
|
||||
DisplayName=Example
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=3
|
||||
Value0=Example
|
||||
Value1=Examples
|
||||
Value2=Sample
|
||||
XMLDocTags=example
|
||||
|
||||
[Section\8]
|
||||
Count=8
|
||||
Description=All text that appears in this section is ignored.
|
||||
DisplayName=Ignore
|
||||
EditorName=
|
||||
JavaDocTags=beaninfo,component,deprecated,event,exclude,index,obsolete,seealso,serial,serialdata,serialfield,tutorial
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=8
|
||||
Type=6
|
||||
Value0=Ignore Text
|
||||
Value1=$Log
|
||||
Value2=$Filename
|
||||
Value3=$Revision
|
||||
Value4=$Date
|
||||
Value5=$Author
|
||||
Value6=$History
|
||||
Value7=$Id
|
||||
XMLDocTags=
|
||||
|
||||
[Section\9]
|
||||
Count=2
|
||||
Description=Contains a comma separated list of topic IDs which build the see also list of the topic.
|
||||
DisplayName=See Also
|
||||
EditorName=
|
||||
JavaDocTags=
|
||||
OutputFind=
|
||||
OutputReplace=
|
||||
SectionFlags=15
|
||||
Type=5
|
||||
Value0=See Also
|
||||
Value1=Seealso
|
||||
XMLDocTags=
|
||||
|
||||
[Sections]
|
||||
Count=40
|
||||
DefID=1
|
||||
ID0=0
|
||||
ID1=1
|
||||
ID10=10
|
||||
ID11=11
|
||||
ID12=12
|
||||
ID13=13
|
||||
ID14=14
|
||||
ID15=15
|
||||
ID16=16
|
||||
ID17=17
|
||||
ID18=18
|
||||
ID19=19
|
||||
ID2=2
|
||||
ID20=20
|
||||
ID21=21
|
||||
ID22=22
|
||||
ID23=23
|
||||
ID24=24
|
||||
ID25=25
|
||||
ID26=26
|
||||
ID27=27
|
||||
ID28=28
|
||||
ID29=29
|
||||
ID3=3
|
||||
ID30=30
|
||||
ID31=31
|
||||
ID32=32
|
||||
ID33=33
|
||||
ID34=34
|
||||
ID35=35
|
||||
ID36=36
|
||||
ID37=37
|
||||
ID38=38
|
||||
ID39=39
|
||||
ID4=4
|
||||
ID5=5
|
||||
ID6=6
|
||||
ID7=7
|
||||
ID8=8
|
||||
ID9=9
|
||||
SavedValues=1
|
||||
|
||||
[Source Files]
|
||||
Count=1
|
||||
File0=fpspreadsheet.pas
|
||||
|
||||
[Source Include Directories]
|
||||
Count=0
|
||||
|
588
components/fpspreadsheet/fpspreadsheet.pas
Executable file
588
components/fpspreadsheet/fpspreadsheet.pas
Executable file
@ -0,0 +1,588 @@
|
||||
{
|
||||
fpspreadsheet.pas
|
||||
|
||||
Writes an spreadsheet document
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
}
|
||||
unit fpspreadsheet;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
{$endif}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils;
|
||||
|
||||
type
|
||||
TsSpreadsheetFormat = (sfExcel2, sfExcel3, sfExcel4, sfExcel5, sfExcel8,
|
||||
sfOOXML, sfOpenDocument, sfCSV);
|
||||
|
||||
const
|
||||
{ Default extensions }
|
||||
STR_EXCEL_EXTENSION = '.xls';
|
||||
|
||||
const
|
||||
{ TokenID values }
|
||||
|
||||
{ Binary Operator Tokens }
|
||||
INT_EXCEL_TOKEN_TADD = $03;
|
||||
INT_EXCEL_TOKEN_TSUB = $04;
|
||||
INT_EXCEL_TOKEN_TMUL = $05;
|
||||
INT_EXCEL_TOKEN_TDIV = $06;
|
||||
INT_EXCEL_TOKEN_TPOWER = $07;
|
||||
|
||||
{ Constant Operand Tokens }
|
||||
INT_EXCEL_TOKEN_TNUM = $1F;
|
||||
|
||||
{ Operand Tokens }
|
||||
INT_EXCEL_TOKEN_TREFR = $24;
|
||||
INT_EXCEL_TOKEN_TREFV = $44;
|
||||
INT_EXCEL_TOKEN_TREFA = $64;
|
||||
|
||||
type
|
||||
|
||||
{@@ A Token of a RPN Token array for formulas }
|
||||
|
||||
TRPNToken = record
|
||||
TokenID: Byte;
|
||||
Col: Byte;
|
||||
Row: Word;
|
||||
DoubleValue: double;
|
||||
end;
|
||||
|
||||
{@@ RPN Token array for formulas }
|
||||
|
||||
TRPNFormula = array of TRPNToken;
|
||||
|
||||
{@@ Describes the type of content of a cell on a TsWorksheet }
|
||||
|
||||
TCellContentType = (cctFormula, cctNumber, cctString, cctWideString);
|
||||
|
||||
{@@ Cell structure for TsWorksheet }
|
||||
|
||||
TCell = record
|
||||
Row, Col: Cardinal;
|
||||
ContentType: TCellContentType;
|
||||
FormulaValue: TRPNFormula;
|
||||
NumberValue: double;
|
||||
StringValue: string;
|
||||
WideStringValue: widestring;
|
||||
end;
|
||||
|
||||
PCell = ^TCell;
|
||||
|
||||
type
|
||||
|
||||
TsCustomSpreadWriter = class;
|
||||
|
||||
{@@ TsWorksheet }
|
||||
|
||||
TsWorksheet = class
|
||||
private
|
||||
procedure RemoveCallback(data, arg: pointer);
|
||||
public
|
||||
FCells: TFPList;
|
||||
Name: string;
|
||||
{ Base methods }
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
{ Data manipulation methods }
|
||||
function FindCell(ARow, ACol: Cardinal): PCell;
|
||||
function GetCell(ARow, ACol: Cardinal): PCell;
|
||||
procedure RemoveAllCells;
|
||||
procedure WriteAnsiText(ARow, ACol: Cardinal; AText: ansistring);
|
||||
procedure WriteNumber(ARow, ACol: Cardinal; ANumber: double);
|
||||
procedure WriteRPNFormula(ARow, ACol: Cardinal; AFormula: TRPNFormula);
|
||||
end;
|
||||
|
||||
{@@ TsWorkbook }
|
||||
|
||||
TsWorkbook = class
|
||||
private
|
||||
FWorksheets: TFPList;
|
||||
procedure RemoveCallback(data, arg: pointer);
|
||||
public
|
||||
{ Base methods }
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function CreateSpreadWriter(AFormat: TsSpreadsheetFormat): TsCustomSpreadWriter;
|
||||
procedure WriteToFile(AFileName: string; AFormat: TsSpreadsheetFormat);
|
||||
procedure WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat);
|
||||
{ Worksheet list handling methods }
|
||||
function AddWorksheet(AName: string): TsWorksheet;
|
||||
function GetFirstWorksheet: TsWorksheet;
|
||||
function GetWorksheetByIndex(AIndex: Cardinal): TsWorksheet;
|
||||
function GetWorksheetCount: Cardinal;
|
||||
procedure RemoveAllWorksheets;
|
||||
end;
|
||||
|
||||
{@@ TsSpreadReader class reference type }
|
||||
|
||||
TsSpreadReaderClass = class of TsCustomSpreadReader;
|
||||
|
||||
{@@ TsCustomSpreadReader }
|
||||
|
||||
TsCustomSpreadReader = class
|
||||
protected
|
||||
FWorkbook: TsWorkbook;
|
||||
FCurrentWorksheet: TsWorksheet;
|
||||
public
|
||||
{ General writing methods }
|
||||
procedure ReadFromFile(AFileName: string; AData: TsWorkbook); virtual;
|
||||
procedure ReadFromStream(AStream: TStream; AData: TsWorkbook); virtual; abstract;
|
||||
{ Record reading methods }
|
||||
procedure ReadFormula(AStream: TStream); virtual; abstract;
|
||||
procedure ReadLabel(AStream: TStream); virtual; abstract;
|
||||
procedure ReadNumber(AStream: TStream); virtual; abstract;
|
||||
end;
|
||||
|
||||
{@@ TsSpreadWriter class reference type }
|
||||
|
||||
TsSpreadWriterClass = class of TsCustomSpreadWriter;
|
||||
|
||||
{@@ TsCustomSpreadWriter }
|
||||
|
||||
TsCustomSpreadWriter = class
|
||||
public
|
||||
{ General writing methods }
|
||||
procedure WriteCellCallback(data, arg: pointer);
|
||||
procedure WriteCellsToStream(AStream: TStream; ACells: TFPList);
|
||||
procedure WriteToFile(AFileName: string; AData: TsWorkbook); virtual;
|
||||
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); virtual; abstract;
|
||||
{ Record writing methods }
|
||||
procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TRPNFormula); virtual; abstract;
|
||||
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); virtual; abstract;
|
||||
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); virtual; abstract;
|
||||
end;
|
||||
|
||||
{@@ List of registered formats }
|
||||
|
||||
TsSpreadFormatData = record
|
||||
ReaderClass: TsSpreadReaderClass;
|
||||
WriterClass: TsSpreadWriterClass;
|
||||
Format: TsSpreadsheetFormat;
|
||||
end;
|
||||
|
||||
var
|
||||
GsSpreadFormats: array of TsSpreadFormatData;
|
||||
|
||||
procedure RegisterSpreadFormat(
|
||||
AReaderClass: TsSpreadReaderClass;
|
||||
AWriterClass: TsSpreadWriterClass;
|
||||
AFormat: TsSpreadsheetFormat);
|
||||
|
||||
implementation
|
||||
|
||||
{@@
|
||||
Registers a new reader/writer pair for a format
|
||||
}
|
||||
procedure RegisterSpreadFormat(
|
||||
AReaderClass: TsSpreadReaderClass;
|
||||
AWriterClass: TsSpreadWriterClass;
|
||||
AFormat: TsSpreadsheetFormat);
|
||||
var
|
||||
len: Integer;
|
||||
begin
|
||||
len := Length(GsSpreadFormats);
|
||||
SetLength(GsSpreadFormats, len + 1);
|
||||
|
||||
GsSpreadFormats[len].ReaderClass := AReaderClass;
|
||||
GsSpreadFormats[len].WriterClass := AWriterClass;
|
||||
GsSpreadFormats[len].Format := AFormat;
|
||||
end;
|
||||
|
||||
{ TsWorksheet }
|
||||
|
||||
{@@
|
||||
Helper method for clearing the records in a spreadsheet.
|
||||
}
|
||||
procedure TsWorksheet.RemoveCallback(data, arg: pointer);
|
||||
begin
|
||||
FreeMem(data);
|
||||
end;
|
||||
|
||||
{@@
|
||||
Constructor.
|
||||
}
|
||||
constructor TsWorksheet.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
FCells := TFPList.Create;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Destructor.
|
||||
}
|
||||
destructor TsWorksheet.Destroy;
|
||||
begin
|
||||
RemoveAllCells;
|
||||
|
||||
FCells.Free;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Tryes to locate a Cell in the list of already
|
||||
written Cells
|
||||
|
||||
@param ARow The row of the cell
|
||||
@param ACol The column of the cell
|
||||
|
||||
@return Nil if no existing cell was found,
|
||||
otherwise a pointer to the desired Cell
|
||||
|
||||
@see TCell
|
||||
}
|
||||
function TsWorksheet.FindCell(ARow, ACol: Cardinal): PCell;
|
||||
var
|
||||
i: Integer;
|
||||
ACell: PCell;
|
||||
begin
|
||||
i := 0;
|
||||
Result := nil;
|
||||
|
||||
while (i < FCells.Count) do
|
||||
begin
|
||||
ACell := PCell(FCells.Items[i]);
|
||||
|
||||
if (ACell^.Row = ARow) and (ACell^.Col = ACol) then
|
||||
begin
|
||||
Result := ACell;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Inc(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Obtains an allocated cell at the desired location.
|
||||
|
||||
If the Cell already exists, a pointer to it will
|
||||
be returned.
|
||||
|
||||
If not, then new memory for the cell will be allocated,
|
||||
a pointer to it will be returned and it will be added
|
||||
to the list of Cells.
|
||||
|
||||
@param ARow The row of the cell
|
||||
@param ACol The column of the cell
|
||||
|
||||
@return A pointer to the Cell on the desired location.
|
||||
|
||||
@see TCell
|
||||
}
|
||||
function TsWorksheet.GetCell(ARow, ACol: Cardinal): PCell;
|
||||
begin
|
||||
Result := FindCell(ARow, ACol);
|
||||
|
||||
if (Result = nil) then
|
||||
begin
|
||||
Result := GetMem(SizeOf(TCell));
|
||||
FillChar(Result^, SizeOf(TCell), #0);
|
||||
|
||||
Result^.Row := ARow;
|
||||
Result^.Col := ACol;
|
||||
|
||||
FCells.Add(Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Clears the list of Cells and releases their memory.
|
||||
}
|
||||
procedure TsWorksheet.RemoveAllCells;
|
||||
begin
|
||||
FCells.ForEachCall(RemoveCallback, nil);
|
||||
end;
|
||||
|
||||
{@@
|
||||
Writes ansi text to a determined cell.
|
||||
|
||||
The text must be encoded on the system default encoding.
|
||||
|
||||
On formats the support unicode the text will be converted to the unicode
|
||||
encoding that the format supports.
|
||||
|
||||
@param ARow The row of the cell
|
||||
@param ACol The column of the cell
|
||||
@param AText The text to be written encoded with the system encoding
|
||||
}
|
||||
procedure TsWorksheet.WriteAnsiText(ARow, ACol: Cardinal; AText: ansistring);
|
||||
var
|
||||
ACell: PCell;
|
||||
begin
|
||||
ACell := GetCell(ARow, ACol);
|
||||
|
||||
ACell^.ContentType := cctString;
|
||||
ACell^.StringValue := AText;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Writes a floating-point number to a determined cell
|
||||
|
||||
@param ARow The row of the cell
|
||||
@param ACol The column of the cell
|
||||
@param ANumber The number to be written
|
||||
}
|
||||
procedure TsWorksheet.WriteNumber(ARow, ACol: Cardinal; ANumber: double);
|
||||
var
|
||||
ACell: PCell;
|
||||
begin
|
||||
ACell := GetCell(ARow, ACol);
|
||||
|
||||
ACell^.ContentType := cctNumber;
|
||||
ACell^.NumberValue := ANumber;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Writes a formula to a determined cell
|
||||
|
||||
@param ARow The row of the cell
|
||||
@param ACol The column of the cell
|
||||
@param AFormula The formula in RPN array format
|
||||
}
|
||||
procedure TsWorksheet.WriteRPNFormula(ARow, ACol: Cardinal; AFormula: TRPNFormula);
|
||||
var
|
||||
ACell: PCell;
|
||||
begin
|
||||
ACell := GetCell(ARow, ACol);
|
||||
|
||||
ACell^.ContentType := cctFormula;
|
||||
ACell^.FormulaValue := AFormula;
|
||||
end;
|
||||
|
||||
{ TsWorkbook }
|
||||
|
||||
{@@
|
||||
Helper method for clearing the spreadsheet list.
|
||||
}
|
||||
procedure TsWorkbook.RemoveCallback(data, arg: pointer);
|
||||
begin
|
||||
TsWorksheet(data).Free;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Constructor.
|
||||
}
|
||||
constructor TsWorkbook.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
FWorksheets := TFPList.Create;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Destructor.
|
||||
}
|
||||
destructor TsWorkbook.Destroy;
|
||||
begin
|
||||
RemoveAllWorksheets;
|
||||
|
||||
FWorksheets.Free;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Convenience method which creates the correct
|
||||
writer object for a given spreadsheet format.
|
||||
}
|
||||
function TsWorkbook.CreateSpreadWriter(AFormat: TsSpreadsheetFormat): TsCustomSpreadWriter;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := nil;
|
||||
|
||||
for i := 0 to Length(GsSpreadFormats) - 1 do
|
||||
if GsSpreadFormats[i].Format = AFormat then
|
||||
begin
|
||||
Result := GsSpreadFormats[i].WriterClass.Create;
|
||||
|
||||
Break;
|
||||
end;
|
||||
|
||||
if Result = nil then raise Exception.Create('Unsuported spreadsheet format.');
|
||||
end;
|
||||
|
||||
{@@
|
||||
Writes the document to a file.
|
||||
|
||||
If the file doesn't exist, it will be created.
|
||||
}
|
||||
procedure TsWorkbook.WriteToFile(AFileName: string; AFormat: TsSpreadsheetFormat);
|
||||
var
|
||||
AWriter: TsCustomSpreadWriter;
|
||||
begin
|
||||
AWriter := CreateSpreadWriter(AFormat);
|
||||
|
||||
try
|
||||
AWriter.WriteToFile(AFileName, Self);
|
||||
finally
|
||||
AWriter.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Writes the document to a stream
|
||||
}
|
||||
procedure TsWorkbook.WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat);
|
||||
var
|
||||
AWriter: TsCustomSpreadWriter;
|
||||
begin
|
||||
AWriter := CreateSpreadWriter(AFormat);
|
||||
|
||||
try
|
||||
AWriter.WriteToStream(AStream, Self);
|
||||
finally
|
||||
AWriter.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Adds a new worksheet to the workbook
|
||||
|
||||
It is added to the end of the list of worksheets
|
||||
|
||||
@param AName The name of the new worksheet
|
||||
|
||||
@return The instace of the newly created worksheet
|
||||
|
||||
@see TsWorkbook
|
||||
}
|
||||
function TsWorkbook.AddWorksheet(AName: string): TsWorksheet;
|
||||
begin
|
||||
Result := TsWorksheet.Create;
|
||||
|
||||
Result.Name := AName;
|
||||
|
||||
FWorksheets.Add(Pointer(Result));
|
||||
end;
|
||||
|
||||
{@@
|
||||
Quick helper routine which returns the first worksheet
|
||||
|
||||
@return A TsWorksheet instance if at least one is present.
|
||||
nil otherwise.
|
||||
|
||||
@see TsWorkbook.GetWorksheetByIndex
|
||||
@see TsWorksheet
|
||||
}
|
||||
function TsWorkbook.GetFirstWorksheet: TsWorksheet;
|
||||
begin
|
||||
Result := TsWorksheet(FWorksheets.First);
|
||||
end;
|
||||
|
||||
{@@
|
||||
Gets the worksheet with a given index
|
||||
|
||||
The index is zero-based, so the first worksheet
|
||||
added has index 0, the second 1, etc.
|
||||
|
||||
@param AIndex The index of the worksheet (0-based)
|
||||
|
||||
@return A TsWorksheet instance if one is present at that index.
|
||||
nil otherwise.
|
||||
|
||||
@see TsWorkbook.GetFirstWorksheet
|
||||
@see TsWorksheet
|
||||
}
|
||||
function TsWorkbook.GetWorksheetByIndex(AIndex: Cardinal): TsWorksheet;
|
||||
begin
|
||||
Result := TsWorksheet(FWorksheets.Items[AIndex]);
|
||||
end;
|
||||
|
||||
{@@
|
||||
The number of worksheets on the workbook
|
||||
|
||||
@see TsWorksheet
|
||||
}
|
||||
function TsWorkbook.GetWorksheetCount: Cardinal;
|
||||
begin
|
||||
Result := FWorksheets.Count;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Clears the list of Worksheets and releases their memory.
|
||||
}
|
||||
procedure TsWorkbook.RemoveAllWorksheets;
|
||||
begin
|
||||
FWorksheets.ForEachCall(RemoveCallback, nil);
|
||||
end;
|
||||
|
||||
{ TsCustomSpreadReader }
|
||||
|
||||
procedure TsCustomSpreadReader.ReadFromFile(AFileName: string; AData: TsWorkbook);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
{ TsCustomSpreadWriter }
|
||||
|
||||
{@@
|
||||
Helper function for the spreadsheet writers.
|
||||
|
||||
@see TsCustomSpreadWriter.WriteCellsToStream
|
||||
}
|
||||
procedure TsCustomSpreadWriter.WriteCellCallback(data, arg: pointer);
|
||||
var
|
||||
ACell: PCell;
|
||||
AStream: TStream;
|
||||
begin
|
||||
ACell := PCell(data);
|
||||
AStream := TStream(arg);
|
||||
|
||||
case ACell.ContentType of
|
||||
cctFormula: WriteFormula(AStream, ACell^.Row, ACell^.Col, ACell^.FormulaValue);
|
||||
cctNumber: WriteNumber(AStream, ACell^.Row, ACell^.Col, ACell^.NumberValue);
|
||||
cctString: WriteLabel(AStream, ACell^.Row, ACell^.Col, ACell^.StringValue);
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@
|
||||
Helper function for the spreadsheet writers.
|
||||
|
||||
Iterates all cells on a list, calling the appropriate write method for them.
|
||||
|
||||
@param AStream The output stream.
|
||||
@param ACells List of cells to be writeen
|
||||
}
|
||||
procedure TsCustomSpreadWriter.WriteCellsToStream(AStream: TStream; ACells: TFPList);
|
||||
begin
|
||||
ACells.ForEachCall(WriteCellCallback, Pointer(AStream));
|
||||
end;
|
||||
|
||||
{@@
|
||||
Default file writting method.
|
||||
|
||||
Opens the file and calls WriteToStream
|
||||
|
||||
@param AFileName The output file name.
|
||||
If the file already exists it will be replaced.
|
||||
@param AData The Workbook to be saved.
|
||||
|
||||
@see TsWorkbook
|
||||
}
|
||||
procedure TsCustomSpreadWriter.WriteToFile(AFileName: string; AData: TsWorkbook);
|
||||
var
|
||||
OutputFile: TFileStream;
|
||||
begin
|
||||
OutputFile := TFileStream.Create(AFileName, fmCreate or fmOpenWrite);
|
||||
try
|
||||
WriteToStream(OutputFile, AData);
|
||||
finally
|
||||
OutputFile.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
finalization
|
||||
|
||||
SetLength(GsSpreadFormats, 0);
|
||||
|
||||
end.
|
||||
|
305
components/fpspreadsheet/xlsbiff2.pas
Executable file
305
components/fpspreadsheet/xlsbiff2.pas
Executable file
@ -0,0 +1,305 @@
|
||||
{
|
||||
xlsbiff2.pas
|
||||
|
||||
Writes an Excel 2.x file
|
||||
|
||||
Excel 2.x files support only one Worksheet per Workbook, so only the first
|
||||
will be written.
|
||||
|
||||
An Excel file consists of a number of subsequent records.
|
||||
To ensure a properly formed file, the following order must be respected:
|
||||
|
||||
1st record: BOF
|
||||
2nd to Nth record: Any record
|
||||
Last record: EOF
|
||||
|
||||
Excel file format specification obtained from:
|
||||
|
||||
http://sc.openoffice.org/excelfileformat.pdf
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
}
|
||||
unit xlsbiff2;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
{$endif}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils,
|
||||
fpspreadsheet;
|
||||
|
||||
type
|
||||
|
||||
{ TsSpreadBIFF2Writer }
|
||||
|
||||
TsSpreadBIFF2Writer = class(TsCustomSpreadWriter)
|
||||
public
|
||||
{ General writing methods }
|
||||
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); override;
|
||||
{ Record writing methods }
|
||||
procedure WriteBOF(AStream: TStream);
|
||||
procedure WriteEOF(AStream: TStream);
|
||||
procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TRPNFormula); override;
|
||||
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override;
|
||||
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
{ Excel record IDs }
|
||||
INT_EXCEL_ID_NUMBER = $0003;
|
||||
INT_EXCEL_ID_LABEL = $0004;
|
||||
INT_EXCEL_ID_FORMULA = $0006;
|
||||
INT_EXCEL_ID_BOF = $0009;
|
||||
INT_EXCEL_ID_EOF = $000A;
|
||||
|
||||
{ Cell Addresses constants }
|
||||
MASK_EXCEL_ROW = $3FFF;
|
||||
MASK_EXCEL_RELATIVE_ROW = $4000;
|
||||
MASK_EXCEL_RELATIVE_COL = $8000;
|
||||
|
||||
{ BOF record constants }
|
||||
INT_EXCEL_SHEET = $0010;
|
||||
INT_EXCEL_CHART = $0020;
|
||||
INT_EXCEL_MACRO_SHEET = $0040;
|
||||
|
||||
{
|
||||
Endianess helper functions
|
||||
|
||||
Excel files are all written with Little Endian byte order,
|
||||
so it's necessary to swap the data to be able to build a
|
||||
correct file on big endian systems.
|
||||
}
|
||||
|
||||
function WordToLE(AValue: Word): Word;
|
||||
begin
|
||||
{$IFDEF BIG_ENDIAN}
|
||||
Result := ((AValue shl 8) and $FF00) or ((AValue shr 8) and $00FF);
|
||||
{$ELSE}
|
||||
Result := AValue;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{ TsSpreadBIFF2Writer }
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF2Writer.WriteToStream ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 file to a stream
|
||||
*
|
||||
* Excel 2.x files support only one Worksheet per Workbook,
|
||||
* so only the first will be written.
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF2Writer.WriteToStream(AStream: TStream; AData: TsWorkbook);
|
||||
begin
|
||||
WriteBOF(AStream);
|
||||
|
||||
WriteCellsToStream(AStream, AData.GetFirstWorksheet.FCells);
|
||||
|
||||
WriteEOF(AStream);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF2Writer.WriteBOF ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 BOF record
|
||||
*
|
||||
* This must be the first record on an Excel 2 stream
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF2Writer.WriteBOF(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_BOF));
|
||||
AStream.WriteWord(WordToLE($0004));
|
||||
|
||||
{ Unused }
|
||||
AStream.WriteWord($0000);
|
||||
|
||||
{ Data type }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_SHEET));
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF2Writer.WriteEOF ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 EOF record
|
||||
*
|
||||
* This must be the last record on an Excel 2 stream
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF2Writer.WriteEOF(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_EOF));
|
||||
AStream.WriteWord($0000);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF2Writer.WriteFormula ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 FORMULA record
|
||||
*
|
||||
* To input a formula to this method, first convert it
|
||||
* to RPN, and then list all it's members in the
|
||||
* AFormula array
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF2Writer.WriteFormula(AStream: TStream; const ARow,
|
||||
ACol: Word; const AFormula: TRPNFormula);
|
||||
var
|
||||
FormulaResult: double;
|
||||
i: Integer;
|
||||
RPNLength: Word;
|
||||
TokenArraySizePos, RecordSizePos, FinalPos: Cardinal;
|
||||
begin
|
||||
RPNLength := 0;
|
||||
FormulaResult := 0.0;
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_FORMULA));
|
||||
RecordSizePos := AStream.Position;
|
||||
AStream.WriteWord(WordToLE(17 + RPNLength));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ Result of the formula in IEE 754 floating-point value }
|
||||
AStream.WriteBuffer(FormulaResult, 8);
|
||||
|
||||
{ 0 = Do not recalculate
|
||||
1 = Always recalculate }
|
||||
AStream.WriteByte($1);
|
||||
|
||||
{ Formula }
|
||||
|
||||
{ The size of the token array is written later,
|
||||
because it's necessary to calculate if first,
|
||||
and this is done at the same time it is written }
|
||||
TokenArraySizePos := AStream.Position;
|
||||
AStream.WriteByte(RPNLength);
|
||||
|
||||
{ Formula data (RPN token array) }
|
||||
for i := 0 to Length(AFormula) - 1 do
|
||||
begin
|
||||
{ Token identifier }
|
||||
AStream.WriteByte(AFormula[i].TokenID);
|
||||
Inc(RPNLength);
|
||||
|
||||
{ Additional data }
|
||||
case AFormula[i].TokenID of
|
||||
|
||||
{ binary operation tokens }
|
||||
|
||||
INT_EXCEL_TOKEN_TADD, INT_EXCEL_TOKEN_TSUB, INT_EXCEL_TOKEN_TMUL,
|
||||
INT_EXCEL_TOKEN_TDIV, INT_EXCEL_TOKEN_TPOWER: begin end;
|
||||
|
||||
INT_EXCEL_TOKEN_TNUM:
|
||||
begin
|
||||
AStream.WriteBuffer(AFormula[i].DoubleValue, 8);
|
||||
Inc(RPNLength, 8);
|
||||
end;
|
||||
|
||||
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA:
|
||||
begin
|
||||
AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW);
|
||||
AStream.WriteByte(AFormula[i].Col);
|
||||
Inc(RPNLength, 3);
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Write sizes in the end, after we known them }
|
||||
FinalPos := AStream.Position;
|
||||
AStream.position := TokenArraySizePos;
|
||||
AStream.WriteByte(RPNLength);
|
||||
AStream.Position := RecordSizePos;
|
||||
AStream.WriteWord(WordToLE(17 + RPNLength));
|
||||
AStream.position := FinalPos;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF2Writer.WriteLabel ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 LABEL record
|
||||
*
|
||||
* Writes a string to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF2Writer.WriteLabel(AStream: TStream; const ARow,
|
||||
ACol: Word; const AValue: string);
|
||||
var
|
||||
L: Byte;
|
||||
begin
|
||||
L := Length(AValue);
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_LABEL));
|
||||
AStream.WriteWord(WordToLE(8 + L));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ String with 8-bit size }
|
||||
AStream.WriteByte(L);
|
||||
AStream.WriteBuffer(AValue[1], L);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF2Writer.WriteNumber ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 NUMBER record
|
||||
*
|
||||
* Writes a number (64-bit IEE 754 floating point) to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF2Writer.WriteNumber(AStream: TStream; const ARow,
|
||||
ACol: Cardinal; const AValue: double);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_NUMBER));
|
||||
AStream.WriteWord(WordToLE(15));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ IEE 754 floating-point value }
|
||||
AStream.WriteBuffer(AValue, 8);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* Initialization section
|
||||
*
|
||||
* Registers this reader / writer on fpSpreadsheet
|
||||
*
|
||||
*******************************************************************}
|
||||
initialization
|
||||
|
||||
RegisterSpreadFormat(TsCustomSpreadReader, TsSpreadBIFF2Writer, sfExcel2);
|
||||
|
||||
end.
|
||||
|
879
components/fpspreadsheet/xlsbiff5.pas
Executable file
879
components/fpspreadsheet/xlsbiff5.pas
Executable file
@ -0,0 +1,879 @@
|
||||
{
|
||||
xlsbiff5.pas
|
||||
|
||||
Writes an Excel 5 file
|
||||
|
||||
An Excel worksheet stream consists of a number of subsequent records.
|
||||
To ensure a properly formed file, the following order must be respected:
|
||||
|
||||
1st record: BOF
|
||||
2nd to Nth record: Any record
|
||||
Last record: EOF
|
||||
|
||||
Excel 5 files are OLE compound document files, and must be written using the
|
||||
fpOLE library.
|
||||
|
||||
Records Needed to Make a BIFF5 File Microsoft Excel Can Use:
|
||||
|
||||
Required Records:
|
||||
|
||||
BOF - Set the 6 byte offset to 0x0005 (workbook globals)
|
||||
Window1
|
||||
FONT - At least five of these records must be included
|
||||
XF - At least 15 Style XF records and 1 Cell XF record must be included
|
||||
STYLE
|
||||
BOUNDSHEET - Include one BOUNDSHEET record per worksheet
|
||||
EOF
|
||||
|
||||
BOF - Set the 6 byte offset to 0x0010 (worksheet)
|
||||
INDEX
|
||||
DIMENSIONS
|
||||
WINDOW2
|
||||
EOF
|
||||
|
||||
Excel file format specification obtained from:
|
||||
|
||||
http://sc.openoffice.org/excelfileformat.pdf
|
||||
|
||||
Records Needed to Make a BIFF5 File Microsoft Excel Can Use obtained from:
|
||||
|
||||
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q147732&ID=KB;EN-US;Q147732&LN=EN-US&rnk=2&SD=msdn&FR=0&qry=BIFF&src=DHCS_MSPSS_msdn_SRCH&SPR=MSALL&
|
||||
|
||||
Microsoft BIFF 5 writer example:
|
||||
|
||||
http://support.microsoft.com/kb/150447/en-us
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
}
|
||||
unit xlsbiff5;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
{$endif}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, fpcanvas,
|
||||
fpspreadsheet, fpolestorage;
|
||||
|
||||
type
|
||||
|
||||
{ TsSpreadBIFF5Writer }
|
||||
|
||||
TsSpreadBIFF5Writer = class(TsCustomSpreadWriter)
|
||||
public
|
||||
// constructor Create;
|
||||
// destructor Destroy; override;
|
||||
{ General writing methods }
|
||||
procedure WriteToFile(AFileName: string; AData: TsWorkbook); override;
|
||||
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); override;
|
||||
{ Record writing methods }
|
||||
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
||||
function WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
||||
procedure WriteDimensions(AStream: TStream);
|
||||
procedure WriteEOF(AStream: TStream);
|
||||
procedure WriteFont(AStream: TStream; AFont: TFPCustomFont);
|
||||
procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TRPNFormula); override;
|
||||
procedure WriteIndex(AStream: TStream);
|
||||
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override;
|
||||
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override;
|
||||
procedure WriteStyle(AStream: TStream);
|
||||
procedure WriteWindow1(AStream: TStream);
|
||||
procedure WriteWindow2(AStream: TStream; ASheetSelected: Boolean);
|
||||
procedure WriteXF(AStream: TStream; AFontIndex: Word; AXF_TYPE_PROT: Byte);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
{ Excel record IDs }
|
||||
INT_EXCEL_ID_BOF = $0809;
|
||||
INT_EXCEL_ID_BOUNDSHEET = $0085;
|
||||
INT_EXCEL_ID_EOF = $000A;
|
||||
INT_EXCEL_ID_DIMENSIONS = $0200;
|
||||
INT_EXCEL_ID_FONT = $0031;
|
||||
INT_EXCEL_ID_FORMULA = $0006;
|
||||
INT_EXCEL_ID_INDEX = $020B;
|
||||
INT_EXCEL_ID_LABEL = $0204;
|
||||
INT_EXCEL_ID_NUMBER = $0203;
|
||||
INT_EXCEL_ID_STYLE = $0293;
|
||||
INT_EXCEL_ID_WINDOW1 = $003D;
|
||||
INT_EXCEL_ID_WINDOW2 = $023E;
|
||||
INT_EXCEL_ID_XF = $00E0;
|
||||
|
||||
{ Cell Addresses constants }
|
||||
MASK_EXCEL_ROW = $3FFF;
|
||||
MASK_EXCEL_RELATIVE_ROW = $4000;
|
||||
MASK_EXCEL_RELATIVE_COL = $8000;
|
||||
|
||||
{ BOF record constants }
|
||||
INT_BOF_BIFF5_VER = $0500;
|
||||
INT_BOF_WORKBOOK_GLOBALS= $0005;
|
||||
INT_BOF_VB_MODULE = $0006;
|
||||
INT_BOF_SHEET = $0010;
|
||||
INT_BOF_CHART = $0020;
|
||||
INT_BOF_MACRO_SHEET = $0040;
|
||||
INT_BOF_WORKSPACE = $0100;
|
||||
INT_BOF_BUILD_ID = $1FD2;
|
||||
INT_BOF_BUILD_YEAR = $07CD;
|
||||
|
||||
{ FONT record constants }
|
||||
INT_FONT_WEIGHT_NORMAL = $0190;
|
||||
|
||||
{ FORMULA record constants }
|
||||
MASK_FORMULA_RECALCULATE_ALWAYS = $0001;
|
||||
MASK_FORMULA_RECALCULATE_ON_OPEN = $0002;
|
||||
MASK_FORMULA_SHARED_FORMULA = $0008;
|
||||
|
||||
{ STYLE record constants }
|
||||
MASK_STYLE_BUILT_IN = $8000;
|
||||
|
||||
{ WINDOW1 record constants }
|
||||
MASK_WINDOW1_OPTION_WINDOW_HIDDEN = $0001;
|
||||
MASK_WINDOW1_OPTION_WINDOW_MINIMISED = $0002;
|
||||
MASK_WINDOW1_OPTION_HORZ_SCROLL_VISIBLE = $0008;
|
||||
MASK_WINDOW1_OPTION_VERT_SCROLL_VISIBLE = $0010;
|
||||
MASK_WINDOW1_OPTION_WORKSHEET_TAB_VISIBLE = $0020;
|
||||
|
||||
{ WINDOW2 record constants }
|
||||
MASK_WINDOW2_OPTION_SHOW_FORMULAS = $0001;
|
||||
MASK_WINDOW2_OPTION_SHOW_GRID_LINES = $0002;
|
||||
MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS = $0004;
|
||||
MASK_WINDOW2_OPTION_PANES_ARE_FROZEN = $0008;
|
||||
MASK_WINDOW2_OPTION_SHOW_ZERO_VALUES = $0010;
|
||||
MASK_WINDOW2_OPTION_AUTO_GRIDLINE_COLOR = $0020;
|
||||
MASK_WINDOW2_OPTION_COLUMNS_RIGHT_TO_LEFT = $0040;
|
||||
MASK_WINDOW2_OPTION_SHOW_OUTLINE_SYMBOLS = $0080;
|
||||
MASK_WINDOW2_OPTION_REMOVE_SPLITS_ON_UNFREEZE = $0100;
|
||||
MASK_WINDOW2_OPTION_SHEET_SELECTED = $0200;
|
||||
MASK_WINDOW2_OPTION_SHEET_ACTIVE = $0400;
|
||||
|
||||
{ XF substructures }
|
||||
|
||||
{ XF_TYPE_PROT - XF Type and Cell protection (3 Bits) - BIFF3-BIFF8 }
|
||||
MASK_XF_TYPE_PROT_LOCKED = $1;
|
||||
MASK_XF_TYPE_PROT_FORMULA_HIDDEN = $2;
|
||||
MASK_XF_TYPE_PROT_STYLE_XF = $4; // 0 = CELL XF
|
||||
|
||||
{ XF_USED_ATTRIB - Attributes from parent Style XF (6 Bits) - BIFF3-BIFF8
|
||||
|
||||
In a CELL XF a cleared bit means that the parent attribute is used,
|
||||
while a set bit indicates that the data in this XF is used
|
||||
|
||||
In a STYLE XF a cleared bit means that the data in this XF is used,
|
||||
while a set bit indicates that the attribute should be ignored }
|
||||
MASK_XF_USED_ATTRIB_NUMBER_FORMAT = $04;
|
||||
MASK_XF_USED_ATTRIB_FONT = $08;
|
||||
MASK_XF_USED_ATTRIB_TEXT = $10;
|
||||
MASK_XF_USED_ATTRIB_BORDER_LINES = $20;
|
||||
MASK_XF_USED_ATTRIB_BACKGROUND = $40;
|
||||
MASK_XF_USED_ATTRIB_CELL_PROTECTION = $80;
|
||||
|
||||
{ XF_VERT_ALIGN }
|
||||
MASK_XF_VERT_ALIGN_TOP = $00;
|
||||
MASK_XF_VERT_ALIGN_CENTRED = $10;
|
||||
MASK_XF_VERT_ALIGN_BOTTOM = $20;
|
||||
MASK_XF_VERT_ALIGN_JUSTIFIED = $30;
|
||||
|
||||
{ XF record constants }
|
||||
MASK_XF_TYPE_PROT = $0007;
|
||||
MASK_XF_TYPE_PROT_PARENT = $FFF0;
|
||||
|
||||
MASK_XF_VERT_ALIGN = $70;
|
||||
|
||||
{
|
||||
Endianess helper functions
|
||||
|
||||
Excel files are all written with Little Endian byte order,
|
||||
so it's necessary to swap the data to be able to build a
|
||||
correct file on big endian systems.
|
||||
}
|
||||
|
||||
function WordToLE(AValue: Word): Word;
|
||||
begin
|
||||
{$IFDEF BIG_ENDIAN}
|
||||
Result := ((AValue shl 8) and $FF00) or ((AValue shr 8) and $00FF);
|
||||
{$ELSE}
|
||||
Result := AValue;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{
|
||||
Exported functions
|
||||
}
|
||||
|
||||
{ TsSpreadBIFF5Writer }
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteToFile ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel BIFF5 file to the disc
|
||||
*
|
||||
* The BIFF 5 writer overrides this method because
|
||||
* BIFF 5 is written as an OLE document, and our
|
||||
* current OLE document writing method involves:
|
||||
*
|
||||
* 1 - Writing the BIFF data to a memory stream
|
||||
*
|
||||
* 2 - Write the memory stream data to disk using
|
||||
* COM functions
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteToFile(AFileName: string; AData: TsWorkbook);
|
||||
var
|
||||
MemStream: TMemoryStream;
|
||||
OutputStorage: TOLEStorage;
|
||||
begin
|
||||
MemStream := TMemoryStream.Create;
|
||||
OutputStorage := TOLEStorage.Create;
|
||||
try
|
||||
WriteToStream(MemStream, AData);
|
||||
|
||||
OutputStorage.WriteStreamToOLEFile(AFileName, MemStream);
|
||||
finally
|
||||
MemStream.Free;
|
||||
OutputStorage.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteToStream ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel BIFF5 record structure
|
||||
*
|
||||
* Be careful as this method doesn't write the OLE
|
||||
* part of the document, just the BIFF records
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteToStream(AStream: TStream; AData: TsWorkbook);
|
||||
var
|
||||
FontData: TFPCustomFont;
|
||||
MyData: TMemoryStream;
|
||||
CurrentPos: Int64;
|
||||
Boundsheets: array of Int64;
|
||||
i, len: Integer;
|
||||
begin
|
||||
{ Write workbook globals }
|
||||
|
||||
WriteBOF(AStream, INT_BOF_WORKBOOK_GLOBALS);
|
||||
|
||||
WriteWindow1(AStream);
|
||||
|
||||
FontData := TFPCustomFont.Create;
|
||||
try
|
||||
FontData.Name := 'Arial';
|
||||
|
||||
// FONT0
|
||||
WriteFont(AStream, FontData);
|
||||
// FONT1
|
||||
WriteFont(AStream, FontData);
|
||||
// FONT2
|
||||
WriteFont(AStream, FontData);
|
||||
// FONT3
|
||||
WriteFont(AStream, FontData);
|
||||
// FONT5
|
||||
WriteFont(AStream, FontData);
|
||||
finally
|
||||
FontData.Free;
|
||||
end;
|
||||
|
||||
// XF0
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF1
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF2
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF3
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF4
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF5
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF6
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF7
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF8
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF9
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF10
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF11
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF12
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF13
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF14
|
||||
WriteXF(AStream, 0, MASK_XF_TYPE_PROT_STYLE_XF);
|
||||
// XF15
|
||||
WriteXF(AStream, 0, 0);
|
||||
|
||||
WriteStyle(AStream);
|
||||
|
||||
for i := 0 to AData.GetWorksheetCount - 1 do
|
||||
begin
|
||||
len := Length(Boundsheets);
|
||||
SetLength(Boundsheets, len + 1);
|
||||
Boundsheets[len] := WriteBoundsheet(AStream, AData.GetWorksheetByIndex(i).Name);
|
||||
end;
|
||||
|
||||
WriteEOF(AStream);
|
||||
|
||||
{ Write each worksheet }
|
||||
|
||||
for i := 0 to AData.GetWorksheetCount - 1 do
|
||||
begin
|
||||
{ First goes back and writes the position of the BOF of the
|
||||
sheet on the respective BOUNDSHEET record }
|
||||
CurrentPos := AStream.Position;
|
||||
AStream.Position := Boundsheets[i];
|
||||
AStream.WriteDWord(CurrentPos);
|
||||
AStream.Position := CurrentPos;
|
||||
|
||||
WriteBOF(AStream, INT_BOF_SHEET);
|
||||
|
||||
WriteIndex(AStream);
|
||||
|
||||
WriteDimensions(AStream);
|
||||
|
||||
WriteWindow2(AStream, True);
|
||||
|
||||
WriteCellsToStream(AStream, AData.GetWorksheetByIndex(i).FCells);
|
||||
|
||||
WriteEOF(AStream);
|
||||
end;
|
||||
|
||||
{ Cleanup }
|
||||
|
||||
SetLength(Boundsheets, 0);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteBOF ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 BOF record
|
||||
*
|
||||
* This must be the first record on an Excel 5 stream
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteBOF(AStream: TStream; ADataType: Word);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_BOF));
|
||||
AStream.WriteWord(WordToLE(8));
|
||||
|
||||
{ BIFF version. Should only be used if this BOF is for the workbook globals }
|
||||
if ADataType = INT_BOF_WORKBOOK_GLOBALS then
|
||||
AStream.WriteWord(WordToLE(INT_BOF_BIFF5_VER))
|
||||
else AStream.WriteWord(0);
|
||||
|
||||
{ Data type }
|
||||
AStream.WriteWord(WordToLE(ADataType));
|
||||
|
||||
{ Build identifier, must not be 0 }
|
||||
AStream.WriteWord(WordToLE(INT_BOF_BUILD_ID));
|
||||
|
||||
{ Build year, must not be 0 }
|
||||
AStream.WriteWord(WordToLE(INT_BOF_BUILD_YEAR));
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteBoundsheet ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 BOUNDSHEET record
|
||||
*
|
||||
* Always located on the workbook globals substream.
|
||||
*
|
||||
* One BOUNDSHEET is written for each worksheet.
|
||||
*
|
||||
* RETURNS: The stream position where the absolute stream position
|
||||
* of the BOF of this sheet should be written (4 bytes size).
|
||||
*
|
||||
*******************************************************************}
|
||||
function TsSpreadBIFF5Writer.WriteBoundsheet(AStream: TStream; ASheetName: string): Int64;
|
||||
var
|
||||
Len: Byte;
|
||||
begin
|
||||
Len := Length(ASheetName);
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_BOUNDSHEET));
|
||||
AStream.WriteWord(WordToLE(6 + 1 + Len));
|
||||
|
||||
{ Absolute stream position of the BOF record of the sheet represented
|
||||
by this record }
|
||||
Result := AStream.Position;
|
||||
AStream.WriteDWord(WordToLE(0));
|
||||
|
||||
{ Visibility }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Sheet type }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Sheet name: Byte string, 8-bit length }
|
||||
AStream.WriteByte(Len);
|
||||
AStream.WriteBuffer(ASheetName[1], Len);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteIndex ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 DIMENSIONS record
|
||||
*
|
||||
* nm = (rl - rf - 1) / 32 + 1 (using integer division)
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteDimensions(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_DIMENSIONS));
|
||||
AStream.WriteWord(WordToLE(10));
|
||||
|
||||
{ Index to first used row }
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Index to last used row, increased by 1 }
|
||||
AStream.WriteWord(33);
|
||||
|
||||
{ Index to first used column }
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Index to last used column, increased by 1 }
|
||||
AStream.WriteWord(10);
|
||||
|
||||
{ Not used }
|
||||
AStream.WriteWord(0);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteEOF ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 EOF record
|
||||
*
|
||||
* This must be the last record on an Excel 5 stream
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteEOF(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_EOF));
|
||||
AStream.WriteWord($0000);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteFont ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 FONT record
|
||||
*
|
||||
* The font data is passed in an instance of TFPCustomFont
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteFont(AStream: TStream; AFont: TFPCustomFont);
|
||||
var
|
||||
Len: Byte;
|
||||
begin
|
||||
Len := Length(AFont.Name);
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_FONT));
|
||||
AStream.WriteWord(WordToLE(14 + 1 + Len));
|
||||
|
||||
{ Height of the font in twips = 1/20 of a point }
|
||||
AStream.WriteWord(WordToLE(200));
|
||||
|
||||
{ Option flags }
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Colour index }
|
||||
AStream.WriteWord($7FFF);
|
||||
|
||||
{ Font weight }
|
||||
AStream.WriteWord(WordToLE(INT_FONT_WEIGHT_NORMAL));
|
||||
|
||||
{ Escapement type }
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Underline type }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Font family }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Character set }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Not used }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Font name: Byte string, 8-bit length }
|
||||
AStream.WriteByte(Len);
|
||||
AStream.WriteBuffer(AFont.Name[1], Len);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteFormula ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 FORMULA record
|
||||
*
|
||||
* To input a formula to this method, first convert it
|
||||
* to RPN, and then list all it's members in the
|
||||
* AFormula array
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteFormula(AStream: TStream; const ARow,
|
||||
ACol: Word; const AFormula: TRPNFormula);
|
||||
var
|
||||
FormulaResult: double;
|
||||
i: Integer;
|
||||
RPNLength: Word;
|
||||
TokenArraySizePos, RecordSizePos, FinalPos: Int64;
|
||||
begin
|
||||
RPNLength := 0;
|
||||
FormulaResult := 0.0;
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_FORMULA));
|
||||
RecordSizePos := AStream.Position;
|
||||
AStream.WriteWord(WordToLE(22 + RPNLength));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ Index to XF Record }
|
||||
AStream.WriteWord($0000);
|
||||
|
||||
{ Result of the formula in IEE 754 floating-point value }
|
||||
AStream.WriteBuffer(FormulaResult, 8);
|
||||
|
||||
{ Options flags }
|
||||
AStream.WriteWord(WordToLE(MASK_FORMULA_RECALCULATE_ALWAYS));
|
||||
|
||||
{ Not used }
|
||||
AStream.WriteDWord(0);
|
||||
|
||||
{ Formula }
|
||||
|
||||
{ The size of the token array is written later,
|
||||
because it's necessary to calculate if first,
|
||||
and this is done at the same time it is written }
|
||||
TokenArraySizePos := AStream.Position;
|
||||
AStream.WriteWord(RPNLength);
|
||||
|
||||
{ Formula data (RPN token array) }
|
||||
for i := 0 to Length(AFormula) - 1 do
|
||||
begin
|
||||
{ Token identifier }
|
||||
AStream.WriteByte(AFormula[i].TokenID);
|
||||
Inc(RPNLength);
|
||||
|
||||
{ Additional data }
|
||||
case AFormula[i].TokenID of
|
||||
|
||||
{ binary operation tokens }
|
||||
|
||||
INT_EXCEL_TOKEN_TADD, INT_EXCEL_TOKEN_TSUB, INT_EXCEL_TOKEN_TMUL,
|
||||
INT_EXCEL_TOKEN_TDIV, INT_EXCEL_TOKEN_TPOWER: begin end;
|
||||
|
||||
INT_EXCEL_TOKEN_TNUM:
|
||||
begin
|
||||
AStream.WriteBuffer(AFormula[i].DoubleValue, 8);
|
||||
Inc(RPNLength, 8);
|
||||
end;
|
||||
|
||||
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA:
|
||||
begin
|
||||
AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW);
|
||||
AStream.WriteByte(AFormula[i].Col);
|
||||
Inc(RPNLength, 3);
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Write sizes in the end, after we known them }
|
||||
FinalPos := AStream.Position;
|
||||
AStream.position := TokenArraySizePos;
|
||||
AStream.WriteByte(RPNLength);
|
||||
AStream.Position := RecordSizePos;
|
||||
AStream.WriteWord(WordToLE(22 + RPNLength));
|
||||
AStream.position := FinalPos;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteIndex ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 INDEX record
|
||||
*
|
||||
* nm = (rl - rf - 1) / 32 + 1 (using integer division)
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteIndex(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_INDEX));
|
||||
AStream.WriteWord(WordToLE(12));
|
||||
|
||||
{ Not used }
|
||||
AStream.WriteDWord(0);
|
||||
|
||||
{ Index to first used row, rf, 0 based }
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Index to first row of unused tail of sheet, rl, last used row + 1, 0 based }
|
||||
AStream.WriteWord(33);
|
||||
|
||||
{ Absolute stream position of the DEFCOLWIDTH record of the current sheet.
|
||||
If it doesn't exist, the offset points to where it would occur. }
|
||||
AStream.WriteDWord($00);
|
||||
|
||||
{ Array of nm absolute stream positions of the DBCELL record of each Row Block }
|
||||
|
||||
{ OBS: It seams to be no problem just ignoring this part of the record }
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteLabel ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 8 LABEL record
|
||||
*
|
||||
* Writes a string to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteLabel(AStream: TStream; const ARow,
|
||||
ACol: Word; const AValue: string);
|
||||
var
|
||||
L: Word;
|
||||
begin
|
||||
L := Length(AValue);
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_LABEL));
|
||||
AStream.WriteWord(WordToLE(8 + L));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ Index to XF record }
|
||||
AStream.WriteWord(15);
|
||||
|
||||
{ Byte String with 16-bit size }
|
||||
AStream.WriteWord(L);
|
||||
AStream.WriteBuffer(AValue[1], L);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteNumber ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 NUMBER record
|
||||
*
|
||||
* Writes a number (64-bit floating point) to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteNumber(AStream: TStream; const ARow,
|
||||
ACol: Cardinal; const AValue: double);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_NUMBER));
|
||||
AStream.WriteWord(WordToLE(14));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ Index to XF record }
|
||||
AStream.WriteWord($0);
|
||||
|
||||
{ IEE 754 floating-point value }
|
||||
AStream.WriteBuffer(AValue, 8);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteStyle ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 STYLE record
|
||||
*
|
||||
* Registers the name of a user-defined style or
|
||||
* specific options for a built-in cell style.
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteStyle(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_STYLE));
|
||||
AStream.WriteWord(WordToLE(4));
|
||||
|
||||
{ Index to style XF and defines if it's a built-in or used defined style }
|
||||
AStream.WriteWord(WordToLE(MASK_STYLE_BUILT_IN));
|
||||
|
||||
{ Built-in cell style identifier }
|
||||
AStream.WriteByte($00);
|
||||
|
||||
{ Level if the identifier for a built-in style is RowLevel or ColLevel, $FF otherwise }
|
||||
AStream.WriteByte(WordToLE($FF));
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteWindow1 ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 WINDOW1 record
|
||||
*
|
||||
* This record contains general settings for the
|
||||
* document window and global workbook settings.
|
||||
*
|
||||
* The values written here are reasonable defaults,
|
||||
* which should work for most sheets.
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteWindow1(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_WINDOW1));
|
||||
AStream.WriteWord(WordToLE(18));
|
||||
|
||||
{ Horizontal position of the document window, in twips = 1 / 20 of a point }
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Vertical position of the document window, in twips = 1 / 20 of a point }
|
||||
AStream.WriteWord(WordToLE($0069));
|
||||
|
||||
{ Width of the document window, in twips = 1 / 20 of a point }
|
||||
AStream.WriteWord(WordToLE($339F));
|
||||
|
||||
{ Height of the document window, in twips = 1 / 20 of a point }
|
||||
AStream.WriteWord(WordToLE($1B5D));
|
||||
|
||||
{ Option flags }
|
||||
AStream.WriteWord(WordToLE(
|
||||
MASK_WINDOW1_OPTION_HORZ_SCROLL_VISIBLE or
|
||||
MASK_WINDOW1_OPTION_VERT_SCROLL_VISIBLE or
|
||||
MASK_WINDOW1_OPTION_WORKSHEET_TAB_VISIBLE));
|
||||
|
||||
{ Index to active (displayed) worksheet }
|
||||
AStream.WriteWord($00);
|
||||
|
||||
{ Index of first visible tab in the worksheet tab bar }
|
||||
AStream.WriteWord($00);
|
||||
|
||||
{ Number of selected worksheets }
|
||||
AStream.WriteWord(WordToLE(1));
|
||||
|
||||
{ Width of worksheet tab bar (in 1/1000 of window width).
|
||||
The remaining space is used by the horizontal scroll bar }
|
||||
AStream.WriteWord(WordToLE(600));
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteWindow1 ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 WINDOW1 record
|
||||
*
|
||||
* This record contains aditional settings for the
|
||||
* document window (BIFF2-BIFF4) or for a specific
|
||||
* worksheet (BIFF5-BIFF8).
|
||||
*
|
||||
* The values written here are reasonable defaults,
|
||||
* which should work for most sheets.
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteWindow2(AStream: TStream;
|
||||
ASheetSelected: Boolean);
|
||||
var
|
||||
Options: Word;
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_WINDOW2));
|
||||
AStream.WriteWord(WordToLE(10));
|
||||
|
||||
{ Options flags }
|
||||
Options := MASK_WINDOW2_OPTION_SHOW_GRID_LINES or
|
||||
MASK_WINDOW2_OPTION_SHOW_SHEET_HEADERS or
|
||||
MASK_WINDOW2_OPTION_SHOW_ZERO_VALUES or
|
||||
MASK_WINDOW2_OPTION_AUTO_GRIDLINE_COLOR or
|
||||
MASK_WINDOW2_OPTION_SHOW_OUTLINE_SYMBOLS or
|
||||
MASK_WINDOW2_OPTION_SHEET_ACTIVE;
|
||||
|
||||
if ASheetSelected then Options := Options or MASK_WINDOW2_OPTION_SHEET_SELECTED;
|
||||
|
||||
AStream.WriteWord(WordToLE(Options));
|
||||
|
||||
{ Index to first visible row }
|
||||
AStream.WriteWord(WordToLE(0));
|
||||
|
||||
{ Index to first visible column }
|
||||
AStream.WriteWord(WordToLE(0));
|
||||
|
||||
{ Grid line RGB colour }
|
||||
AStream.WriteDWord(WordToLE(0));
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteXF ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 XF record
|
||||
*
|
||||
* Writes a number (64-bit floating point) to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteXF(AStream: TStream; AFontIndex: Word;
|
||||
AXF_TYPE_PROT: Byte);
|
||||
var
|
||||
XFOptions: Word;
|
||||
XFAlignment, XFOrientationAttrib: Byte;
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_XF));
|
||||
AStream.WriteWord(WordToLE(16));
|
||||
|
||||
{ Index to FONT record }
|
||||
AStream.WriteWord(WordToLE(AFontIndex));
|
||||
|
||||
{ Index to FORMAT record }
|
||||
AStream.WriteWord($00);
|
||||
|
||||
{ XF type, cell protection and parent style XF }
|
||||
XFOptions := AXF_TYPE_PROT and MASK_XF_TYPE_PROT;
|
||||
|
||||
if AXF_TYPE_PROT and MASK_XF_TYPE_PROT_STYLE_XF <> 0 then
|
||||
XFOptions := XFOptions or MASK_XF_TYPE_PROT_PARENT;
|
||||
|
||||
AStream.WriteWord(WordToLE(XFOptions));
|
||||
|
||||
{ Alignment and text break }
|
||||
XFAlignment := MASK_XF_VERT_ALIGN_BOTTOM;
|
||||
|
||||
AStream.WriteByte(WordToLE(XFAlignment));
|
||||
|
||||
{ Text orientation and flags for used attribute groups }
|
||||
XFOrientationAttrib :=
|
||||
MASK_XF_USED_ATTRIB_NUMBER_FORMAT or
|
||||
MASK_XF_USED_ATTRIB_FONT or
|
||||
MASK_XF_USED_ATTRIB_TEXT or
|
||||
MASK_XF_USED_ATTRIB_BORDER_LINES or
|
||||
MASK_XF_USED_ATTRIB_BACKGROUND or
|
||||
MASK_XF_USED_ATTRIB_CELL_PROTECTION;
|
||||
|
||||
AStream.WriteByte(WordToLE(XFOrientationAttrib));
|
||||
|
||||
{ Cell border lines and background area }
|
||||
AStream.WriteDWord($000020C0);
|
||||
AStream.WriteDWord($00000000);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* Initialization section
|
||||
*
|
||||
* Registers this reader / writer on fpSpreadsheet
|
||||
*
|
||||
*******************************************************************}
|
||||
initialization
|
||||
|
||||
RegisterSpreadFormat(TsCustomSpreadReader, TsSpreadBIFF5Writer, sfExcel5);
|
||||
|
||||
end.
|
||||
|
430
components/fpspreadsheet/xlsbiff8.pas
Executable file
430
components/fpspreadsheet/xlsbiff8.pas
Executable file
@ -0,0 +1,430 @@
|
||||
{
|
||||
xlsbiff5.pas
|
||||
|
||||
Writes an Excel 5 file
|
||||
|
||||
An Excel worksheet stream consists of a number of subsequent records.
|
||||
To ensure a properly formed file, the following order must be respected:
|
||||
|
||||
1st record: BOF
|
||||
2nd to Nth record: Any record
|
||||
Last record: EOF
|
||||
|
||||
Excel 5 files are OLE compound document files, and must be written using the
|
||||
fpOLE library.
|
||||
|
||||
Records Needed to Make a BIFF5 File Microsoft Excel Can Use:
|
||||
|
||||
Required Records:
|
||||
|
||||
BOF - Set the 6 byte offset to 0x0005 (workbook globals)
|
||||
Window1
|
||||
FONT - At least five of these records must be included
|
||||
XF - At least 15 Style XF records and 1 Cell XF record must be included
|
||||
STYLE
|
||||
BOUNDSHEET - Include one BOUNDSHEET record per worksheet
|
||||
EOF
|
||||
|
||||
BOF - Set the 6 byte offset to 0x0010 (worksheet)
|
||||
INDEX
|
||||
DIMENSIONS
|
||||
WINDOW2
|
||||
EOF
|
||||
|
||||
Excel file format specification obtained from:
|
||||
|
||||
http://sc.openoffice.org/excelfileformat.pdf
|
||||
|
||||
Records Needed to Make a BIFF5 File Microsoft Excel Can Use obtained from:
|
||||
|
||||
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q147732&ID=KB;EN-US;Q147732&LN=EN-US&rnk=2&SD=msdn&FR=0&qry=BIFF&src=DHCS_MSPSS_msdn_SRCH&SPR=MSALL&
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
}
|
||||
unit xlsbiff8;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}{$H+}
|
||||
{$endif}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils,
|
||||
fpspreadsheet;
|
||||
|
||||
type
|
||||
|
||||
{ TsSpreadBIFF5Writer }
|
||||
|
||||
TsSpreadBIFF5Writer = class(TsCustomSpreadWriter)
|
||||
public
|
||||
{ General writing methods }
|
||||
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); override;
|
||||
{ Record writing methods }
|
||||
procedure WriteBOF(AStream: TStream);
|
||||
procedure WriteEOF(AStream: TStream);
|
||||
procedure WriteFont(AStream: TStream; AFontName: Widestring = 'Arial');
|
||||
procedure WriteFormat(AStream: TStream; AIndex: Word = 0; AFormatString: Widestring = 'General');
|
||||
procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TRPNFormula); override;
|
||||
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override;
|
||||
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override;
|
||||
procedure WriteXF(AStream: TStream);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
{ Excel record IDs }
|
||||
INT_EXCEL_ID_BOF = $0809;
|
||||
INT_EXCEL_ID_EOF = $000A;
|
||||
INT_EXCEL_ID_FONT = $0031;
|
||||
INT_EXCEL_ID_FORMAT = $041E;
|
||||
INT_EXCEL_ID_FORMULA = $0006;
|
||||
INT_EXCEL_ID_LABEL = $0004;
|
||||
INT_EXCEL_ID_NUMBER = $0203;
|
||||
INT_EXCEL_ID_XF = $00E0;
|
||||
|
||||
{ Cell Addresses constants }
|
||||
MASK_EXCEL_ROW = $3FFF;
|
||||
MASK_EXCEL_RELATIVE_ROW = $4000;
|
||||
MASK_EXCEL_RELATIVE_COL = $8000;
|
||||
|
||||
{ Unicode string constants }
|
||||
INT_EXCEL_UNCOMPRESSED_STRING = $01;
|
||||
|
||||
{ BOF record constants }
|
||||
INT_EXCEL_BIFF8_VER = $0600;
|
||||
INT_EXCEL_WORKBOOK = $0005;
|
||||
INT_EXCEL_SHEET = $0010;
|
||||
INT_EXCEL_CHART = $0020;
|
||||
INT_EXCEL_MACRO_SHEET = $0040;
|
||||
INT_EXCEL_BUILD_ID = $1FD2;
|
||||
INT_EXCEL_BUILD_YEAR = $07CD;
|
||||
INT_EXCEL_FILE_HISTORY = $0000C0C1;
|
||||
INT_EXCEL_LOWEST_VER = $00000306;
|
||||
|
||||
{ FONT record constants}
|
||||
INT_EXCEL_FONTWEIGHT_NORMAL = $0190;
|
||||
|
||||
{ XF record constants }
|
||||
INT_EXCEL_XF_TYPE_PROT_STYLEXF = $FFF4;
|
||||
|
||||
{
|
||||
Excel files are all written with Little Endian number,
|
||||
so it's necessary to swap the numbers to be able to build a
|
||||
correct file on big endian systems.
|
||||
|
||||
Endianess helper functions
|
||||
}
|
||||
|
||||
function WordToLE(AValue: Word): Word;
|
||||
begin
|
||||
{$IFDEF BIG_ENDIAN}
|
||||
Result := ((AValue shl 8) and $FF00) or ((AValue shr 8) and $00FF);
|
||||
{$ELSE}
|
||||
Result := AValue;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{
|
||||
Exported functions
|
||||
}
|
||||
|
||||
{ TsSpreadBIFF5Writer }
|
||||
|
||||
procedure TsSpreadBIFF5Writer.WriteToStream(AStream: TStream; AData: TsWorkbook);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteBOF ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 BOF record
|
||||
*
|
||||
* This must be the first record on an Excel 5 stream
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteBOF(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_BOF));
|
||||
AStream.WriteWord(WordToLE(16));
|
||||
|
||||
{ BIFF version }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_BIFF8_VER));
|
||||
|
||||
{ Data type }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_WORKBOOK));
|
||||
|
||||
{ Build identifier, must not be 0 }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_BUILD_ID));
|
||||
|
||||
{ Build year, must not be 0 }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_BUILD_YEAR));
|
||||
|
||||
{ File history flags }
|
||||
// AStream.WriteDWord($00000000);
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_FILE_HISTORY));
|
||||
|
||||
{ Lowest Excel version that can read all records of this file }
|
||||
// AStream.WriteDWord($00000000);
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_LOWEST_VER));
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteEOF ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 EOF record
|
||||
*
|
||||
* This must be the last record on an Excel 5 stream
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteEOF(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_EOF));
|
||||
AStream.WriteWord($0000);
|
||||
end;
|
||||
|
||||
procedure TsSpreadBIFF5Writer.WriteFont(AStream: TStream;
|
||||
AFontName: Widestring);
|
||||
var
|
||||
Len: Byte;
|
||||
begin
|
||||
Len := Length(AFontName);
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_FONT));
|
||||
AStream.WriteWord(WordToLE(14 + 2 + Len*2));
|
||||
|
||||
{ Height of the font in twips = 1/20 of a point }
|
||||
AStream.WriteWord(WordToLE(200));
|
||||
|
||||
{ Option flags }
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Colour index }
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Font weight }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_FONTWEIGHT_NORMAL));
|
||||
|
||||
{ Underline type }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Font family }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Character set }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Not used }
|
||||
AStream.WriteByte(0);
|
||||
|
||||
{ Font name: Unicode string, 8-bit length }
|
||||
AStream.WriteByte(Len);
|
||||
AStream.WriteByte(INT_EXCEL_UNCOMPRESSED_STRING);
|
||||
AStream.WriteBuffer(AFontName[1], Len*2);
|
||||
end;
|
||||
|
||||
procedure TsSpreadBIFF5Writer.WriteFormat(AStream: TStream; AIndex: Word;
|
||||
AFormatString: Widestring);
|
||||
var
|
||||
Len: Integer;
|
||||
begin
|
||||
Len := Length(AFormatString);
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_FORMAT));
|
||||
AStream.WriteWord(WordToLE(2 + 3 + Len*2));
|
||||
|
||||
{ Format index used by other records }
|
||||
AStream.WriteWord(WordToLE(AIndex));
|
||||
|
||||
{ Unicode string, 16-bit length }
|
||||
AStream.WriteWord(WordToLE(Len));
|
||||
AStream.WriteByte(INT_EXCEL_UNCOMPRESSED_STRING);
|
||||
AStream.WriteBuffer(AFormatString[1], Len*2);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteFormula ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 FORMULA record
|
||||
*
|
||||
* To input a formula to this method, first convert it
|
||||
* to RPN, and then list all it's members in the
|
||||
* AFormula array
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteFormula(AStream: TStream; const ARow,
|
||||
ACol: Word; const AFormula: TRPNFormula);
|
||||
var
|
||||
FormulaResult: double;
|
||||
i: Integer;
|
||||
RPNLength: Word;
|
||||
TokenArraySizePos, RecordSizePos, FinalPos: Cardinal;
|
||||
begin
|
||||
RPNLength := 0;
|
||||
FormulaResult := 0.0;
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_FORMULA));
|
||||
RecordSizePos := AStream.Position;
|
||||
AStream.WriteWord(WordToLE(17 + RPNLength));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ Result of the formula in IEE 754 floating-point value }
|
||||
AStream.WriteBuffer(FormulaResult, 8);
|
||||
|
||||
{ 0 = Do not recalculate
|
||||
1 = Always recalculate }
|
||||
AStream.WriteByte($1);
|
||||
|
||||
{ Formula }
|
||||
|
||||
{ The size of the token array is written later,
|
||||
because it's necessary to calculate if first,
|
||||
and this is done at the same time it is written }
|
||||
TokenArraySizePos := AStream.Position;
|
||||
AStream.WriteByte(RPNLength);
|
||||
|
||||
{ Formula data (RPN token array) }
|
||||
for i := 0 to Length(AFormula) - 1 do
|
||||
begin
|
||||
{ Token identifier }
|
||||
AStream.WriteByte(AFormula[i].TokenID);
|
||||
Inc(RPNLength);
|
||||
|
||||
{ Additional data }
|
||||
case AFormula[i].TokenID of
|
||||
|
||||
{ binary operation tokens }
|
||||
|
||||
INT_EXCEL_TOKEN_TADD, INT_EXCEL_TOKEN_TSUB, INT_EXCEL_TOKEN_TMUL,
|
||||
INT_EXCEL_TOKEN_TDIV, INT_EXCEL_TOKEN_TPOWER: begin end;
|
||||
|
||||
INT_EXCEL_TOKEN_TNUM:
|
||||
begin
|
||||
AStream.WriteBuffer(AFormula[i].DoubleValue, 8);
|
||||
Inc(RPNLength, 8);
|
||||
end;
|
||||
|
||||
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA:
|
||||
begin
|
||||
AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW);
|
||||
AStream.WriteByte(AFormula[i].Col);
|
||||
Inc(RPNLength, 3);
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Write sizes in the end, after we known them }
|
||||
FinalPos := AStream.Position;
|
||||
AStream.position := TokenArraySizePos;
|
||||
AStream.WriteByte(RPNLength);
|
||||
AStream.Position := RecordSizePos;
|
||||
AStream.WriteWord(WordToLE(17 + RPNLength));
|
||||
AStream.position := FinalPos;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteLabel ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 8 LABEL record
|
||||
*
|
||||
* Writes a string to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteLabel(AStream: TStream; const ARow,
|
||||
ACol: Word; const AValue: string);
|
||||
var
|
||||
L: Byte;
|
||||
begin
|
||||
L := Length(AValue);
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_LABEL));
|
||||
AStream.WriteWord(WordToLE(8 + L));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ String with 8-bit size }
|
||||
AStream.WriteByte(L);
|
||||
AStream.WriteBuffer(Pointer(AValue)^, L);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadBIFF5Writer.WriteNumber ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 5 NUMBER record
|
||||
*
|
||||
* Writes a number (64-bit floating point) to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadBIFF5Writer.WriteNumber(AStream: TStream; const ARow,
|
||||
ACol: Cardinal; const AValue: double);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_NUMBER));
|
||||
AStream.WriteWord(WordToLE(14));
|
||||
|
||||
{ BIFF Record data }
|
||||
AStream.WriteWord(WordToLE(ARow));
|
||||
AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ Index to XF record }
|
||||
AStream.WriteWord($0);
|
||||
|
||||
{ IEE 754 floating-point value }
|
||||
AStream.WriteBuffer(AValue, 8);
|
||||
end;
|
||||
|
||||
procedure TsSpreadBIFF5Writer.WriteXF(AStream: TStream);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_XF));
|
||||
AStream.WriteWord(WordToLE(12));
|
||||
|
||||
{ Index to FONT record }
|
||||
AStream.WriteByte($00);
|
||||
|
||||
{ Index to FORMAT record }
|
||||
AStream.WriteByte($00);
|
||||
|
||||
{ XF type, cell protection and parent style XF }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_XF_TYPE_PROT_STYLEXF));
|
||||
|
||||
{ Alignment, text break and text orientation }
|
||||
AStream.WriteByte($00);
|
||||
|
||||
{ Flags for used attribute groups }
|
||||
AStream.WriteByte($00);
|
||||
|
||||
{ XF_AREA_34 - Cell background area }
|
||||
AStream.WriteWord($0000);
|
||||
|
||||
{ XF_BORDER_34 - Cell border lines }
|
||||
AStream.WriteDWord($00000000);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
383
components/fpspreadsheet/xlsxooxml.pas
Executable file
383
components/fpspreadsheet/xlsxooxml.pas
Executable file
@ -0,0 +1,383 @@
|
||||
{
|
||||
xlsxooxml.pas
|
||||
|
||||
Writes an OOXML (Office Open XML) document
|
||||
|
||||
An OOXML document is a compressed ZIP file with the following files inside:
|
||||
|
||||
[Content_Types].xml
|
||||
_rels\.rels
|
||||
xl\_rels\workbook.xml.rels
|
||||
xl\workbook.xml
|
||||
xl\styles.xml
|
||||
xl\sharedStrings.xml
|
||||
xl\worksheets\sheet1.xml
|
||||
...
|
||||
xl\worksheets\sheetN.xml
|
||||
|
||||
Specifications obtained from:
|
||||
|
||||
http://openxmldeveloper.org/default.aspx
|
||||
|
||||
AUTHORS: Felipe Monteiro de Carvalho
|
||||
|
||||
IMPORTANT: This writer doesn't work yet!!! This is just initial code.
|
||||
}
|
||||
unit xlsxooxml;
|
||||
|
||||
{$ifdef fpc}
|
||||
{$mode delphi}
|
||||
{$endif}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, {zipper,}
|
||||
fpspreadsheet;
|
||||
|
||||
type
|
||||
|
||||
{ TsSpreadOOXMLWriter }
|
||||
|
||||
TsSpreadOOXMLWriter = class(TsCustomSpreadWriter)
|
||||
protected
|
||||
// FZip: TZipper;
|
||||
FContentTypes: string;
|
||||
FRelsRels: string;
|
||||
FWorkbook, FWorkbookRels, FStyles, FSharedString, FSheet1: string;
|
||||
public
|
||||
{ General writing methods }
|
||||
procedure WriteStringToFile(AFileName, AString: string);
|
||||
procedure WriteToFile(AFileName: string; AData: TsWorkbook); override;
|
||||
procedure WriteToStream(AStream: TStream; AData: TsWorkbook); override;
|
||||
{ Record writing methods }
|
||||
procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); override;
|
||||
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; const AValue: double); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
{ OOXML general XML constants }
|
||||
XML_HEADER = '<?xml version="1.0" encoding="utf-8" ?>';
|
||||
|
||||
{ OOXML Directory structure constants }
|
||||
OOXML_PATH_TYPES = '[Content_Types].xml';
|
||||
OOXML_PATH_RELS = '_rels\';
|
||||
OOXML_PATH_RELS_RELS = '_rels\.rels';
|
||||
OOXML_PATH_XL = 'xl\';
|
||||
OOXML_PATH_XL_RELS = 'xl\_rels\';
|
||||
OOXML_PATH_XL_RELS_RELS = 'xl\_rels\workbook.xml.rels';
|
||||
OOXML_PATH_XL_WORKBOOK = 'xl\workbook.xml';
|
||||
OOXML_PATH_XL_STYLES = 'xl\styles.xml';
|
||||
OOXML_PATH_XL_STRINGS = 'xl\sharedStrings.xml';
|
||||
OOXML_PATH_XL_WORKSHEETS = 'xl\worksheets\';
|
||||
|
||||
{ OOXML schemas constants }
|
||||
SCHEMAS_TYPES = 'http://schemas.openxmlformats.org/package/2006/content-types';
|
||||
SCHEMAS_RELS = 'http://schemas.openxmlformats.org/package/2006/relationships';
|
||||
SCHEMAS_DOC_RELS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
|
||||
SCHEMAS_DOCUMENT = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument';
|
||||
SCHEMAS_WORKSHEET = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet';
|
||||
SCHEMAS_STYLES = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles';
|
||||
SCHEMAS_STRINGS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings';
|
||||
SCHEMAS_SPREADML = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';
|
||||
|
||||
{ OOXML mime types constants }
|
||||
MIME_XML = 'application/xml';
|
||||
MIME_RELS = 'application/vnd.openxmlformats-package.relationships+xml';
|
||||
MIME_SPREADML = 'application/vnd.openxmlformats-officedocument.spreadsheetml';
|
||||
MIME_SHEET = MIME_SPREADML + '.sheet.main+xml';
|
||||
MIME_WORKSHEET = MIME_SPREADML + '.worksheet+xml';
|
||||
MIME_STYLES = MIME_SPREADML + '.styles+xml';
|
||||
MIME_STRINGS = MIME_SPREADML + '.sharedStrings+xml';
|
||||
|
||||
{ TsSpreadOOXMLWriter }
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteStringToFile ()
|
||||
*
|
||||
* DESCRIPTION: Writes a string to a file. Helper convenience method.
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOOXMLWriter.WriteStringToFile(AFileName, AString: string);
|
||||
var
|
||||
TheStream : TFileStream;
|
||||
S : String;
|
||||
begin
|
||||
TheStream := TFileStream.Create(AFileName, fmCreate);
|
||||
S:=AString;
|
||||
TheStream.WriteBuffer(Pointer(S)^,Length(S));
|
||||
TheStream.Free;
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteToFile ()
|
||||
*
|
||||
* DESCRIPTION: Writes an OOXML document to the disc
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOOXMLWriter.WriteToFile(AFileName: string; AData: TsWorkbook);
|
||||
var
|
||||
TempDir: string;
|
||||
begin
|
||||
{FZip := TZipper.Create;
|
||||
FZip.ZipFiles(AFileName, x);
|
||||
FZip.Free;}
|
||||
|
||||
WriteToStream(nil, AData);
|
||||
|
||||
TempDir := IncludeTrailingBackslash(AFileName);
|
||||
|
||||
{ files on the root path }
|
||||
|
||||
ForceDirectories(TempDir);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_TYPES, FContentTypes);
|
||||
|
||||
{ _rels directory }
|
||||
|
||||
ForceDirectories(TempDir + OOXML_PATH_RELS);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_RELS_RELS, FRelsRels);
|
||||
|
||||
{ xl directory }
|
||||
|
||||
ForceDirectories(TempDir + OOXML_PATH_XL_RELS);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_XL_RELS_RELS, FWorkbookRels);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_XL_WORKBOOK, FWorkbook);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_XL_STYLES, FStyles);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_XL_STRINGS, FSharedString);
|
||||
|
||||
{ xl\worksheets directory }
|
||||
|
||||
ForceDirectories(TempDir + OOXML_PATH_XL_WORKSHEETS);
|
||||
|
||||
WriteStringToFile(TempDir + OOXML_PATH_XL_WORKSHEETS + 'sheet1.xml', FSheet1);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteToStream ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 file to a stream
|
||||
*
|
||||
* Excel 2.x files support only one Worksheet per Workbook,
|
||||
* so only the first will be written.
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOOXMLWriter.WriteToStream(AStream: TStream; AData: TsWorkbook);
|
||||
begin
|
||||
// WriteCellsToStream(AStream, AData.GetFirstWorksheet.FCells);
|
||||
|
||||
FContentTypes :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<Types xmlns="' + SCHEMAS_TYPES + '">' + LineEnding +
|
||||
' <Default Extension="xml" ContentType="' + MIME_XML + '" />' + LineEnding +
|
||||
' <Default Extension="rels" ContentType="' + MIME_RELS + '" />' + LineEnding +
|
||||
' <Override PartName="/xl/workbook.xml" ContentType="' + MIME_SHEET + '" />' + LineEnding +
|
||||
' <Override PartName="/xl/worksheets/sheet1.xml" ContentType="' + MIME_WORKSHEET + '" />' + LineEnding +
|
||||
' <Override PartName="/xl/styles.xml" ContentType="' + MIME_STYLES + '" />' + LineEnding +
|
||||
' <Override PartName="/xl/sharedStrings.xml" ContentType="' + MIME_STRINGS + '" />' + LineEnding +
|
||||
'</Types>';
|
||||
|
||||
FRelsRels :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<Relationships xmlns="' + SCHEMAS_RELS + '">' + LineEnding +
|
||||
'<Relationship Type="' + SCHEMAS_DOCUMENT + '" Target="/xl/workbook.xml" Id="rId1" />' + LineEnding +
|
||||
'</Relationships>';
|
||||
|
||||
FWorkbookRels :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<Relationships xmlns="' + SCHEMAS_RELS + '">' + LineEnding +
|
||||
'<Relationship Type="' + SCHEMAS_WORKSHEET + '" Target="/xl/worksheets/sheet1.xml" Id="rId1" />' + LineEnding +
|
||||
'<Relationship Type="' + SCHEMAS_STYLES + '" Target="/xl/styles.xml" Id="rId2" />' + LineEnding +
|
||||
'<Relationship Type="' + SCHEMAS_STRINGS + '" Target="/xl/sharedStrings.xml" Id="rId3" />' + LineEnding +
|
||||
'</Relationships>';
|
||||
|
||||
FWorkbook :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<workbook xmlns="' + SCHEMAS_SPREADML + '" xmlns:r="' + SCHEMAS_DOC_RELS + '">' + LineEnding +
|
||||
' <fileVersion appName="xl" lastEdited="4" lowestEdited="4" rupBuild="4505" />' + LineEnding +
|
||||
' <workbookPr defaultThemeVersion="124226" />' + LineEnding +
|
||||
' <bookViews>' + LineEnding +
|
||||
' <workbookView xWindow="480" yWindow="90" windowWidth="15195" windowHeight="12525" />' + LineEnding +
|
||||
' </bookViews>' + LineEnding +
|
||||
' <sheets>' + LineEnding +
|
||||
' <sheet name="Sheet1" sheetId="1" r:id="rId1" />' + LineEnding +
|
||||
' </sheets>' + LineEnding +
|
||||
' <calcPr calcId="114210" />' + LineEnding +
|
||||
'</workbook>';
|
||||
|
||||
FStyles :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<styleSheet xmlns="' + SCHEMAS_SPREADML + '">' + LineEnding +
|
||||
' <fonts count="1">' + LineEnding +
|
||||
' <font>' + LineEnding +
|
||||
' <sz val="10" />' + LineEnding +
|
||||
' <name val="Arial" />' + LineEnding +
|
||||
' </font>' + LineEnding +
|
||||
' </fonts>' + LineEnding +
|
||||
' <fills count="2">' + LineEnding +
|
||||
' <fill>' + LineEnding +
|
||||
' <patternFill patternType="none" />' + LineEnding +
|
||||
' </fill>' + LineEnding +
|
||||
' <fill>' + LineEnding +
|
||||
' <patternFill patternType="gray125" />' + LineEnding +
|
||||
' </fill>' + LineEnding +
|
||||
' </fills>' + LineEnding +
|
||||
' <borders count="1">' + LineEnding +
|
||||
' <border>' + LineEnding +
|
||||
' <left />' + LineEnding +
|
||||
' <right />' + LineEnding +
|
||||
' <top />' + LineEnding +
|
||||
' <bottom />' + LineEnding +
|
||||
' <diagonal />' + LineEnding +
|
||||
' </border>' + LineEnding +
|
||||
' </borders>' + LineEnding +
|
||||
' <cellStyleXfs count="1">' + LineEnding +
|
||||
' <xf numFmtId="0" fontId="0" fillId="0" borderId="0" />' + LineEnding +
|
||||
' </cellStyleXfs>' + LineEnding +
|
||||
' <cellXfs count="1">' + LineEnding +
|
||||
' <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" />' + LineEnding +
|
||||
' </cellXfs>' + LineEnding +
|
||||
' <cellStyles count="1">' + LineEnding +
|
||||
' <cellStyle name="Normal" xfId="0" builtinId="0" />' + LineEnding +
|
||||
' </cellStyles>' + LineEnding +
|
||||
' <dxfs count="0" />' + LineEnding +
|
||||
' <tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleLight16" />' + LineEnding +
|
||||
'</styleSheet>';
|
||||
|
||||
FSharedString :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<sst xmlns="' + SCHEMAS_SPREADML + '" count="4" uniqueCount="4">' + LineEnding +
|
||||
' <si>' + LineEnding +
|
||||
' <t>First</t>' + LineEnding +
|
||||
' </si>' + LineEnding +
|
||||
' <si>' + LineEnding +
|
||||
' <t>Second</t>' + LineEnding +
|
||||
' </si>' + LineEnding +
|
||||
' <si>' + LineEnding +
|
||||
' <t>Third</t>' + LineEnding +
|
||||
' </si>' + LineEnding +
|
||||
' <si>' + LineEnding +
|
||||
' <t>Fourth</t>' + LineEnding +
|
||||
' </si>' + LineEnding +
|
||||
'</sst>';
|
||||
|
||||
FSheet1 :=
|
||||
XML_HEADER + LineEnding +
|
||||
'<worksheet xmlns="' + SCHEMAS_SPREADML + '" xmlns:r="' + SCHEMAS_DOC_RELS + '">' + LineEnding +
|
||||
' <sheetViews>' + LineEnding +
|
||||
' <sheetView workbookViewId="0" />' + LineEnding +
|
||||
' </sheetViews>' + LineEnding +
|
||||
' <sheetData>' + LineEnding +
|
||||
' <row r="1" spans="1:4">' + LineEnding +
|
||||
' <c r="A1">' + LineEnding +
|
||||
' <v>1</v>' + LineEnding +
|
||||
' </c>' + LineEnding +
|
||||
' <c r="B1">' + LineEnding +
|
||||
' <v>2</v>' + LineEnding +
|
||||
' </c>' + LineEnding +
|
||||
' <c r="C1">' + LineEnding +
|
||||
' <v>3</v>' + LineEnding +
|
||||
' </c>' + LineEnding +
|
||||
' <c r="D1">' + LineEnding +
|
||||
' <v>4</v>' + LineEnding +
|
||||
' </c>' + LineEnding +
|
||||
' </row>' + LineEnding +
|
||||
' <row r="2" spans="1:4">' + LineEnding +
|
||||
' <c r="A2" t="s">' + LineEnding +
|
||||
' <v>0</v>' + LineEnding +
|
||||
' </c>' + LineEnding +
|
||||
' <c r="B2" t="s">' + LineEnding +
|
||||
' <v>1</v>' + LineEnding +
|
||||
' </c>' + LineEnding +
|
||||
' <c r="C2" t="s">' + LineEnding +
|
||||
' <v>2</v>' + LineEnding +
|
||||
' </c>' + LineEnding +
|
||||
' <c r="D2" t="s">' + LineEnding +
|
||||
' <v>3</v>' + LineEnding +
|
||||
' </c>' + LineEnding +
|
||||
' </row>' + LineEnding +
|
||||
' </sheetData>' + LineEnding +
|
||||
'</worksheet>';
|
||||
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteLabel ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 LABEL record
|
||||
*
|
||||
* Writes a string to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOOXMLWriter.WriteLabel(AStream: TStream; const ARow,
|
||||
ACol: Word; const AValue: string);
|
||||
var
|
||||
L: Byte;
|
||||
begin
|
||||
L := Length(AValue);
|
||||
|
||||
{ BIFF Record header }
|
||||
// AStream.WriteWord(WordToLE(INT_EXCEL_ID_LABEL));
|
||||
// AStream.WriteWord(WordToLE(8 + L));
|
||||
|
||||
{ BIFF Record data }
|
||||
// AStream.WriteWord(WordToLE(ARow));
|
||||
// AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ String with 8-bit size }
|
||||
AStream.WriteByte(L);
|
||||
AStream.WriteBuffer(AValue[1], L);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* TsSpreadOOXMLWriter.WriteNumber ()
|
||||
*
|
||||
* DESCRIPTION: Writes an Excel 2 NUMBER record
|
||||
*
|
||||
* Writes a number (64-bit IEE 754 floating point) to the sheet
|
||||
*
|
||||
*******************************************************************}
|
||||
procedure TsSpreadOOXMLWriter.WriteNumber(AStream: TStream; const ARow,
|
||||
ACol: Cardinal; const AValue: double);
|
||||
begin
|
||||
{ BIFF Record header }
|
||||
// AStream.WriteWord(WordToLE(INT_EXCEL_ID_NUMBER));
|
||||
// AStream.WriteWord(WordToLE(15));
|
||||
|
||||
{ BIFF Record data }
|
||||
// AStream.WriteWord(WordToLE(ARow));
|
||||
// AStream.WriteWord(WordToLE(ACol));
|
||||
|
||||
{ BIFF2 Attributes }
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
AStream.WriteByte($0);
|
||||
|
||||
{ IEE 754 floating-point value }
|
||||
AStream.WriteBuffer(AValue, 8);
|
||||
end;
|
||||
|
||||
{*******************************************************************
|
||||
* Initialization section
|
||||
*
|
||||
* Registers this reader / writer on fpSpreadsheet
|
||||
*
|
||||
*******************************************************************}
|
||||
initialization
|
||||
|
||||
RegisterSpreadFormat(TsCustomSpreadReader, TsSpreadOOXMLWriter, sfOOXML);
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user