From cacfb22337dc642e247fc758f3eda8874805cc0d Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Wed, 19 Oct 2016 09:31:06 +0000 Subject: [PATCH] fpspreadsheet: Ignore filler columns added by Calc when reading an Excel file. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5269 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/fpspreadsheet/fpsreaderwriter.pas | 44 +++++++++++++++---- .../fpspreadsheet/tests/formattests.pas | 2 +- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/components/fpspreadsheet/fpsreaderwriter.pas b/components/fpspreadsheet/fpsreaderwriter.pas index b9d89f6b0..cfe80aa80 100644 --- a/components/fpspreadsheet/fpsreaderwriter.pas +++ b/components/fpspreadsheet/fpsreaderwriter.pas @@ -323,29 +323,55 @@ procedure TsCustomSpreadReader.FixCols(AWorkSheet: TsWorksheet); const EPS = 1E-3; var - c: Cardinal; + c: LongInt; w: Single; lCol: PCol; + sameWidth: Boolean; begin + // If the count of columns is equal to the max colcount of the file format + // then it is likely that dummy columns have been added -> delete all empty + // columns (starting at the right) until the first non-empty column is found + if AWorksheet.Cols.Count = FLimitations.MaxColCount then + begin + c := AWorksheet.Cols.Count - 1; + lCol := PCol(AWorksheet.Cols[c]); + w := lCol.Width; + while c >= 0 do begin + lCol := PCol(AWorksheet.Cols[c]); + if not SameValue(lCol^.Width, w, EPS) then + break; + if AWorksheet.FindNextCellInCol(0, c) <> nil then + break; + AWorksheet.RemoveCol(c); + dec(c); + end; + end; + if AWorksheet.Cols.Count < 2 then exit; // Check whether all columns have the same column width + sameWidth := true; w := PCol(AWorksheet.Cols[0])^.Width; for c := 1 to AWorksheet.Cols.Count-1 do begin lCol := PCol(AWorksheet.Cols[c]); if not SameValue(lCol^.Width, w, EPS) then - exit; + begin + sameWidth := false; + break; + end; end; - // At this point we know that all columns have the same width. We pass this - // to the DefaultColWidth ... - AWorksheet.WriteDefaultColWidth(w, FWorkbook.Units); + if sameWidth then begin + // At this point we know that all columns have the same width. We pass this + // to the DefaultColWidth ... + AWorksheet.WriteDefaultColWidth(w, FWorkbook.Units); - // ...and delete all column records with non-default format - for c := AWorksheet.Cols.Count-1 downto 0 do begin - lCol := PCol(AWorksheet.Cols[c]); - if lCol^.FormatIndex = 0 then AWorksheet.RemoveCol(c); + // ...and delete all column records with non-default format + for c := AWorksheet.Cols.Count-1 downto 0 do begin + lCol := PCol(AWorksheet.Cols[c]); + if lCol^.FormatIndex = 0 then AWorksheet.RemoveCol(c); + end; end; end; diff --git a/components/fpspreadsheet/tests/formattests.pas b/components/fpspreadsheet/tests/formattests.pas index ed345dc99..7ce1fdde9 100644 --- a/components/fpspreadsheet/tests/formattests.pas +++ b/components/fpspreadsheet/tests/formattests.pas @@ -1129,7 +1129,7 @@ begin fail('Error in test code. Failed to get named worksheet'); for Col := Low(SollColWidths) to High(SollColWidths) do begin - lpCol := MyWorksheet.GetCol(Col); + lpCol := MyWorksheet.FindCol(Col); if lpCol = nil then fail('Error in test code. Failed to return saved column width'); ActualColWidth := MyWorkbook.ConvertUnits(lpCol^.Width, MyWorkbook.Units, suChars);