fpspreadsheet: Workaround for ods rows and columns erroneously added by Libre/OpenOffice when importing an xlsx file (see forum http://forum.lazarus.freepascal.org/index.php/topic,32193.0.html)

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4610 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-04-08 18:54:58 +00:00
parent 0f266666b8
commit 34025326da
5 changed files with 39 additions and 41 deletions

View File

@ -14,7 +14,7 @@ object MainForm: TMainForm
Left = 0
Height = 518
Top = 83
Width = 711
Width = 694
TabIndex = 0
Tabs.Strings = (
'Sheet1'
@ -26,11 +26,10 @@ object MainForm: TMainForm
Left = 2
Height = 493
Top = 23
Width = 707
Width = 690
FrozenCols = 0
FrozenRows = 0
ReadFormulas = True
SelectionPen.Width = 2
TextOverflow = True
WorkbookSource = WorkbookSource
Align = alClient
@ -55,10 +54,10 @@ object MainForm: TMainForm
end
end
object InspectorTabControl: TTabControl
Left = 716
Left = 699
Height = 518
Top = 83
Width = 281
Width = 298
OnChange = InspectorTabControlChange
TabIndex = 0
Tabs.Strings = (
@ -74,7 +73,7 @@ object MainForm: TMainForm
Left = 2
Height = 493
Top = 23
Width = 277
Width = 294
Align = alClient
DefaultColWidth = 125
MouseWheelOption = mwGrid
@ -131,7 +130,7 @@ object MainForm: TMainForm
end
end
object InspectorSplitter: TSplitter
Left = 711
Left = 694
Height = 518
Top = 83
Width = 5

View File

@ -1034,17 +1034,25 @@ var
colStyle: TColumnStyleData;
i: Integer;
u: TsSizeUnits;
defColWidth: Single;
lastOccCol: Integer;
begin
u := FWorkbook.Units;
defColWidth := FWorksheet.ReadDefaultColWidth(u);
lastOccCol := FWorksheet.GetLastOccupiedColIndex;
for i:=0 to FColumnList.Count-1 do
begin
colIndex := TColumnData(FColumnList[i]).Col;
// Skip column records beyond the last data column - there's a bug in OO/LO
// which adds column records up to the max column limit.
if colIndex > lastOccCol then
Continue;
colStyleIndex := TColumnData(FColumnList[i]).ColStyleIndex;
colStyle := TColumnStyleData(FColumnStyleList[colStyleIndex]);
// Add only column records to the worksheet if their width is different from
// the default column width. The column width stored in colStyle is already
// in workbook units (see ReadColumnStyles).
if not SameValue(colStyle.ColWidth, FWorksheet.ReadDefaultColWidth(u), COLWIDTH_EPS) then
if not SameValue(colStyle.ColWidth, defColWidth, COLWIDTH_EPS) then
FWorksheet.WriteColWidth(colIndex, colStyle.ColWidth, u);
end;
end;
@ -3320,8 +3328,13 @@ var
paramColsRepeated := GetAttrValue(cellNode, 'table:number-columns-repeated');
if paramColsRepeated = '' then paramColsRepeated := '1';
n := StrToInt(paramColsRepeated);
if n > 1 then
if (n > 1) and (col + n < FLimitations.MaxColCount - 10) then
begin
// The 2nd condition belongs to a workaround for a bug of LO/OO whichs
// extends imported xlsx files with blank cols up to their
// specification limit.
// React some columns earlier because the added column range is
// sometimes split into two parts.
cell := FWorksheet.FindCell(row, col);
if cell <> nil then
for i:=1 to n-1 do
@ -3347,6 +3360,11 @@ var
rowsRepeated := StrToInt(paramRowsRepeated);
// Transfer non-default row heights to sheet's rows
// This first "if" is a workaround for a bug of LO/OO whichs extends imported
// xlsx files with blank rows up to their specification limit.
// React some rows earlier because the added row range is sometimes split
// into two parts.
if row + rowsRepeated < FLimitations.MaxRowCount - 10 then
if not autoRowHeight then
for i:=1 to rowsRepeated do
FWorksheet.WriteRowHeight(row + i - 1, rowHeight, FWorkbook.Units);
@ -3391,7 +3409,7 @@ end;
procedure TsSpreadOpenDocReader.ReadRowStyle(AStyleNode: TDOMNode);
var
styleName: String;
styleName, nodename: String;
styleChildNode: TDOMNode;
rowHeight: Double;
auto: Boolean;
@ -3405,7 +3423,8 @@ begin
while Assigned(styleChildNode) do
begin
if styleChildNode.NodeName = 'style:table-row-properties' then
nodename := styleChildNode.NodeName;
if nodeName = 'style:table-row-properties' then
begin
s := GetAttrValue(styleChildNode, 'style:row-height');
if s <> '' then

View File

@ -3303,9 +3303,9 @@ begin
begin
AStrings.Add(Format('Name=%s', [ASheet.Name]));
AStrings.Add(Format('First row=%d', [Integer(ASheet.GetFirstRowIndex)]));
AStrings.Add(Format('Last row=%d', [ASheet.GetLastRowIndex]));
AStrings.Add(Format('Last row=%d', [ASheet.GetLastRowIndex(true)]));
AStrings.Add(Format('First column=%d', [Integer(ASheet.GetFirstColIndex)]));
AStrings.Add(Format('Last column=%d', [ASheet.GetLastColIndex]));
AStrings.Add(Format('Last column=%d', [ASheet.GetLastColIndex(true)]));
AStrings.Add(Format('Active cell=%s',
[GetCellString(ASheet.ActiveCellRow, ASheet.ActiveCellCol)]));
AStrings.Add(Format('Selection=%s', [ASheet.GetSelectionAsString]));

View File

@ -4187,32 +4187,7 @@ begin
GetWorkbookSource.CreateNewWorkbook;
ColCount := AColCount + FHeaderCount;
RowCount := ARowCount + FHeaderCount;
// FInitColCount := AColCount;
// FInitRowCount := ARowCount;
Setup;
{
if FOwnsWorkbook then
FreeAndNil(FOwnedWorkbook);
if FWorkbookSource <> nil then
FWorkbookSource.CreateNewWorkbook
else
begin
BeginUpdate;
try
CreateNewWorkbook;
FOwnedWorksheet := FOwnedWorkbook.AddWorksheet('Sheet1');
FOwnedWorksheet.OnChangeCell := @ChangedCellHandler;
FOwnedWorksheet.OnChangeFont := @ChangedFontHandler;
FInitColCount := AColCount;
FInitRowCount := ARowCount;
Setup;
finally
EndUpdate;
end;
end;
}
end;
{@@ ----------------------------------------------------------------------------

View File

@ -1109,6 +1109,11 @@ begin
//MyWorksheet.WriteNumber(0, Col, 1);
MyWorksheet.WriteColInfo(Col, lCol);
end;
if AFormat = sfOpenDocument then
// In ODS empty columns are ignored due to a workaround for a
// LO/OO import error for xlsx files. --> add dummy cells
for Col := low(SollColWidths) to High(SollColWidths) do
MyWorksheet.WriteText(0, Col, 'test');
TempFile:=NewTempFile;
MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally