fpspreadsheet: Fix biff8 writer to use CONTINUE records if text in STRING record is too long.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6055 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2017-11-03 18:43:37 +00:00
parent 0310e5587e
commit f20779983f
12 changed files with 147 additions and 44 deletions

View File

@ -8,7 +8,7 @@ msgstr ""
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.9\n" "X-Generator: Poedit 2.0.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: de\n" "Language: de\n"
@ -310,15 +310,15 @@ msgstr "Palettenindex %d"
#: fpsstrings.rspasswordremoved_biff2 #: fpsstrings.rspasswordremoved_biff2
msgid "Password removed (BIFF2 requires matching workbook and worksheet passwords)" msgid "Password removed (BIFF2 requires matching workbook and worksheet passwords)"
msgstr "" msgstr "Das Passwort wurde entfernt (BIFF2 erfordert übereinstimmende Passwörter von Workbook und Worksheet "
#: fpsstrings.rspasswordremoved_excel #: fpsstrings.rspasswordremoved_excel
msgid "Password removed (Hashing algorithm not compatible with Excel)" msgid "Password removed (Hashing algorithm not compatible with Excel)"
msgstr "" msgstr "Das Passwort wurde entfernt (Der Hashing-Algorithmus ist nicht mit Excel kompatibel)."
#: fpsstrings.rspasswordremoved_notvalid #: fpsstrings.rspasswordremoved_notvalid
msgid "Password removed (Not valid)." msgid "Password removed (Not valid)."
msgstr "" msgstr "Das Passwort wurde entfernt (ungültig)."
#: fpsstrings.rspurple #: fpsstrings.rspurple
msgid "purple" msgid "purple"
@ -364,6 +364,10 @@ msgstr "transparent"
msgid "Text value exceeds the %d character limit in cell %s and has been truncated." msgid "Text value exceeds the %d character limit in cell %s and has been truncated."
msgstr "Der Text überschreitet die Grenze von %d Zeichen in Zelle %s und wurde abgeschnitten." msgstr "Der Text überschreitet die Grenze von %d Zeichen in Zelle %s und wurde abgeschnitten."
#: fpsstrings.rstruncatetoolongtext
msgid "Text value exceeds the %d character limit and has been truncated."
msgstr "Der Text ist länger als die Grenze bei %d Zeichen und wurde gekürzt."
#: fpsstrings.rsunexpectedendofexpression #: fpsstrings.rsunexpectedendofexpression
msgid "Unexpected end of expression" msgid "Unexpected end of expression"
msgstr "Unerwartetes Ende des Ausdrucks" msgstr "Unerwartetes Ende des Ausdrucks"
@ -431,4 +435,3 @@ msgstr "Die Datei kann nicht geschrieben werden, weil der Name des Arbeitsblatte
#: fpsstrings.rsyellow #: fpsstrings.rsyellow
msgid "yellow" msgid "yellow"
msgstr "gelb" msgstr "gelb"

View File

@ -353,6 +353,10 @@ msgstr "läpinäkyvä"
msgid "Text value exceeds the %d character limit in cell %s and has been truncated." msgid "Text value exceeds the %d character limit in cell %s and has been truncated."
msgstr "" msgstr ""
#: fpsstrings.rstruncatetoolongtext
msgid "Text value exceeds the %d character limit and has been truncated."
msgstr ""
#: fpsstrings.rsunexpectedendofexpression #: fpsstrings.rsunexpectedendofexpression
msgid "Unexpected end of expression" msgid "Unexpected end of expression"
msgstr "" msgstr ""

View File

@ -367,6 +367,10 @@ msgstr "átlátszó"
msgid "Text value exceeds the %d character limit in cell %s and has been truncated." msgid "Text value exceeds the %d character limit in cell %s and has been truncated."
msgstr "A szöveg hosszabb mint a(z) 15 karakteres korlát a(z) %s cellában, ezért csonkolva lett." msgstr "A szöveg hosszabb mint a(z) 15 karakteres korlát a(z) %s cellában, ezért csonkolva lett."
#: fpsstrings.rstruncatetoolongtext
msgid "Text value exceeds the %d character limit and has been truncated."
msgstr ""
#: fpsstrings.rsunexpectedendofexpression #: fpsstrings.rsunexpectedendofexpression
msgid "Unexpected end of expression" msgid "Unexpected end of expression"
msgstr "A kifejezés váratlanul ért véget" msgstr "A kifejezés váratlanul ért véget"

View File

@ -353,6 +353,10 @@ msgstr ""
msgid "Text value exceeds the %d character limit in cell %s and has been truncated." msgid "Text value exceeds the %d character limit in cell %s and has been truncated."
msgstr "" msgstr ""
#: fpsstrings.rstruncatetoolongtext
msgid "Text value exceeds the %d character limit and has been truncated."
msgstr ""
#: fpsstrings.rsunexpectedendofexpression #: fpsstrings.rsunexpectedendofexpression
msgid "Unexpected end of expression" msgid "Unexpected end of expression"
msgstr "" msgstr ""

View File

@ -357,6 +357,10 @@ msgstr "прозрачно"
msgid "Text value exceeds the %d character limit in cell %s and has been truncated." msgid "Text value exceeds the %d character limit in cell %s and has been truncated."
msgstr "Текстовое выражения ограничено %d символами в ячейке %s и будет уменьшено." msgstr "Текстовое выражения ограничено %d символами в ячейке %s и будет уменьшено."
#: fpsstrings.rstruncatetoolongtext
msgid "Text value exceeds the %d character limit and has been truncated."
msgstr ""
#: fpsstrings.rsunexpectedendofexpression #: fpsstrings.rsunexpectedendofexpression
msgid "Unexpected end of expression" msgid "Unexpected end of expression"
msgstr "Ожидается конец выражения" msgstr "Ожидается конец выражения"

View File

@ -280,7 +280,7 @@ type
procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override; procedure WriteToStream(AStream: TStream; AParams: TsStreamParams = []); override;
end; end;
{ procedure WriteStarObjectDescriptorToStream(AStream: TStream); } procedure InitOpenDocLimitations(out ALimitations: TsSpreadsheetFormatLimitations);
var var
sfidOpenDocument: TsSpreadFormatID; sfidOpenDocument: TsSpreadFormatID;
@ -452,6 +452,16 @@ begin
end; *) end; *)
procedure InitOpenDocLimitations(out ALimitations: TsSpreadsheetFormatLimitations);
begin
// http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications
ALimitations.MaxColCount := 1024;
ALimitations.MaxRowCount := 1048576;
//https://forum.openoffice.org/en/forum/viewtopic.php?f=9&t=11247&p=52985
ALimitations.MaxCharsInTextCell := 65535;
end;
{******************************************************************************} {******************************************************************************}
{ TXMLHeaderFooterFont } { TXMLHeaderFooterFont }
{******************************************************************************} {******************************************************************************}
@ -993,9 +1003,7 @@ constructor TsSpreadOpenDocReader.Create(AWorkbook: TsWorkbook);
begin begin
inherited Create(AWorkbook); inherited Create(AWorkbook);
// http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications InitOpenDocLimitations(FLimitations);
FLimitations.MaxColCount := 1024;
FLimitations.MaxRowCount := 1048576;
FPointSeparatorSettings := DefaultFormatSettings; FPointSeparatorSettings := DefaultFormatSettings;
FPointSeparatorSettings.DecimalSeparator := '.'; FPointSeparatorSettings.DecimalSeparator := '.';
@ -6280,9 +6288,7 @@ begin
FPointSeparatorSettings.DecimalSeparator:='.'; FPointSeparatorSettings.DecimalSeparator:='.';
FPointSeparatorSettings.ListSeparator := ';'; // for formulas FPointSeparatorSettings.ListSeparator := ';'; // for formulas
// http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications InitOpenDocLimitations(FLimitations);
FLimitations.MaxColCount := 1024;
FLimitations.MaxRowCount := 1048576;
end; end;
destructor TsSpreadOpenDocWriter.Destroy; destructor TsSpreadOpenDocWriter.Destroy;

View File

@ -37,6 +37,8 @@ resourcestring
'the best-matching palette colors.'; 'the best-matching palette colors.';
rsTruncateTooLongCellText = 'Text value exceeds the %d character limit in ' + rsTruncateTooLongCellText = 'Text value exceeds the %d character limit in ' +
'cell %s and has been truncated.'; 'cell %s and has been truncated.';
rsTruncateTooLongText = 'Text value exceeds the %d character limit ' +
'and has been truncated.';
rsWriteError_WorksheetNameTooLong = 'File cannot be written because ' + rsWriteError_WorksheetNameTooLong = 'File cannot be written because ' +
'the name of worksheet "%0:s" is too long (max %1:d characters).'; 'the name of worksheet "%0:s" is too long (max %1:d characters).';

View File

@ -45,6 +45,7 @@ type
MaxColCount: Cardinal; MaxColCount: Cardinal;
MaxPaletteSize: Integer; MaxPaletteSize: Integer;
MaxSheetNameLength: Integer; MaxSheetNameLength: Integer;
MaxCharsInTextCell: Integer;
end; end;
const const

View File

@ -170,6 +170,9 @@ var
sfidExcel2: TsSpreadFormatID; sfidExcel2: TsSpreadFormatID;
procedure InitBiff2Limitations(out ALimitations: TsSpreadsheetFormatLimitations);
implementation implementation
uses uses
@ -270,6 +273,12 @@ type
end; end;
procedure InitBiff2Limitations(out ALimitations: TsSpreadsheetFormatLimitations);
begin
InitBiffLimitations(ALimitations);
ALimitations.MaxPaletteSize := BIFF2_MAX_PALETTE_SIZE;
end;
procedure InternalAddBuiltinNumFormats(AList: TStringList; AFormatSettings: TFormatSettings); procedure InternalAddBuiltinNumFormats(AList: TStringList; AFormatSettings: TFormatSettings);
var var
fs: TFormatSettings absolute AFormatSettings; fs: TFormatSettings absolute AFormatSettings;
@ -311,13 +320,12 @@ end;
constructor TsSpreadBIFF2Reader.Create(AWorkbook: TsWorkbook); constructor TsSpreadBIFF2Reader.Create(AWorkbook: TsWorkbook);
begin begin
inherited Create(AWorkbook); inherited Create(AWorkbook);
FLimitations.MaxPaletteSize := BIFF2_MAX_PALETTE_SIZE; InitBiff2Limitations(FLimitations);
end; end;
procedure TsSpreadBIFF2Reader.AddBuiltInNumFormats; procedure TsSpreadBIFF2Reader.AddBuiltInNumFormats;
begin begin
FFirstNumFormatIndexInFile := 0; FFirstNumFormatIndexInFile := 0;
//InternalAddBuiltInNumFormats(FNumFormatList, Workbook.FormatSettings);
end; end;
procedure TsSpreadBIFF2Reader.ReadBlank(AStream: TStream); procedure TsSpreadBIFF2Reader.ReadBlank(AStream: TStream);
@ -1203,7 +1211,9 @@ end;
constructor TsSpreadBIFF2Writer.Create(AWorkbook: TsWorkbook); constructor TsSpreadBIFF2Writer.Create(AWorkbook: TsWorkbook);
begin begin
inherited Create(AWorkbook); inherited Create(AWorkbook);
FLimitations.MaxPaletteSize := BIFF2_MAX_PALETTE_SIZE;
InitBiff2Limitations(FLimitations);
FDateMode := Excel2Settings.DateMode; FDateMode := Excel2Settings.DateMode;
FCodePage := Excel2Settings.CodePage; FCodePage := Excel2Settings.CodePage;
FSheetIndex := Excel2Settings.SheetIndex; FSheetIndex := Excel2Settings.SheetIndex;

View File

@ -403,6 +403,7 @@ const
SHAPEID_BASE = 1024; SHAPEID_BASE = 1024;
MAX_BYTES_IN_RECORD = 8224; // without header MAX_BYTES_IN_RECORD = 8224; // without header
MAX_CHARS_IN_WIDESTRING = 32758;
type type
@ -3179,13 +3180,10 @@ end;
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsSpreadBIFF8Writer.WriteLABEL(AStream: TStream; procedure TsSpreadBIFF8Writer.WriteLABEL(AStream: TStream;
const ARow, ACol: Cardinal; const AValue: String; ACell: PCell); const ARow, ACol: Cardinal; const AValue: String; ACell: PCell);
const
//limit for this format: 32767 characters (2 byte each) - header:
//37267-8-1=32758
MAXCHARS = 32758;
var var
L: Word; L: Word;
WideStr: WideString; WideStr: WideString;
recSize: Integer;
rec: TBIFF8_LabelRecord; rec: TBIFF8_LabelRecord;
recSST: TBIFF8_LabelSSTRecord; recSST: TBIFF8_LabelSSTRecord;
buf: array of byte; buf: array of byte;
@ -3195,8 +3193,8 @@ begin
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
// If string is in SST write a LABELSST record
idx := IndexOfSharedString(ACell^.UTF8StringValue, ACell^.RichTextParams); idx := IndexOfSharedString(ACell^.UTF8StringValue, ACell^.RichTextParams);
if idx > -1 then begin if idx > -1 then begin
recSST.RecordID := WordToLE(INT_EXCEL_ID_LABELSST); recSST.RecordID := WordToLE(INT_EXCEL_ID_LABELSST);
recSST.RecordSize := WordToLE(SizeOf(recSST) - SizeOf(TsBiffHeader)); recSST.RecordSize := WordToLE(SizeOf(recSST) - SizeOf(TsBiffHeader));
@ -3208,6 +3206,7 @@ begin
exit; exit;
end; end;
// If string is not in SST write a standard LABEL cell
WideStr := UTF8Decode(FixLineEnding(AValue)); //to UTF16 WideStr := UTF8Decode(FixLineEnding(AValue)); //to UTF16
if WideStr = '' then begin if WideStr = '' then begin
// Badly formatted UTF8String (maybe ANSI?) // Badly formatted UTF8String (maybe ANSI?)
@ -3218,15 +3217,12 @@ begin
Exit; Exit;
end; end;
// wp: THIS IS PROBABLY WRONG, BECAUSE A RECORD CAN ONLY CONTAIN 8224 BYTES AND if Length(WideStr) > FLimitations.MaxCharsInTextCell then begin
// A CONTINUE RECORD MUST BE USED!
if Length(WideStr) > MAXCHARS then begin
// Rather than lose data when reading it, let the application programmer deal // Rather than lose data when reading it, let the application programmer deal
// with the problem or purposefully ignore it. // with the problem or purposefully ignore it.
SetLength(WideStr, MAXCHARS); //may corrupt the string (e.g. in surrogate pairs), but... too bad. SetLength(WideStr, FLimitations.MaxCharsInTextCell); //may corrupt the string (e.g. in surrogate pairs), but... too bad.
Workbook.AddErrorMsg(rsTruncateTooLongCellText, [ Workbook.AddErrorMsg(rsTruncateTooLongCellText, [
MAXCHARS, GetCellString(ARow, ACol) FLimitations.MaxCharsInTextCell, GetCellString(ARow, ACol)
]); ]);
end; end;
L := Length(WideStr); L := Length(WideStr);
@ -3234,6 +3230,12 @@ begin
{ BIFF record header } { BIFF record header }
rec.RecordID := WordToLE(IfThen(nRuns > 0, INT_EXCEL_ID_RSTRING, INT_EXCEL_ID_LABEL)); rec.RecordID := WordToLE(IfThen(nRuns > 0, INT_EXCEL_ID_RSTRING, INT_EXCEL_ID_LABEL));
(*
recSize := SizeOf(TBiff8_LabelRecord) - SizeOf(TsBiffHeader) + L*SizeOf(WideChar);
if nRuns > 0 then
inc(recSize, SizeOf(Word) + nRunms * SizeOf(TBiff8_RichTextFormattingRun);
if n
*)
rec.RecordSize := SizeOf(TBiff8_LabelRecord) - SizeOf(TsBiffHeader) + L *SizeOf(WideChar); rec.RecordSize := SizeOf(TBiff8_LabelRecord) - SizeOf(TsBiffHeader) + L *SizeOf(WideChar);
if nRuns > 0 then if nRuns > 0 then
inc(rec.RecordSize, SizeOf(Word) + nRuns * SizeOf(TBiff8_RichTextFormattingRun)); inc(rec.RecordSize, SizeOf(Word) + nRuns * SizeOf(TBiff8_RichTextFormattingRun));
@ -3763,13 +3765,24 @@ begin
s := FixLineEnding(FSharedStringTable.Strings[i]); s := FixLineEnding(FSharedStringTable.Strings[i]);
isASCII := Is8BitString(s); isASCII := Is8BitString(s);
if isASCII then if isASCII then
rs := s begin
else begin rs := s;
if Length(s) > FLimitations.MaxCharsInTextCell then
begin
SetLength(rs, FLimitations.MaxCharsInTextCell);
FWorkbook.AddErrorMsg(rsTruncateTooLongText, [FLimitations.MaxCharsInTextCell]);
end;
end else
begin
ws := WideStringToLE(UTF8ToUTF16(s)); ws := WideStringToLE(UTF8ToUTF16(s));
SetLength(rs, Length(ws) * SizeOf(widechar)); SetLength(rs, Length(ws) * SizeOf(widechar));
Move(ws[1], rs[1], Length(rs)); Move(ws[1], rs[1], Length(rs));
if Length(ws) > FLimitations.MaxCharsInTextCell then
begin
SetLength(ws, FLimitations.MaxCharsInTextCell);
FWorkbook.AddErrorMsg(rsTruncateTooLongText, [FLimitations.MaxCharsInTextCell]);
end;
end; end;
// To do: Truncate if string is too long
rtParams := TsRichTextParams(FSharedStringTable.Objects[i]); rtParams := TsRichTextParams(FSharedStringTable.Objects[i]);
@ -4096,6 +4109,7 @@ end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Write the result of a string formula in the preceding record. Write the result of a string formula in the preceding record.
In BIFF8 files no STRING record occurs, if the result string is empty.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsSpreadBIFF8Writer.WriteSTRINGRecord(AStream: TStream; procedure TsSpreadBIFF8Writer.WriteSTRINGRecord(AStream: TStream;
AString: String); AString: String);
@ -4106,20 +4120,51 @@ procedure TsSpreadBIFF8Writer.WriteSTRINGRecord(AStream: TStream;
var var
wideStr: widestring; wideStr: widestring;
len: Integer; len: Integer;
strBytes: Integer;
idx: Integer;
needCONTINUE: Boolean;
begin begin
wideStr := UTF8Decode(AString); if AString = '' then
exit;
wideStr := WideStringToLE(UTF8Decode(FixLineEnding(AString)));
len := Length(wideStr); len := Length(wideStr);
{ BIFF Record header } strBytes := len * SizeOf(WideChar);
needCONTINUE := 3 + strBytes > MAX_BYTES_IN_RECORD;
if needCONTINUE then
strBytes := MAX_BYTES_IN_RECORD - 4; // -4 = -3 (header) - 1 (even byte count)
{ BIFF STRING record header}
AStream.WriteWord(WordToLE(INT_EXCEL_ID_STRING)); AStream.WriteWord(WordToLE(INT_EXCEL_ID_STRING));
AStream.WriteWord(WordToLE(3 + len*SizeOf(widechar))); AStream.WriteWord(WordToLE(3 + strBytes));
{ Write widestring length } { Write widestring length }
AStream.WriteWord(WordToLE(len)); AStream.WriteWord(WordToLE(len));
{ Widestring flags, 1=regular unicode LE string } { Widestring flags, 1=regular unicode LE string }
AStream.WriteByte(1); AStream.WriteByte(1);
{ Write characters } { Write characters }
AStream.WriteBuffer(WideStringToLE(wideStr)[1], len * SizeOf(WideChar)); AStream.WriteBuffer(wideStr[1], strBytes);
idx := 1 + strBytes div SizeOf(WideChar);
while needCONTINUE and (idx < len) do begin
strBytes := (len - idx) * SizeOf(WideChar);
needCONTINUE := strBytes + 1 > MAX_BYTES_IN_RECORD;
if needCONTINUE then
strBytes := MAX_BYTES_IN_RECORD - 2; // -2 = -1 (flag byte) - 1 (for even count)
{ BIFF CONTINUE record header }
AStream.WriteWord(WordToLE(INT_EXCEL_ID_CONTINUE));
AStream.WriteWord(WordToLE(1 + strBytes)); // for flag byte
{ Widestring flags, 1 = regular unicode LE string }
AStream.WriteByte(1);
{Write characters }
AStream.WriteBuffer(wideStr[idx], strBytes);
inc(idx, strBytes div SizeOf(WideChar));
end;
end; end;
{@@----------------------------------------------------------------------------- {@@-----------------------------------------------------------------------------

View File

@ -656,6 +656,8 @@ type
procedure AddBuiltinBiffFormats(AList: TStringList; procedure AddBuiltinBiffFormats(AList: TStringList;
AFormatSettings: TFormatSettings; ALastIndex: Integer); AFormatSettings: TFormatSettings; ALastIndex: Integer);
procedure InitBiffLimitations(out ALimitations: TsSpreadsheetFormatLimitations);
implementation implementation
@ -884,6 +886,15 @@ begin
for i:=50 to ALastIndex do AList.Add(''); // not supported/used for i:=50 to ALastIndex do AList.Add(''); // not supported/used
end; end;
procedure InitBiffLimitations(out ALimitations: TsSpreadsheetFormatLimitations);
begin
ALimitations.MaxColCount := 256;
ALimitations.MaxRowCount := 65536;
ALimitations.MaxPaletteSize := 64;
ALimitations.MaxSheetNameLength := 31;
ALimitations.MaxCharsInTextCell := 320000; // 32767 in Excel 2003
end;
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
{ TsBIFFDefinedName } { TsBIFFDefinedName }
@ -980,9 +991,7 @@ begin
FActivePane := 3; FActivePane := 3;
// Limitations of BIFF5 and BIFF8 file format // Limitations of BIFF5 and BIFF8 file format
FLimitations.MaxColCount := 256; InitBiffLimitations(FLimitations);
FLimitations.MaxRowCount := 65536;
FLimitations.MaxPaletteSize := 64;
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@ -3076,16 +3085,15 @@ end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Constructor of the general BIFF writer. Constructor of the general BIFF writer.
Initializes the date mode and the limitations of the format. Initializes the date mode and the limitations of the format.
https://support.microsoft.com/de-de/help/507098
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
constructor TsSpreadBIFFWriter.Create(AWorkbook: TsWorkbook); constructor TsSpreadBIFFWriter.Create(AWorkbook: TsWorkbook);
begin begin
inherited Create(AWorkbook); inherited Create(AWorkbook);
// Limitations of BIFF5 and BIFF8 file formats // Limitations of BIFF5 and BIFF8 file formats
FLimitations.MaxColCount := 256; InitBIFFLimitations(FLimitations);
FLimitations.MaxRowCount := 65536;
FLimitations.MaxPaletteSize := 64;
FLimitations.MaxSheetNameLength := 31;
// Initial base date in case it won't be set otherwise. // Initial base date in case it won't be set otherwise.
// Use 1900 to get a bit more range between 1900..1904. // Use 1900 to get a bit more range between 1900..1904.

View File

@ -229,6 +229,8 @@ var
sfidOOXML: TsSpreadFormatID; sfidOOXML: TsSpreadFormatID;
procedure InitOOXMLLimitations(out ALimitations: TsSpreadsheetFormatLimitations);
implementation implementation
@ -353,6 +355,17 @@ const
); );
procedure InitOOXMLLimitations(out ALimitations: TsSpreadsheetFormatLimitations);
begin
// http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications
ALimitations.MaxColCount := 16384;
aLimitations.MaxRowCount := 1048576;
ALimitations.MaxSheetNameLength := 31;
// https://support.office.com/en-us/article/Excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3#ID0EBABAAA=Excel_2007
ALimitations.MaxCharsInTextCell := 32767;
end;
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
{ TsSpreadOOXMLReader } { TsSpreadOOXMLReader }
{------------------------------------------------------------------------------} {------------------------------------------------------------------------------}
@ -375,6 +388,8 @@ begin
FPointSeparatorSettings := DefaultFormatSettings; FPointSeparatorSettings := DefaultFormatSettings;
FPointSeparatorSettings.DecimalSeparator := '.'; FPointSeparatorSettings.DecimalSeparator := '.';
InitOOXMLLimitations(FLimitations);
end; end;
destructor TsSpreadOOXMLReader.Destroy; destructor TsSpreadOOXMLReader.Destroy;
@ -2593,10 +2608,7 @@ begin
FPointSeparatorSettings := DefaultFormatSettings; FPointSeparatorSettings := DefaultFormatSettings;
FPointSeparatorSettings.DecimalSeparator := '.'; FPointSeparatorSettings.DecimalSeparator := '.';
// http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications InitOOXMLLimitations(FLimitations);
FLimitations.MaxColCount := 16384;
FLimitations.MaxRowCount := 1048576;
FLimitations.MaxSheetNameLength := 31;
end; end;