fpspreadsheet: Fix issue http://mantis.freepascal.org/view.php?id=26221 (empty cells misplace following cells in .ods)

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3100 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-05-26 15:00:43 +00:00
parent 070845d3ae
commit f1a1a4474a
2 changed files with 89 additions and 91 deletions

View File

@ -107,7 +107,7 @@
<PackageName Value="LCL"/> <PackageName Value="LCL"/>
</Item2> </Item2>
</RequiredPackages> </RequiredPackages>
<Units Count="61"> <Units Count="62">
<Unit0> <Unit0>
<Filename Value="fpsgrid.lpr"/> <Filename Value="fpsgrid.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -137,7 +137,6 @@
<Unit2> <Unit2>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<UnitName Value="fpspreadsheet"/> <UnitName Value="fpspreadsheet"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="5"/> <EditorIndex Value="5"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="523"/> <TopLine Value="523"/>
@ -151,7 +150,7 @@
<Unit3> <Unit3>
<Filename Value="..\..\fpspreadsheetgrid.pas"/> <Filename Value="..\..\fpspreadsheetgrid.pas"/>
<UnitName Value="fpspreadsheetgrid"/> <UnitName Value="fpspreadsheetgrid"/>
<EditorIndex Value="6"/> <EditorIndex Value="7"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="539"/> <TopLine Value="539"/>
<CursorPos X="42" Y="557"/> <CursorPos X="42" Y="557"/>
@ -596,127 +595,138 @@
<CursorPos X="1" Y="120"/> <CursorPos X="1" Y="120"/>
<UsageCount Value="11"/> <UsageCount Value="11"/>
</Unit60> </Unit60>
<Unit61>
<Filename Value="C:\development\fpc\rtl\win32\sysinitpas.pp"/>
<UnitName Value="sysinitpas"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="6"/>
<WindowIndex Value="0"/>
<TopLine Value="28"/>
<CursorPos X="1" Y="44"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit61>
</Units> </Units>
<JumpHistory Count="30" HistoryIndex="29"> <JumpHistory Count="30" HistoryIndex="29">
<Position1> <Position1>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="742" Column="12" TopLine="723"/> <Caret Line="115" Column="1" TopLine="115"/>
</Position1> </Position1>
<Position2> <Position2>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="115" Column="1" TopLine="115"/> <Caret Line="349" Column="12" TopLine="318"/>
</Position2> </Position2>
<Position3> <Position3>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="349" Column="12" TopLine="318"/> <Caret Line="358" Column="25" TopLine="327"/>
</Position3> </Position3>
<Position4> <Position4>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="358" Column="25" TopLine="327"/> <Caret Line="478" Column="34" TopLine="449"/>
</Position4> </Position4>
<Position5> <Position5>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheetgrid.pas"/>
<Caret Line="478" Column="34" TopLine="449"/> <Caret Line="2524" Column="3" TopLine="2520"/>
</Position5> </Position5>
<Position6> <Position6>
<Filename Value="..\..\fpspreadsheetgrid.pas"/> <Filename Value="..\..\fpspreadsheetgrid.pas"/>
<Caret Line="2524" Column="3" TopLine="2520"/> <Caret Line="2504" Column="46" TopLine="2498"/>
</Position6> </Position6>
<Position7> <Position7>
<Filename Value="..\..\fpspreadsheetgrid.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="2504" Column="46" TopLine="2498"/> <Caret Line="654" Column="3" TopLine="647"/>
</Position7> </Position7>
<Position8> <Position8>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="654" Column="3" TopLine="647"/> <Caret Line="661" Column="3" TopLine="654"/>
</Position8> </Position8>
<Position9> <Position9>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="661" Column="3" TopLine="654"/> <Caret Line="542" Column="56" TopLine="540"/>
</Position9> </Position9>
<Position10> <Position10>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="542" Column="56" TopLine="540"/> <Caret Line="728" Column="1" TopLine="704"/>
</Position10> </Position10>
<Position11> <Position11>
<Filename Value="mainform.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="728" Column="1" TopLine="704"/> <Caret Line="1316" Column="1" TopLine="1285"/>
</Position11> </Position11>
<Position12> <Position12>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="1316" Column="1" TopLine="1285"/> <Caret Line="394" Column="34" TopLine="394"/>
</Position12> </Position12>
<Position13> <Position13>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="394" Column="34" TopLine="394"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position13> </Position13>
<Position14> <Position14>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="1" Column="1" TopLine="1"/> <Caret Line="501" Column="18" TopLine="470"/>
</Position14> </Position14>
<Position15> <Position15>
<Filename Value="..\..\fpspreadsheet.pas"/> <Filename Value="..\..\xlscommon.pas"/>
<Caret Line="501" Column="18" TopLine="470"/> <Caret Line="1430" Column="28" TopLine="1430"/>
</Position15> </Position15>
<Position16> <Position16>
<Filename Value="..\..\xlscommon.pas"/> <Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1430" Column="28" TopLine="1430"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position16> </Position16>
<Position17> <Position17>
<Filename Value="..\..\xlscommon.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="1" Column="1" TopLine="1"/> <Caret Line="704" Column="21" TopLine="704"/>
</Position17> </Position17>
<Position18> <Position18>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="704" Column="21" TopLine="704"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position18> </Position18>
<Position19> <Position19>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="1" Column="1" TopLine="1"/> <Caret Line="83" Column="19" TopLine="53"/>
</Position19> </Position19>
<Position20> <Position20>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="83" Column="19" TopLine="53"/> <Caret Line="229" Column="29" TopLine="199"/>
</Position20> </Position20>
<Position21> <Position21>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="229" Column="29" TopLine="199"/> <Caret Line="540" Column="32" TopLine="509"/>
</Position21> </Position21>
<Position22> <Position22>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="540" Column="32" TopLine="509"/> <Caret Line="511" Column="29" TopLine="511"/>
</Position22> </Position22>
<Position23> <Position23>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="511" Column="29" TopLine="511"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position23> </Position23>
<Position24> <Position24>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="1" Column="1" TopLine="1"/> <Caret Line="83" Column="19" TopLine="53"/>
</Position24> </Position24>
<Position25> <Position25>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="83" Column="19" TopLine="53"/> <Caret Line="229" Column="29" TopLine="199"/>
</Position25> </Position25>
<Position26> <Position26>
<Filename Value="mainform.pas"/> <Filename Value="mainform.pas"/>
<Caret Line="229" Column="29" TopLine="199"/> <Caret Line="540" Column="32" TopLine="509"/>
</Position26> </Position26>
<Position27> <Position27>
<Filename Value="mainform.pas"/> <Filename Value="..\..\xlscommon.pas"/>
<Caret Line="540" Column="32" TopLine="509"/> <Caret Line="1141" Column="28" TopLine="1111"/>
</Position27> </Position27>
<Position28> <Position28>
<Filename Value="..\..\xlscommon.pas"/> <Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1141" Column="28" TopLine="1111"/> <Caret Line="1142" Column="1" TopLine="1106"/>
</Position28> </Position28>
<Position29> <Position29>
<Filename Value="..\..\xlscommon.pas"/> <Filename Value="..\..\xlscommon.pas"/>
<Caret Line="1142" Column="1" TopLine="1106"/> <Caret Line="1427" Column="3" TopLine="1408"/>
</Position29> </Position29>
<Position30> <Position30>
<Filename Value="..\..\xlscommon.pas"/> <Filename Value="..\..\fpspreadsheet.pas"/>
<Caret Line="1427" Column="3" TopLine="1408"/> <Caret Line="533" Column="22" TopLine="523"/>
</Position30> </Position30>
</JumpHistory> </JumpHistory>
</ProjectOptions> </ProjectOptions>

View File

@ -58,7 +58,6 @@ type
TsSpreadOpenDocReader = class(TsCustomSpreadReader) TsSpreadOpenDocReader = class(TsCustomSpreadReader)
private private
FDoc : TXMLDocument;
FDateMode: TDateMode; FDateMode: TDateMode;
FWorksheet: TsWorksheet; FWorksheet: TsWorksheet;
// Gets value for the specified attribute. Returns empty string if attribute // Gets value for the specified attribute. Returns empty string if attribute
@ -235,6 +234,7 @@ end;
procedure TsSpreadOpenDocReader.ReadFromFile(AFileName: string; AData: TsWorkbook); procedure TsSpreadOpenDocReader.ReadFromFile(AFileName: string; AData: TsWorkbook);
var var
Doc : TXMLDocument;
Col, Row : integer; Col, Row : integer;
FilePath : string; FilePath : string;
UnZip : TUnZipper; UnZip : TUnZipper;
@ -258,90 +258,77 @@ begin
FreeAndNil(UnZip); FreeAndNil(UnZip);
end; //try end; //try
FDoc := nil; Doc := nil;
try try
// process the styles.xml file // process the styles.xml file
ReadXMLFile(FDoc, FilePath+'styles.xml'); ReadXMLFile(Doc, FilePath+'styles.xml');
DeleteFile(FilePath+'styles.xml'); DeleteFile(FilePath+'styles.xml');
StylesNode := FDoc.DocumentElement.FindNode('office:styles'); StylesNode := Doc.DocumentElement.FindNode('office:styles');
ReadNumFormats(StylesNode); ReadNumFormats(StylesNode);
// FDoc.Free;
//process the content.xml file //process the content.xml file
ReadXMLFile(FDoc, FilePath+'content.xml'); ReadXMLFile(Doc, FilePath+'content.xml');
DeleteFile(FilePath+'content.xml'); DeleteFile(FilePath+'content.xml');
StylesNode := FDoc.DocumentElement.FindNode('office:automatic-styles'); StylesNode := Doc.DocumentElement.FindNode('office:automatic-styles');
ReadNumFormats(StylesNode); ReadNumFormats(StylesNode);
BodyNode := FDoc.DocumentElement.FindNode('office:body'); BodyNode := Doc.DocumentElement.FindNode('office:body');
if not Assigned(BodyNode) then Exit; if not Assigned(BodyNode) then Exit;
SpreadSheetNode:=BodyNode.FindNode('office:spreadsheet'); SpreadSheetNode := BodyNode.FindNode('office:spreadsheet');
if not Assigned(SpreadSheetNode) then Exit; if not Assigned(SpreadSheetNode) then Exit;
ReadDateMode(SpreadSheetNode); ReadDateMode(SpreadSheetNode);
//process each table (sheet) //process each table (sheet)
TableNode:=SpreadSheetNode.FindNode('table:table'); TableNode := SpreadSheetNode.FindNode('table:table');
while Assigned(TableNode) do begin while Assigned(TableNode) do begin
FWorkSheet:=aData.AddWorksheet(GetAttrValue(TableNode,'table:name')); FWorkSheet := aData.AddWorksheet(GetAttrValue(TableNode,'table:name'));
Row:=0; Row := 0;
//process each row inside the sheet //process each row inside the sheet
RowNode:=TableNode.FindNode('table:table-row'); RowNode := TableNode.FindNode('table:table-row');
while Assigned(RowNode) do begin while Assigned(RowNode) do begin
Col:=0; Col:=0;
ParamRowsRepeated:=GetAttrValue(RowNode,'table:number-rows-repeated');
if ParamRowsRepeated='' then ParamRowsRepeated:='1';
//process each cell of the row //process each cell of the row
CellNode:=RowNode.FindNode('table:table-cell'); CellNode:=RowNode.FindNode('table:table-cell');
while Assigned(CellNode) do while Assigned(CellNode) do begin
begin
ParamColsRepeated:=GetAttrValue(CellNode,'table:number-columns-repeated');
if ParamColsRepeated='' then ParamColsRepeated:='1';
// select this cell value's type // select this cell value's type
ParamValueType:=GetAttrValue(CellNode,'office:value-type'); ParamValueType := GetAttrValue(CellNode,'office:value-type');
ParamFormula:=GetAttrValue(CellNode,'table:formula'); ParamFormula := GetAttrValue(CellNode,'table:formula');
// Speed optimization: only read cells that may have contents;
// leave rest empty. Update if we support more cell types if ParamValueType = 'string' then
if (ParamValueType='string') or ReadLabel(Row, Col, CellNode)
(ParamValueType='float') or else if (ParamValueType = 'float') or (ParamValueType = 'percentage') then
(ParamValueType='date') or ReadNumber(Row, Col, CellNode)
(ParamValueType='time') or else if (ParamValueType = 'date') or (ParamValueType = 'time') then
(ParamFormula<>'') then ReadDate(Row, Col, CellNode)
begin else if ParamFormula <> '' then
for RowsCount:=0 to StrToInt(ParamRowsRepeated)-1 do begin ReadLabel(Row, Col, CellNode);
for ColsCount:=0 to StrToInt(ParamColsRepeated)-1 do begin
if ParamValueType='string' then ParamColsRepeated := GetAttrValue(CellNode,'table:number-columns-repeated');
ReadLabel(Row+RowsCount,Col+ColsCount,CellNode) if ParamColsRepeated='' then ParamColsRepeated := '1';
else if ParamFormula<>'' then Col := Col + StrToInt(ParamColsRepeated);
ReadFormula(Row+RowsCount,Col+ColsCount,CellNode)
else if ParamValueType='float' then CellNode := CellNode.NextSibling;
ReadNumber(Row+RowsCount,Col+ColsCount,CellNode)
else if (ParamValueType='date') or (ParamValueType='time') then
ReadDate(Row+RowsCount,Col+ColsCount,CellNode);
end; //for ColsCount
end; //for RowsCount
end;
Inc(Col,ColsCount+1);
CellNode:=CellNode.NextSibling;
end; //while Assigned(CellNode) end; //while Assigned(CellNode)
Inc(Row,RowsCount+1); ParamRowsRepeated := GetAttrValue(RowNode,'table:number-rows-repeated');
RowNode:=RowNode.NextSibling; if ParamRowsRepeated='' then ParamRowsRepeated := '1';
Row := Row + StrToInt(ParamRowsRepeated);
RowNode := RowNode.NextSibling;
end; // while Assigned(RowNode) end; // while Assigned(RowNode)
TableNode:=TableNode.NextSibling; TableNode := TableNode.NextSibling;
end; //while Assigned(TableNode) end; //while Assigned(TableNode)
finally finally
FDoc.Free; Doc.Free;
end; end;
end; end;
@ -398,6 +385,7 @@ begin
if Value<>'' then if Value<>'' then
begin begin
{$IFDEF FPSPREADDEBUG} {$IFDEF FPSPREADDEBUG}
end;
writeln('Row (1based): ',ARow+1,'office:date-value: '+Value); writeln('Row (1based): ',ARow+1,'office:date-value: '+Value);
{$ENDIF} {$ENDIF}
// Date or date/time string // Date or date/time string