From 948839a79a6e2a3b99613d5560885d75b13bf548 Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Sun, 29 May 2011 17:21:51 +0000 Subject: [PATCH] Reworks the common xls files and attempt to fix bug 18886 excel5 files are truncated when imported git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1654 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../fpspreadsheet/laz_fpspreadsheet.lpk | 6 +- .../fpspreadsheet/laz_fpspreadsheet.pas | 2 +- components/fpspreadsheet/xlsbiff5.pas | 16 +-- components/fpspreadsheet/xlsbiff8.pas | 17 ++-- components/fpspreadsheet/xlsbiffcommon.pas | 80 --------------- components/fpspreadsheet/xlscommon.pas | 97 ++++++++++++++++++- 6 files changed, 119 insertions(+), 99 deletions(-) delete mode 100644 components/fpspreadsheet/xlsbiffcommon.pas diff --git a/components/fpspreadsheet/laz_fpspreadsheet.lpk b/components/fpspreadsheet/laz_fpspreadsheet.lpk index c301fcbdb..1596b4e88 100644 --- a/components/fpspreadsheet/laz_fpspreadsheet.lpk +++ b/components/fpspreadsheet/laz_fpspreadsheet.lpk @@ -18,7 +18,7 @@ - + @@ -95,10 +95,6 @@ - - - - diff --git a/components/fpspreadsheet/laz_fpspreadsheet.pas b/components/fpspreadsheet/laz_fpspreadsheet.pas index 1d0f5c817..37fe42b35 100644 --- a/components/fpspreadsheet/laz_fpspreadsheet.pas +++ b/components/fpspreadsheet/laz_fpspreadsheet.pas @@ -11,7 +11,7 @@ uses xlsbiff5, xlsbiff8, xlsxooxml, fpsutils, fpszipper, uvirtuallayer_types, uvirtuallayer, uvirtuallayer_ole, uvirtuallayer_ole_helpers, uvirtuallayer_ole_types, uvirtuallayer_stream, fpolebasic, xlscommon, - fpsconvencoding, xlsbiffcommon, LazarusPackageIntf; + fpsconvencoding, LazarusPackageIntf; implementation diff --git a/components/fpspreadsheet/xlsbiff5.pas b/components/fpspreadsheet/xlsbiff5.pas index c9e346658..738e944c3 100755 --- a/components/fpspreadsheet/xlsbiff5.pas +++ b/components/fpspreadsheet/xlsbiff5.pas @@ -101,7 +101,7 @@ type { TsSpreadBIFF5Writer } - TsSpreadBIFF5Writer = class(TsCustomSpreadWriter) + TsSpreadBIFF5Writer = class(TsSpreadBIFFWriter) private WorkBookEncoding: TsEncoding; function FEKindToExcelID(AElement: TFEKind; var AParamsNum: Byte; var AExtra: Word): Byte; @@ -116,7 +116,7 @@ type procedure WriteBOF(AStream: TStream; ADataType: Word); function WriteBoundsheet(AStream: TStream; ASheetName: string): Int64; procedure WriteCodepage(AStream: TStream; AEncoding: TsEncoding); - procedure WriteDimensions(AStream: TStream); + procedure WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet); procedure WriteEOF(AStream: TStream); procedure WriteFont(AStream: TStream; AFont: TFPCustomFont); procedure WriteRPNFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsRPNFormula); override; @@ -445,7 +445,7 @@ begin WriteIndex(AStream); - WriteDimensions(AStream); + WriteDimensions(AStream, AData.GetWorksheetByIndex(i)); WriteWindow2(AStream, True); @@ -560,7 +560,9 @@ end; * nm = (rl - rf - 1) / 32 + 1 (using integer division) * *******************************************************************} -procedure TsSpreadBIFF5Writer.WriteDimensions(AStream: TStream); +procedure TsSpreadBIFF5Writer.WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet); +var + lLastCol, lLastRow: Word; begin { BIFF Record header } AStream.WriteWord(WordToLE(INT_EXCEL_ID_DIMENSIONS)); @@ -570,13 +572,15 @@ begin AStream.WriteWord(0); { Index to last used row, increased by 1 } - AStream.WriteWord(33); + lLastRow := Word(GetLastRowIndex(AWorksheet)+1); + AStream.WriteWord(WordToLE(lLastRow)); // Old dummy value: 33 { Index to first used column } AStream.WriteWord(0); { Index to last used column, increased by 1 } - AStream.WriteWord(10); + lLastCol := Word(GetLastColIndex(AWorksheet)+1); + AStream.WriteWord(WordToLE(lLastCol)); // Old dummy value: 10 { Not used } AStream.WriteWord(0); diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas index 0e90836d2..cb707b8eb 100755 --- a/components/fpspreadsheet/xlsbiff8.pas +++ b/components/fpspreadsheet/xlsbiff8.pas @@ -53,7 +53,7 @@ interface uses Classes, SysUtils, fpcanvas, - fpspreadsheet, xlsbiffcommon, + fpspreadsheet, xlscommon, {$ifdef USE_NEW_OLE} fpolebasic, {$else} @@ -117,7 +117,7 @@ type { Record writing methods } procedure WriteBOF(AStream: TStream; ADataType: Word); function WriteBoundsheet(AStream: TStream; ASheetName: string): Int64; - procedure WriteDimensions(AStream: TStream); + procedure WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet); procedure WriteEOF(AStream: TStream); procedure WriteFont(AStream: TStream; AFont: TFPCustomFont); procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TsFormula); override; @@ -517,7 +517,7 @@ begin WriteIndex(AStream); - WriteDimensions(AStream); + WriteDimensions(AStream, AData.GetWorksheetByIndex(i)); WriteWindow2(AStream, True); @@ -618,7 +618,10 @@ end; * nm = (rl - rf - 1) / 32 + 1 (using integer division) * *******************************************************************} -procedure TsSpreadBIFF8Writer.WriteDimensions(AStream: TStream); +procedure TsSpreadBIFF8Writer.WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet); +var + lLastCol: Word; + lLastRow: Integer; begin { BIFF Record header } AStream.WriteWord(WordToLE(INT_EXCEL_ID_DIMENSIONS)); @@ -628,13 +631,15 @@ begin AStream.WriteDWord(DWordToLE(0)); { Index to last used row, increased by 1 } - AStream.WriteDWord(DWordToLE(33)); + lLastRow := GetLastRowIndex(AWorksheet)+1; + AStream.WriteDWord(DWordToLE(lLastRow)); // Old dummy value: 33 { Index to first used column } AStream.WriteWord(WordToLE(0)); { Index to last used column, increased by 1 } - AStream.WriteWord(WordToLE(10)); + lLastCol := GetLastColIndex(AWorksheet)+1; + AStream.WriteWord(WordToLE(lLastCol)); // Old dummy value: 10 { Not used } AStream.WriteWord(WordToLE(0)); diff --git a/components/fpspreadsheet/xlsbiffcommon.pas b/components/fpspreadsheet/xlsbiffcommon.pas deleted file mode 100644 index 306beb205..000000000 --- a/components/fpspreadsheet/xlsbiffcommon.pas +++ /dev/null @@ -1,80 +0,0 @@ -unit xlsbiffcommon; - -{$ifdef fpc} - {$mode delphi} -{$endif} - -interface - -uses - Classes, SysUtils, - fpspreadsheet, - fpsutils; - -{ Excel Constants which don't change across versions } -const - { Built In Color Pallete Indexes } - BUILT_IN_COLOR_PALLETE_BLACK = $08; // 000000H - BUILT_IN_COLOR_PALLETE_WHITE = $09; // FFFFFFH - BUILT_IN_COLOR_PALLETE_RED = $0A; // FF0000H - BUILT_IN_COLOR_PALLETE_GREEN = $0B; // 00FF00H - BUILT_IN_COLOR_PALLETE_BLUE = $0C; // 0000FFH - BUILT_IN_COLOR_PALLETE_YELLOW = $0D; // FFFF00H - BUILT_IN_COLOR_PALLETE_MAGENTA = $0E; // FF00FFH - BUILT_IN_COLOR_PALLETE_CYAN = $0F; // 00FFFFH - BUILT_IN_COLOR_PALLETE_DARK_RED = $10; // 800000H - BUILT_IN_COLOR_PALLETE_DARK_GREEN= $11; // 008000H - BUILT_IN_COLOR_PALLETE_DARK_BLUE = $12; // 000080H - BUILT_IN_COLOR_PALLETE_OLIVE = $13; // 808000H - BUILT_IN_COLOR_PALLETE_PURPLE = $14; // 800080H - BUILT_IN_COLOR_PALLETE_TEAL = $15; // 008080H - BUILT_IN_COLOR_PALLETE_SILVER = $16; // C0C0C0H - BUILT_IN_COLOR_PALLETE_GREY = $17; // 808080H - - EXTRA_COLOR_PALETTE_GREY10PCT = $18; // E6E6E6H - EXTRA_COLOR_PALETTE_GREY20PCT = $19; // E6E6E6H - -type - - { TsSpreadBIFFReader } - - TsSpreadBIFFReader = class(TsCustomSpreadReader) - protected - end; - - { TsSpreadBIFFWriter } - - TsSpreadBIFFWriter = class(TsCustomSpreadWriter) - protected - function FPSColorToEXCELPallete(AColor: TsColor): Word; - end; - -implementation - -function TsSpreadBIFFWriter.FPSColorToEXCELPallete(AColor: TsColor): Word; -begin - case AColor of - scBlack: Result := BUILT_IN_COLOR_PALLETE_BLACK; - scWhite: Result := BUILT_IN_COLOR_PALLETE_WHITE; - scRed: Result := BUILT_IN_COLOR_PALLETE_RED; - scGREEN: Result := BUILT_IN_COLOR_PALLETE_GREEN; - scBLUE: Result := BUILT_IN_COLOR_PALLETE_BLUE; - scYELLOW: Result := BUILT_IN_COLOR_PALLETE_YELLOW; - scMAGENTA: Result := BUILT_IN_COLOR_PALLETE_MAGENTA; - scCYAN: Result := BUILT_IN_COLOR_PALLETE_CYAN; - scDarkRed: Result := BUILT_IN_COLOR_PALLETE_DARK_RED; - scDarkGreen: Result := BUILT_IN_COLOR_PALLETE_DARK_GREEN; - scDarkBlue: Result := BUILT_IN_COLOR_PALLETE_DARK_BLUE; - scOLIVE: Result := BUILT_IN_COLOR_PALLETE_OLIVE; - scPURPLE: Result := BUILT_IN_COLOR_PALLETE_PURPLE; - scTEAL: Result := BUILT_IN_COLOR_PALLETE_TEAL; - scSilver: Result := BUILT_IN_COLOR_PALLETE_SILVER; - scGrey: Result := BUILT_IN_COLOR_PALLETE_GREY; - // - scGrey10pct: Result := EXTRA_COLOR_PALETTE_GREY10PCT; - scGrey20pct: Result := EXTRA_COLOR_PALETTE_GREY20PCT; - end; -end; - -end. - diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas index 6f81a6405..e6402047b 100644 --- a/components/fpspreadsheet/xlscommon.pas +++ b/components/fpspreadsheet/xlscommon.pas @@ -1,9 +1,16 @@ unit xlscommon; -{$mode objfpc}{$H+} +{$ifdef fpc} + {$mode delphi} +{$endif} interface +uses + Classes, SysUtils, + fpspreadsheet, + fpsutils; + const { Formula constants TokenID values } @@ -31,7 +38,95 @@ const INT_EXCEL_SHEET_FUNC_ABS = 24; INT_EXCEL_SHEET_FUNC_ROUND = 27; + { Built In Color Pallete Indexes } + BUILT_IN_COLOR_PALLETE_BLACK = $08; // 000000H + BUILT_IN_COLOR_PALLETE_WHITE = $09; // FFFFFFH + BUILT_IN_COLOR_PALLETE_RED = $0A; // FF0000H + BUILT_IN_COLOR_PALLETE_GREEN = $0B; // 00FF00H + BUILT_IN_COLOR_PALLETE_BLUE = $0C; // 0000FFH + BUILT_IN_COLOR_PALLETE_YELLOW = $0D; // FFFF00H + BUILT_IN_COLOR_PALLETE_MAGENTA = $0E; // FF00FFH + BUILT_IN_COLOR_PALLETE_CYAN = $0F; // 00FFFFH + BUILT_IN_COLOR_PALLETE_DARK_RED = $10; // 800000H + BUILT_IN_COLOR_PALLETE_DARK_GREEN= $11; // 008000H + BUILT_IN_COLOR_PALLETE_DARK_BLUE = $12; // 000080H + BUILT_IN_COLOR_PALLETE_OLIVE = $13; // 808000H + BUILT_IN_COLOR_PALLETE_PURPLE = $14; // 800080H + BUILT_IN_COLOR_PALLETE_TEAL = $15; // 008080H + BUILT_IN_COLOR_PALLETE_SILVER = $16; // C0C0C0H + BUILT_IN_COLOR_PALLETE_GREY = $17; // 808080H + + EXTRA_COLOR_PALETTE_GREY10PCT = $18; // E6E6E6H + EXTRA_COLOR_PALETTE_GREY20PCT = $19; // E6E6E6H + +type + + { TsSpreadBIFFReader } + + TsSpreadBIFFReader = class(TsCustomSpreadReader) + protected + end; + + { TsSpreadBIFFWriter } + + TsSpreadBIFFWriter = class(TsCustomSpreadWriter) + protected + FLastRow, FLastCol: Integer; + function FPSColorToEXCELPallete(AColor: TsColor): Word; + procedure GetLastRowCallback(ACell: PCell; AStream: TStream); + function GetLastRowIndex(AWorksheet: TsWorksheet): Integer; + procedure GetLastColCallback(ACell: PCell; AStream: TStream); + function GetLastColIndex(AWorksheet: TsWorksheet): Word; + end; + implementation +function TsSpreadBIFFWriter.FPSColorToEXCELPallete(AColor: TsColor): Word; +begin + case AColor of + scBlack: Result := BUILT_IN_COLOR_PALLETE_BLACK; + scWhite: Result := BUILT_IN_COLOR_PALLETE_WHITE; + scRed: Result := BUILT_IN_COLOR_PALLETE_RED; + scGREEN: Result := BUILT_IN_COLOR_PALLETE_GREEN; + scBLUE: Result := BUILT_IN_COLOR_PALLETE_BLUE; + scYELLOW: Result := BUILT_IN_COLOR_PALLETE_YELLOW; + scMAGENTA: Result := BUILT_IN_COLOR_PALLETE_MAGENTA; + scCYAN: Result := BUILT_IN_COLOR_PALLETE_CYAN; + scDarkRed: Result := BUILT_IN_COLOR_PALLETE_DARK_RED; + scDarkGreen: Result := BUILT_IN_COLOR_PALLETE_DARK_GREEN; + scDarkBlue: Result := BUILT_IN_COLOR_PALLETE_DARK_BLUE; + scOLIVE: Result := BUILT_IN_COLOR_PALLETE_OLIVE; + scPURPLE: Result := BUILT_IN_COLOR_PALLETE_PURPLE; + scTEAL: Result := BUILT_IN_COLOR_PALLETE_TEAL; + scSilver: Result := BUILT_IN_COLOR_PALLETE_SILVER; + scGrey: Result := BUILT_IN_COLOR_PALLETE_GREY; + // + scGrey10pct: Result := EXTRA_COLOR_PALETTE_GREY10PCT; + scGrey20pct: Result := EXTRA_COLOR_PALETTE_GREY20PCT; + end; +end; + +procedure TsSpreadBIFFWriter.GetLastRowCallback(ACell: PCell; AStream: TStream); +begin + if ACell^.Row > FLastRow then FLastRow := ACell^.Row; +end; + +function TsSpreadBIFFWriter.GetLastRowIndex(AWorksheet: TsWorksheet): Integer; +begin + FLastRow := 0; + IterateThroughCells(nil, AWorksheet.Cells, GetLastRowCallback); +end; + +procedure TsSpreadBIFFWriter.GetLastColCallback(ACell: PCell; AStream: TStream); +begin + if ACell^.Col > FLastCol then FLastCol := ACell^.Col; +end; + +function TsSpreadBIFFWriter.GetLastColIndex(AWorksheet: TsWorksheet): Word; +begin + FLastCol := 0; + IterateThroughCells(nil, AWorksheet.Cells, GetLastColCallback); +end; + end.