fpspreadsheet: Improves OpenDocument support and rows/cols are now 1-based

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@686 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat
2009-01-29 11:30:38 +00:00
parent 47baa4b5a9
commit f8cd84c9ee
10 changed files with 181 additions and 177 deletions

View File

@ -38,8 +38,8 @@
<Filename Value="excel2read.lpr"/> <Filename Value="excel2read.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="excel2read"/> <UnitName Value="excel2read"/>
<CursorPos X="1" Y="42"/> <CursorPos X="3" Y="37"/>
<TopLine Value="24"/> <TopLine Value="25"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<UsageCount Value="309"/> <UsageCount Value="309"/>
<Loaded Value="True"/> <Loaded Value="True"/>

View File

@ -38,7 +38,7 @@
<Filename Value="excel2write.lpr"/> <Filename Value="excel2write.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="excel2write"/> <UnitName Value="excel2write"/>
<CursorPos X="24" Y="37"/> <CursorPos X="21" Y="43"/>
<TopLine Value="18"/> <TopLine Value="18"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<UsageCount Value="309"/> <UsageCount Value="309"/>
@ -116,8 +116,8 @@
<Unit10> <Unit10>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<UnitName Value="fpspreadsheet"/> <UnitName Value="fpspreadsheet"/>
<CursorPos X="3" Y="428"/> <CursorPos X="21" Y="67"/>
<TopLine Value="420"/> <TopLine Value="57"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<UsageCount Value="92"/> <UsageCount Value="92"/>
<Loaded Value="True"/> <Loaded Value="True"/>

View File

@ -25,16 +25,16 @@ begin
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet'); MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet');
// Write some number cells // Write some number cells
MyWorksheet.WriteNumber(0, 0, 1.0); MyWorksheet.WriteNumber(1, 1, 1.0);
MyWorksheet.WriteNumber(0, 1, 2.0); MyWorksheet.WriteNumber(1, 2, 2.0);
MyWorksheet.WriteNumber(0, 2, 3.0); MyWorksheet.WriteNumber(1, 3, 3.0);
MyWorksheet.WriteNumber(0, 3, 4.0); MyWorksheet.WriteNumber(1, 4, 4.0);
// Write some string cells // Write some string cells
MyWorksheet.WriteUTF8Text(1, 0, 'First'); MyWorksheet.WriteUTF8Text(2, 1, 'First');
MyWorksheet.WriteUTF8Text(1, 1, 'Second'); MyWorksheet.WriteUTF8Text(2, 2, 'Second');
MyWorksheet.WriteUTF8Text(1, 2, 'Third'); MyWorksheet.WriteUTF8Text(2, 3, 'Third');
MyWorksheet.WriteUTF8Text(1, 3, 'Fourth'); MyWorksheet.WriteUTF8Text(2, 4, 'Fourth');
// Save the spreadsheet to a file // Save the spreadsheet to a file
MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel2); MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel2);

View File

@ -28,10 +28,10 @@ begin
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet'); MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet');
// Write some number cells // Write some number cells
MyWorksheet.WriteNumber(0, 0, 1.0); MyWorksheet.WriteNumber(1, 1, 1.0);
MyWorksheet.WriteNumber(0, 1, 2.0); MyWorksheet.WriteNumber(1, 2, 2.0);
MyWorksheet.WriteNumber(0, 2, 3.0); MyWorksheet.WriteNumber(1, 3, 3.0);
MyWorksheet.WriteNumber(0, 3, 4.0); MyWorksheet.WriteNumber(1, 4, 4.0);
{ Uncommend this to test large XLS files { Uncommend this to test large XLS files
for i := 2 to 20 do for i := 2 to 20 do
@ -47,22 +47,22 @@ begin
// or, in RPN: A1, B1, + // or, in RPN: A1, B1, +
SetLength(MyFormula, 3); SetLength(MyFormula, 3);
MyFormula[0].TokenID := INT_EXCEL_TOKEN_TREFV; {A1} MyFormula[0].TokenID := INT_EXCEL_TOKEN_TREFV; {A1}
MyFormula[0].Col := 0; MyFormula[0].Col := 1;
MyFormula[0].Row := 0; MyFormula[0].Row := 1;
MyFormula[1].TokenID := INT_EXCEL_TOKEN_TREFV; {B1} MyFormula[1].TokenID := INT_EXCEL_TOKEN_TREFV; {B1}
MyFormula[1].Col := 1; MyFormula[1].Col := 2;
MyFormula[1].Row := 0; MyFormula[1].Row := 1;
MyFormula[2].TokenID := INT_EXCEL_TOKEN_TADD; {+} MyFormula[2].TokenID := INT_EXCEL_TOKEN_TADD; {+}
MyWorksheet.WriteRPNFormula(0, 4, MyFormula); MyWorksheet.WriteRPNFormula(1, 5, MyFormula);
// Creates a new worksheet // Creates a new worksheet
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2'); MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2');
// Write some string cells // Write some string cells
MyWorksheet.WriteUTF8Text(0, 0, 'First'); MyWorksheet.WriteUTF8Text(1, 1, 'First');
MyWorksheet.WriteUTF8Text(0, 1, 'Second'); MyWorksheet.WriteUTF8Text(1, 2, 'Second');
MyWorksheet.WriteUTF8Text(0, 2, 'Third'); MyWorksheet.WriteUTF8Text(1, 3, 'Third');
MyWorksheet.WriteUTF8Text(0, 3, 'Fourth'); MyWorksheet.WriteUTF8Text(1, 4, 'Fourth');
// Save the spreadsheet to a file // Save the spreadsheet to a file
MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel5); MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel5);

View File

@ -11,7 +11,7 @@
<TargetFileExt Value=".exe"/> <TargetFileExt Value=".exe"/>
<Title Value="opendocwrite"/> <Title Value="opendocwrite"/>
<UseAppBundle Value="False"/> <UseAppBundle Value="False"/>
<ActiveEditorIndexAtStart Value="1"/> <ActiveEditorIndexAtStart Value="3"/>
</General> </General>
<VersionInfo> <VersionInfo>
<ProjectVersion Value=""/> <ProjectVersion Value=""/>
@ -38,8 +38,8 @@
<Filename Value="opendocwrite.lpr"/> <Filename Value="opendocwrite.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="opendocwrite"/> <UnitName Value="opendocwrite"/>
<CursorPos X="30" Y="37"/> <CursorPos X="33" Y="61"/>
<TopLine Value="33"/> <TopLine Value="47"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<UsageCount Value="309"/> <UsageCount Value="309"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -86,8 +86,8 @@
<Unit6> <Unit6>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<UnitName Value="xlsbiff2"/> <UnitName Value="xlsbiff2"/>
<CursorPos X="1" Y="360"/> <CursorPos X="1" Y="16"/>
<TopLine Value="339"/> <TopLine Value="1"/>
<EditorIndex Value="6"/> <EditorIndex Value="6"/>
<UsageCount Value="139"/> <UsageCount Value="139"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -116,10 +116,10 @@
<Unit10> <Unit10>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<UnitName Value="fpspreadsheet"/> <UnitName Value="fpspreadsheet"/>
<CursorPos X="1" Y="752"/> <CursorPos X="46" Y="308"/>
<TopLine Value="737"/> <TopLine Value="296"/>
<EditorIndex Value="3"/> <EditorIndex Value="3"/>
<UsageCount Value="94"/> <UsageCount Value="95"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit10> </Unit10>
<Unit11> <Unit11>
@ -131,10 +131,10 @@
<Unit12> <Unit12>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<UnitName Value="fpsopendocument"/> <UnitName Value="fpsopendocument"/>
<CursorPos X="87" Y="394"/> <CursorPos X="9" Y="266"/>
<TopLine Value="386"/> <TopLine Value="263"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<UsageCount Value="12"/> <UsageCount Value="13"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit12> </Unit12>
<Unit13> <Unit13>
@ -143,130 +143,130 @@
<CursorPos X="1" Y="268"/> <CursorPos X="1" Y="268"/>
<TopLine Value="253"/> <TopLine Value="253"/>
<EditorIndex Value="2"/> <EditorIndex Value="2"/>
<UsageCount Value="12"/> <UsageCount Value="13"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit13> </Unit13>
</Units> </Units>
<JumpHistory Count="30" HistoryIndex="29"> <JumpHistory Count="30" HistoryIndex="29">
<Position1> <Position1>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="386" Column="1" TopLine="372"/> <Caret Line="390" Column="26" TopLine="377"/>
</Position1> </Position1>
<Position2> <Position2>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="390" Column="26" TopLine="377"/> <Caret Line="420" Column="32" TopLine="407"/>
</Position2> </Position2>
<Position3> <Position3>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="420" Column="32" TopLine="407"/> <Caret Line="421" Column="14" TopLine="408"/>
</Position3> </Position3>
<Position4> <Position4>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="421" Column="14" TopLine="408"/> <Caret Line="460" Column="33" TopLine="440"/>
</Position4> </Position4>
<Position5> <Position5>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="460" Column="33" TopLine="440"/> <Caret Line="181" Column="91" TopLine="160"/>
</Position5> </Position5>
<Position6> <Position6>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="181" Column="91" TopLine="160"/> <Caret Line="769" Column="83" TopLine="754"/>
</Position6> </Position6>
<Position7> <Position7>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="769" Column="83" TopLine="754"/> <Caret Line="102" Column="15" TopLine="89"/>
</Position7> </Position7>
<Position8> <Position8>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="102" Column="15" TopLine="89"/> <Caret Line="103" Column="15" TopLine="90"/>
</Position8> </Position8>
<Position9> <Position9>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="103" Column="15" TopLine="90"/> <Caret Line="404" Column="5" TopLine="379"/>
</Position9> </Position9>
<Position10> <Position10>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="404" Column="5" TopLine="379"/> <Caret Line="187" Column="1" TopLine="172"/>
</Position10> </Position10>
<Position11> <Position11>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="187" Column="1" TopLine="172"/> <Caret Line="380" Column="17" TopLine="362"/>
</Position11> </Position11>
<Position12> <Position12>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="380" Column="17" TopLine="362"/> <Caret Line="412" Column="1" TopLine="404"/>
</Position12> </Position12>
<Position13> <Position13>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="412" Column="1" TopLine="404"/> <Caret Line="716" Column="1" TopLine="702"/>
</Position13> </Position13>
<Position14> <Position14>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="716" Column="1" TopLine="702"/> <Caret Line="167" Column="17" TopLine="154"/>
</Position14> </Position14>
<Position15> <Position15>
<Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="167" Column="17" TopLine="154"/>
</Position15>
<Position16>
<Filename Value="..\..\xlsbiff2.pas"/> <Filename Value="..\..\xlsbiff2.pas"/>
<Caret Line="69" Column="1" TopLine="57"/> <Caret Line="69" Column="1" TopLine="57"/>
</Position16> </Position15>
<Position17> <Position16>
<Filename Value="opendocwrite.lpr"/> <Filename Value="opendocwrite.lpr"/>
<Caret Line="71" Column="1" TopLine="46"/> <Caret Line="71" Column="1" TopLine="46"/>
</Position17> </Position16>
<Position18> <Position17>
<Filename Value="..\..\xlsxooxml.pas"/> <Filename Value="..\..\xlsxooxml.pas"/>
<Caret Line="48" Column="16" TopLine="35"/> <Caret Line="48" Column="16" TopLine="35"/>
</Position17>
<Position18>
<Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="105" Column="1" TopLine="80"/>
</Position18> </Position18>
<Position19> <Position19>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="105" Column="1" TopLine="80"/> <Caret Line="111" Column="1" TopLine="86"/>
</Position19> </Position19>
<Position20> <Position20>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="111" Column="1" TopLine="86"/> <Caret Line="386" Column="1" TopLine="377"/>
</Position20> </Position20>
<Position21> <Position21>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="386" Column="1" TopLine="377"/> <Caret Line="357" Column="1" TopLine="350"/>
</Position21> </Position21>
<Position22> <Position22>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="357" Column="1" TopLine="350"/> <Caret Line="304" Column="3" TopLine="294"/>
</Position22> </Position22>
<Position23> <Position23>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="304" Column="3" TopLine="294"/> <Caret Line="265" Column="28" TopLine="253"/>
</Position23> </Position23>
<Position24> <Position24>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="265" Column="28" TopLine="253"/> <Caret Line="313" Column="1" TopLine="301"/>
</Position24> </Position24>
<Position25> <Position25>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="313" Column="1" TopLine="301"/> <Caret Line="41" Column="45" TopLine="37"/>
</Position25> </Position25>
<Position26> <Position26>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="41" Column="45" TopLine="37"/> <Caret Line="355" Column="5" TopLine="331"/>
</Position26> </Position26>
<Position27> <Position27>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="355" Column="5" TopLine="331"/> <Caret Line="311" Column="1" TopLine="299"/>
</Position27> </Position27>
<Position28> <Position28>
<Filename Value="..\..\fpsopendocument.pas"/> <Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="311" Column="1" TopLine="299"/> <Caret Line="260" Column="28" TopLine="249"/>
</Position28> </Position28>
<Position29> <Position29>
<Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="260" Column="28" TopLine="249"/>
</Position29>
<Position30>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="365" Column="5" TopLine="340"/> <Caret Line="365" Column="5" TopLine="340"/>
</Position29>
<Position30>
<Filename Value="..\..\fpsopendocument.pas"/>
<Caret Line="290" Column="5" TopLine="265"/>
</Position30> </Position30>
</JumpHistory> </JumpHistory>
</ProjectOptions> </ProjectOptions>

View File

@ -28,10 +28,10 @@ begin
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet'); MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet');
// Write some number cells // Write some number cells
MyWorksheet.WriteNumber(0, 0, 1.0); MyWorksheet.WriteNumber(1, 1, 1.0);
MyWorksheet.WriteNumber(0, 1, 2.0); MyWorksheet.WriteNumber(1, 2, 2.0);
MyWorksheet.WriteNumber(0, 2, 3.0); MyWorksheet.WriteNumber(1, 3, 3.0);
MyWorksheet.WriteNumber(0, 3, 4.0); MyWorksheet.WriteNumber(1, 4, 4.0);
{ Uncommend this to test large XLS files { Uncommend this to test large XLS files
for i := 2 to 20 do for i := 2 to 20 do
@ -59,10 +59,10 @@ begin
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2'); MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2');
// Write some string cells // Write some string cells
MyWorksheet.WriteUTF8Text(0, 0, 'First'); MyWorksheet.WriteUTF8Text(1, 1, 'First');
MyWorksheet.WriteUTF8Text(0, 1, 'Second'); MyWorksheet.WriteUTF8Text(1, 2, 'Second');
MyWorksheet.WriteUTF8Text(0, 2, 'Third'); MyWorksheet.WriteUTF8Text(1, 3, 'Third');
MyWorksheet.WriteUTF8Text(0, 3, 'Fourth'); MyWorksheet.WriteUTF8Text(1, 4, 'Fourth');
*) *)
// Save the spreadsheet to a file // Save the spreadsheet to a file

View File

@ -5,13 +5,12 @@ Writes an OpenDocument 1.0 Spreadsheet document
An OpenDocument document is a compressed ZIP file with the following files inside: An OpenDocument document is a compressed ZIP file with the following files inside:
filename\ content.xml - Actual contents
content.xml - Actual contents meta.xml - Authoring data
meta.xml - Authoring data settings.xml - User persistent viewing information, such as zoom, cursor position, etc.
settings.xml - User persistent viewing information, such as zoom, cursor position, etc. styles.xml - Styles, which are the only way to do formatting
styles.xml - Styles, which are the only way to do formatting mimetype - application/vnd.oasis.opendocument.spreadsheet
mimetype - application/vnd.oasis.opendocument.spreadsheet META-INF
META-INF
manifest.xml - manifest.xml -
Specifications obtained from: Specifications obtained from:
@ -19,8 +18,6 @@ Specifications obtained from:
http://docs.oasis-open.org/office/v1.1/OS/OpenDocument-v1.1.pdf http://docs.oasis-open.org/office/v1.1/OS/OpenDocument-v1.1.pdf
AUTHORS: Felipe Monteiro de Carvalho AUTHORS: Felipe Monteiro de Carvalho
IMPORTANT: This writer doesn't work yet!!! This is just initial code.
} }
unit fpsopendocument; unit fpsopendocument;
@ -51,6 +48,7 @@ type
// Routines to write those files // Routines to write those files
procedure WriteGlobalFiles; procedure WriteGlobalFiles;
procedure WriteContent(AData: TsWorkbook); procedure WriteContent(AData: TsWorkbook);
procedure WriteWorksheet(CurSheet: TsWorksheet);
public public
{ General writing methods } { General writing methods }
procedure WriteStringToFile(AFileName, AString: string); procedure WriteStringToFile(AFileName, AString: string);
@ -200,9 +198,7 @@ end;
procedure TsSpreadOpenDocWriter.WriteContent(AData: TsWorkbook); procedure TsSpreadOpenDocWriter.WriteContent(AData: TsWorkbook);
var var
i, j, k: Integer; i: Integer;
CurSheet: TsWorksheet;
CurCell: PCell;
begin begin
FContent := FContent :=
XML_HEADER + LineEnding + XML_HEADER + LineEnding +
@ -234,35 +230,17 @@ begin
' </office:font-face-decls>' + LineEnding + ' </office:font-face-decls>' + LineEnding +
// Automatic styles // Automatic styles
'<office:automatic-styles>' + LineEnding + ' <office:automatic-styles>' + LineEnding +
'<style:style style:name="co1" style:family="table-column">' + LineEnding + ' <style:style style:name="co1" style:family="table-column">' + LineEnding +
'<style:table-column-properties fo:break-before="auto" style:column-width="2.267cm"/>' + LineEnding + ' <style:table-column-properties fo:break-before="auto" style:column-width="2.267cm"/>' + LineEnding +
'</style:style>' + LineEnding +
'<style:style style:name="ro1" style:family="table-row">' + LineEnding +
'<style:table-row-properties style:row-height="0.416cm" fo:break-before="auto" style:use-optimal-row-height="true"/>' + LineEnding +
'</style:style>' + LineEnding +
'<style:style style:name="ta1" style:family="table" style:master-page-name="Default">' + LineEnding +
'<style:table-properties table:display="true" style:writing-mode="lr-tb"/>' + LineEnding +
'</style:style>' + LineEnding +
'</office:automatic-styles>' + 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>' + LineEnding +
' <style:style style:name="ID0EM" style:family="table-row" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding + ' <style:style style:name="ro1" style:family="table-row">' + LineEnding +
' <style:table-row-properties fo:break-before="auto" style:row-height="0.45cm" />' + LineEnding + ' <style:table-row-properties style:row-height="0.416cm" fo:break-before="auto" style:use-optimal-row-height="true"/>' + LineEnding +
' </style:style>' + 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:style style:name="ta1" style:family="table" style:master-page-name="Default">' + LineEnding +
' <style:text-properties fo:font-size="10" style:font-name="Arial" />' + LineEnding + ' <style:table-properties table:display="true" style:writing-mode="lr-tb"/>' + LineEnding +
' </style:style>' + 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 + ' </office:automatic-styles>' + 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 +}
// Body // Body
' <office:body>' + LineEnding + ' <office:body>' + LineEnding +
@ -270,17 +248,31 @@ begin
for i := 0 to AData.GetWorksheetCount - 1 do for i := 0 to AData.GetWorksheetCount - 1 do
begin begin
CurSheet := Adata.GetWorksheetByIndex(i); WriteWorksheet(Adata.GetWorksheetByIndex(i));
end;
FContent := FContent +
' </office:spreadsheet>' + LineEnding +
' </office:body>' + LineEnding +
'</office:document-content>';
end;
procedure TsSpreadOpenDocWriter.WriteWorksheet(CurSheet: TsWorksheet);
var
j, k: Integer;
CurCell: PCell;
begin
// Header // Header
FContent := FContent + '<table:table table:name="' + CurSheet.Name + '" table:style-name="ta1">' + LineEnding FContent := FContent +
+ '<table:table-column table:style-name="co1" table:number-columns-repeated="' + ' <table:table table:name="' + CurSheet.Name + '" table:style-name="ta1">' + LineEnding +
' <table:table-column table:style-name="co1" table:number-columns-repeated="' +
IntToStr(CurSheet.GetLastColNumber + 1) + '" table:default-cell-style-name="Default"/>' + LineEnding; IntToStr(CurSheet.GetLastColNumber + 1) + '" table:default-cell-style-name="Default"/>' + LineEnding;
// The cells need to be written in order, row by row // The cells need to be written in order, row by row
for j := 0 to CurSheet.GetLastRowNumber do for j := 0 to CurSheet.GetLastRowNumber do
begin begin
FContent := FContent + '<table:table-row table:style-name="ro1">' + LineEnding; FContent := FContent +
' <table:table-row table:style-name="ro1">' + LineEnding;
for k := 0 to CurSheet.FCells.Count - 1 do for k := 0 to CurSheet.FCells.Count - 1 do
begin begin
@ -288,17 +280,11 @@ begin
if CurCell^.Row = j then WriteCellCallback(CurCell, nil); if CurCell^.Row = j then WriteCellCallback(CurCell, nil);
end; end;
FContent := FContent + '</table:table-row>' + LineEnding; FContent := FContent + ' </table:table-row>' + LineEnding;
end; end;
// Footer // Footer
FContent := FContent + '</table:table>' + LineEnding; FContent := FContent + ' </table:table>' + LineEnding;
end;
FContent := FContent +
' </office:spreadsheet>' + LineEnding +
' </office:body>' + LineEnding +
'</office:document-content>';
end; end;
{******************************************************************* {*******************************************************************

View File

@ -61,12 +61,13 @@ type
{@@ Describes the type of content of a cell on a TsWorksheet } {@@ Describes the type of content of a cell on a TsWorksheet }
TCellContentType = (cctFormula, cctNumber, cctUTF8String); TCellContentType = (cctEmpty, cctFormula, cctNumber, cctUTF8String);
{@@ Cell structure for TsWorksheet } {@@ Cell structure for TsWorksheet }
TCell = record TCell = record
Row, Col: Cardinal; Col: Byte;
Row: Word;
ContentType: TCellContentType; ContentType: TCellContentType;
FormulaValue: TRPNFormula; FormulaValue: TRPNFormula;
NumberValue: double; NumberValue: double;
@ -303,6 +304,9 @@ end;
} }
function TsWorksheet.GetCell(ARow, ACol: Cardinal): PCell; function TsWorksheet.GetCell(ARow, ACol: Cardinal): PCell;
begin begin
// First make sure the row and col values are valid
if (ARow = 0) or (ACol = 0) then raise Exception.Create('FPSpreadsheet: Row and Col numbers cannot be zero');
Result := FindCell(ARow, ACol); Result := FindCell(ARow, ACol);
if (Result = nil) then if (Result = nil) then

View File

@ -13,6 +13,9 @@ To ensure a properly formed file, the following order must be respected:
2nd to Nth record: Any record 2nd to Nth record: Any record
Last record: EOF Last record: EOF
The row and column numbering in BIFF files is zero-based,
while in FPSpreadsheet it is 1-based, so this needs to be considered.
Excel file format specification obtained from: Excel file format specification obtained from:
http://sc.openoffice.org/excelfileformat.pdf http://sc.openoffice.org/excelfileformat.pdf
@ -82,6 +85,10 @@ const
INT_EXCEL_CHART = $0020; INT_EXCEL_CHART = $0020;
INT_EXCEL_MACRO_SHEET = $0040; INT_EXCEL_MACRO_SHEET = $0040;
{ Marks differences between the BIFF format and FPSpreadsheet }
INT_FPS_BIFF_ROW_DELTA = 1;
INT_FPS_BIFF_COL_DELTA = 1;
{ TsSpreadBIFF2Writer } { TsSpreadBIFF2Writer }
{******************************************************************* {*******************************************************************
@ -165,8 +172,8 @@ begin
AStream.WriteWord(WordToLE(17 + RPNLength)); AStream.WriteWord(WordToLE(17 + RPNLength));
{ BIFF Record data } { BIFF Record data }
AStream.WriteWord(WordToLE(ARow)); AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
AStream.WriteWord(WordToLE(ACol)); AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ BIFF2 Attributes } { BIFF2 Attributes }
AStream.WriteByte($0); AStream.WriteByte($0);
@ -211,8 +218,8 @@ begin
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA: INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA:
begin begin
AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW); AStream.WriteWord( (AFormula[i].Row - INT_FPS_BIFF_ROW_DELTA) and MASK_EXCEL_ROW);
AStream.WriteByte(AFormula[i].Col); AStream.WriteByte(AFormula[i].Col - INT_FPS_BIFF_COL_DELTA);
Inc(RPNLength, 3); Inc(RPNLength, 3);
end; end;
@ -250,8 +257,8 @@ begin
AStream.WriteWord(WordToLE(8 + L)); AStream.WriteWord(WordToLE(8 + L));
{ BIFF Record data } { BIFF Record data }
AStream.WriteWord(WordToLE(ARow)); AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
AStream.WriteWord(WordToLE(ACol)); AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ BIFF2 Attributes } { BIFF2 Attributes }
AStream.WriteByte($0); AStream.WriteByte($0);
@ -279,8 +286,8 @@ begin
AStream.WriteWord(WordToLE(15)); AStream.WriteWord(WordToLE(15));
{ BIFF Record data } { BIFF Record data }
AStream.WriteWord(WordToLE(ARow)); AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
AStream.WriteWord(WordToLE(ACol)); AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ BIFF2 Attributes } { BIFF2 Attributes }
AStream.WriteByte($0); AStream.WriteByte($0);
@ -344,8 +351,8 @@ var
AStrValue: ansistring; AStrValue: ansistring;
begin begin
{ BIFF Record data } { BIFF Record data }
ARow := WordLEToN(AStream.ReadWord); ARow := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_ROW_DELTA;
ACol := WordLEToN(AStream.ReadWord); ACol := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_COL_DELTA;
{ BIFF2 Attributes } { BIFF2 Attributes }
AStream.ReadByte(); AStream.ReadByte();
@ -368,8 +375,8 @@ var
AValue: Double; AValue: Double;
begin begin
{ BIFF Record data } { BIFF Record data }
ARow := WordLEToN(AStream.ReadWord); ARow := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_ROW_DELTA;
ACol := WordLEToN(AStream.ReadWord); ACol := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_COL_DELTA;
{ BIFF2 Attributes } { BIFF2 Attributes }
AStream.ReadByte(); AStream.ReadByte();

View File

@ -31,6 +31,9 @@ DIMENSIONS
WINDOW2 WINDOW2
EOF EOF
The row and column numbering in BIFF files is zero-based,
while in FPSpreadsheet it is 1-based, so this needs to be considered.
Excel file format specification obtained from: Excel file format specification obtained from:
http://sc.openoffice.org/excelfileformat.pdf http://sc.openoffice.org/excelfileformat.pdf
@ -203,6 +206,10 @@ const
MASK_XF_VERT_ALIGN = $70; MASK_XF_VERT_ALIGN = $70;
{ Marks differences between the BIFF format and FPSpreadsheet }
INT_FPS_BIFF_ROW_DELTA = 1;
INT_FPS_BIFF_COL_DELTA = 1;
{ {
Exported functions Exported functions
} }
@ -550,8 +557,8 @@ begin
AStream.WriteWord(WordToLE(22 + RPNLength)); AStream.WriteWord(WordToLE(22 + RPNLength));
{ BIFF Record data } { BIFF Record data }
AStream.WriteWord(WordToLE(ARow)); AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
AStream.WriteWord(WordToLE(ACol)); AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ Index to XF Record } { Index to XF Record }
AStream.WriteWord($0000); AStream.WriteWord($0000);
@ -596,8 +603,8 @@ begin
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA: INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA:
begin begin
AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW); AStream.WriteWord( (AFormula[i].Row - INT_FPS_BIFF_ROW_DELTA) and MASK_EXCEL_ROW);
AStream.WriteByte(AFormula[i].Col); AStream.WriteByte(AFormula[i].Col - INT_FPS_BIFF_COL_DELTA);
Inc(RPNLength, 3); Inc(RPNLength, 3);
end; end;
@ -667,8 +674,8 @@ begin
AStream.WriteWord(WordToLE(8 + L)); AStream.WriteWord(WordToLE(8 + L));
{ BIFF Record data } { BIFF Record data }
AStream.WriteWord(WordToLE(ARow)); AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
AStream.WriteWord(WordToLE(ACol)); AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ Index to XF record } { Index to XF record }
AStream.WriteWord(15); AStream.WriteWord(15);
@ -694,8 +701,8 @@ begin
AStream.WriteWord(WordToLE(14)); AStream.WriteWord(WordToLE(14));
{ BIFF Record data } { BIFF Record data }
AStream.WriteWord(WordToLE(ARow)); AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
AStream.WriteWord(WordToLE(ACol)); AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ Index to XF record } { Index to XF record }
AStream.WriteWord($0); AStream.WriteWord($0);
@ -1053,8 +1060,8 @@ var
AValue: Double; AValue: Double;
begin begin
{ BIFF Record data } { BIFF Record data }
ARow := WordLEToN(AStream.ReadWord); ARow := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_ROW_DELTA;
ACol := WordLEToN(AStream.ReadWord); ACol := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_COL_DELTA;
{ Index to XF record } { Index to XF record }
AStream.ReadWord(); AStream.ReadWord();