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;