diff --git a/components/fpspreadsheet/fpsutils.pas b/components/fpspreadsheet/fpsutils.pas index c97cd5081..f7775cf23 100644 --- a/components/fpspreadsheet/fpsutils.pas +++ b/components/fpspreadsheet/fpsutils.pas @@ -52,7 +52,7 @@ function WordLEtoN(AValue: Word): Word; function DWordLEtoN(AValue: Cardinal): Cardinal; function WideStringLEToN(const AValue: WideString): WideString; -// Other routines +// Cell, column and row strings function ParseIntervalString(const AStr: string; out AFirstCellRow, AFirstCellCol, ACount: Cardinal; out ADirection: TsSelectionDirection): Boolean; @@ -1534,6 +1534,7 @@ begin '"': Result := Result + '"'; '''':Result := Result + '''; '%': Result := Result + '%'; + { this breaks multi-line labels in xlsx #10: begin Result := Result + '
'; if (idx < Length(AText)) and (AText[idx+1] = #13) then inc(idx); @@ -1542,6 +1543,7 @@ begin Result := Result + '
'; if (idx < Length(AText)) and (AText[idx+1] = #10) then inc(idx); end; + } { #10: WrkStr := WrkStr + ' '; #13: WrkStr := WrkStr + ' '; diff --git a/components/fpspreadsheet/xlsbiff2.pas b/components/fpspreadsheet/xlsbiff2.pas index c3743bf9f..4308bc16b 100755 --- a/components/fpspreadsheet/xlsbiff2.pas +++ b/components/fpspreadsheet/xlsbiff2.pas @@ -1836,7 +1836,7 @@ begin if AValue = '' then Exit; // Writing an empty text doesn't work - AnsiText := UTF8ToISO_8859_1(AValue); + AnsiText := UTF8ToISO_8859_1(FixLineEnding(AValue)); if Length(AnsiText) > MAXBYTES then begin // BIFF 5 does not support labels/text bigger than 255 chars, diff --git a/components/fpspreadsheet/xlsbiff5.pas b/components/fpspreadsheet/xlsbiff5.pas index 4c88a6347..4417bdccf 100755 --- a/components/fpspreadsheet/xlsbiff5.pas +++ b/components/fpspreadsheet/xlsbiff5.pas @@ -1465,7 +1465,7 @@ begin if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then exit; - ansiValue := ConvertEncoding(AValue, encodingUTF8, FCodePage); + ansiValue := ConvertEncoding(FixLineEnding(AValue), encodingUTF8, FCodePage); if AnsiValue = '' then begin // Bad formatted UTF8String (maybe ANSI?) if Length(AValue) <> 0 then begin diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas index 70eebf339..971871a6a 100755 --- a/components/fpspreadsheet/xlsbiff8.pas +++ b/components/fpspreadsheet/xlsbiff8.pas @@ -141,7 +141,7 @@ type procedure WriteHyperlinks(AStream: TStream; AWorksheet: TsWorksheet); procedure WriteHyperlinkToolTip(AStream: TStream; const ARow, ACol: Cardinal; const ATooltip: String); - procedure WriteIndex(AStream: TStream); + procedure WriteINDEX(AStream: TStream); procedure WriteLABEL(AStream: TStream; const ARow, ACol: Cardinal; const AValue: string; ACell: PCell); override; procedure WriteMergedCells(AStream: TStream; AWorksheet: TsWorksheet); @@ -2613,7 +2613,7 @@ end; nm = (rl - rf - 1) / 32 + 1 (using integer division) -------------------------------------------------------------------------------} -procedure TsSpreadBIFF8Writer.WriteIndex(AStream: TStream); +procedure TsSpreadBIFF8Writer.WriteINDEX(AStream: TStream); begin { BIFF Record header } WriteBIFFHeader(AStream, INT_EXCEL_ID_INDEX, 16); @@ -2664,7 +2664,7 @@ begin if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then exit; - WideValue := UTF8Decode(AValue); //to UTF16 + WideValue := UTF8Decode(FixLineEnding(AValue)); //to UTF16 if WideValue = '' then begin // Badly formatted UTF8String (maybe ANSI?) if Length(AValue)<>0 then begin diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas index 08bca310b..beaef7caf 100644 --- a/components/fpspreadsheet/xlscommon.pas +++ b/components/fpspreadsheet/xlscommon.pas @@ -460,6 +460,7 @@ type FPalette: TsPalette; procedure AddBuiltinNumFormats; override; function FindXFIndex(ACell: PCell): Integer; virtual; + function FixLineEnding(const AText: String): String; function GetLastRowIndex(AWorksheet: TsWorksheet): Integer; function GetLastColIndex(AWorksheet: TsWorksheet): Word; function GetPrintOptions: Word; virtual; @@ -2414,6 +2415,28 @@ begin Result := LAST_BUILTIN_XF + ACell^.FormatIndex; end; +{@@ ---------------------------------------------------------------------------- + The line separator for multi-line text in label cells is accepted by xls + to be either CRLF or LF, CR does not work. + This procedure replaces accidentally used single CR characters by LF. +-------------------------------------------------------------------------------} +function TsSpreadBIFFWriter.FixLineEnding(const AText: String): String; +var + i: Integer; +begin + Result := AText; + if Result = '' then + exit; + // if the last character is a #13 it cannot be part of a CRLF --> replace by #10 + if Result[Length(Result)] = #13 then + Result[Length(Result)] := #10; + // In the rest of the string replace all #13 (which are not followed by a #10) + // by #10. + for i:=1 to Length(Result)-1 do + if (Result[i] = #13) and (Result[i+1] <> #10) then + Result[i] := #10; +end; + function TsSpreadBIFFWriter.GetLastRowIndex(AWorksheet: TsWorksheet): Integer; begin Result := AWorksheet.GetLastRowIndex; diff --git a/components/fpspreadsheet/xlsxooxml.pas b/components/fpspreadsheet/xlsxooxml.pas index c0aa42c50..22f46c3ae 100755 --- a/components/fpspreadsheet/xlsxooxml.pas +++ b/components/fpspreadsheet/xlsxooxml.pas @@ -3853,7 +3853,7 @@ begin // unformatted string AppendToStream(FSSharedStrings, '' + - '' + txt + '' + + '' + txt + '' + '') else begin @@ -3868,7 +3868,7 @@ begin ValidXMLText(txt); AppendToStream(FSSharedStrings, '' + - '' + txt + '' + + '' + txt + '' + '' ); end; @@ -3883,7 +3883,7 @@ begin ''); WriteFont(FSSharedStrings, fnt, false); // ... font data ... AppendToStream(FSSharedStrings, - '' + txt + '' + + '' + txt + '' + '' ); if (rtParam.EndIndex < L) and (i = High(ACell^.RichTextParams)) then @@ -3892,7 +3892,7 @@ begin ValidXMLText(txt); AppendToStream(FSSharedStrings, '' + - '' + txt + '' + + '' + txt + '' + '' ) end else @@ -3903,7 +3903,7 @@ begin ValidXMLText(txt); AppendToStream(FSSharedStrings, '' + - '' + txt + '' + + '' + txt + '' + '' ); end;