diff --git a/fastexcel-writer/src/main/java/org/dhatim/fastexcel/Cell.java b/fastexcel-writer/src/main/java/org/dhatim/fastexcel/Cell.java
index 37f1ec2c..89ee26f4 100644
--- a/fastexcel-writer/src/main/java/org/dhatim/fastexcel/Cell.java
+++ b/fastexcel-writer/src/main/java/org/dhatim/fastexcel/Cell.java
@@ -62,7 +62,7 @@ void write(Writer w, int r, int c) throws IOException {
} else if (value instanceof RichText) {
((RichText) value).write(w);
} else if (value instanceof String) {
- w.append("").appendEscaped((String) value).append("");
+ w.append("").appendEscaped((String) value).append("");
} else if (value != null) {
w.append("");
if (value instanceof CachedString) {
diff --git a/fastexcel-writer/src/test/java/org/dhatim/fastexcel/CorrectnessTest.java b/fastexcel-writer/src/test/java/org/dhatim/fastexcel/CorrectnessTest.java
index 1ec32dad..c637cc52 100644
--- a/fastexcel-writer/src/test/java/org/dhatim/fastexcel/CorrectnessTest.java
+++ b/fastexcel-writer/src/test/java/org/dhatim/fastexcel/CorrectnessTest.java
@@ -17,17 +17,23 @@
import org.apache.commons.io.output.NullOutputStream;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.*;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.function.Consumer;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import static org.assertj.core.api.Assertions.assertThat;
import static org.dhatim.fastexcel.CellAddress.convertNumToColString;
@@ -770,4 +776,40 @@ void testFormatCodeWithSpecialCharacters() throws Exception {
// If we reach here without exception, the XML was valid
}
+ @Test
+ void stringCellsKeepEdgeWhitespace(@TempDir Path directory) throws Exception {
+ Path file = directory.resolve("whitespace.xlsx");
+ writeWorkbook(wb -> {
+ Worksheet ws = wb.newWorksheet("Sheet 1");
+ ws.value(0, 0, " shared ");
+ ws.inlineString(1, 0, " inline ");
+ ws.inlineString(2, 0, RichText.builder().run(" rich ").end().build());
+ }, file.toString());
+
+ try (ZipFile workbook = new ZipFile(file.toFile())) {
+ String sharedStrings = readPart(workbook, "xl/sharedStrings.xml");
+ String sheet = readPart(workbook, "xl/worksheets/sheet1.xml");
+
+ // Every string path must mark its text as whitespace-significant, otherwise
+ // Excel trims leading and trailing whitespace when it reads the cell.
+ assertThat(sharedStrings).contains(" shared ");
+ assertThat(sheet).contains(" inline ");
+ assertThat(sheet).contains(" rich ");
+ }
+ }
+
+ private static String readPart(ZipFile workbook, String name) throws IOException {
+ ZipEntry entry = workbook.getEntry(name);
+ assertThat(entry).as("%s should be present", name).isNotNull();
+ try (InputStream in = workbook.getInputStream(entry)) {
+ ByteArrayOutputStream contents = new ByteArrayOutputStream();
+ byte[] buffer = new byte[8192];
+ int read;
+ while ((read = in.read(buffer)) != -1) {
+ contents.write(buffer, 0, read);
+ }
+ return new String(contents.toByteArray(), StandardCharsets.UTF_8);
+ }
+ }
+
}