{
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 = '';
{ 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 +
'' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
'';
FRelsRels :=
XML_HEADER + LineEnding +
'' + LineEnding +
'' + LineEnding +
'';
FWorkbookRels :=
XML_HEADER + LineEnding +
'' + LineEnding +
'' + LineEnding +
'' + LineEnding +
'' + LineEnding +
'';
FWorkbook :=
XML_HEADER + LineEnding +
'' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
'';
FStyles :=
XML_HEADER + LineEnding +
'' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
'';
FSharedString :=
XML_HEADER + LineEnding +
'' + LineEnding +
' ' + LineEnding +
' First' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' Second' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' Third' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' Fourth' + LineEnding +
' ' + LineEnding +
'';
FSheet1 :=
XML_HEADER + LineEnding +
'' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' 1' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' 2' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' 3' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' 4' + LineEnding +
' ' + LineEnding +
'
' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' 0' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' 1' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' 2' + LineEnding +
' ' + LineEnding +
' ' + LineEnding +
' 3' + LineEnding +
' ' + LineEnding +
'
' + LineEnding +
' ' + LineEnding +
'';
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.