diff --git a/build.gradle b/build.gradle index a4b5d906e1c..f69bab2ad19 100644 --- a/build.gradle +++ b/build.gradle @@ -141,7 +141,7 @@ subprojects { apply plugin: 'de.thetaphi.forbiddenapis' apply plugin: 'com.github.spotbugs' - version = '5.2.3-AIRSLATE-26' + version = '5.2.3-AIRSLATE-26.2' ext { bouncyCastleVersion = '1.70' commonsCodecVersion = '1.15' diff --git a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java index 9e0a699eab8..6d7f9fa813a 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java @@ -541,13 +541,19 @@ private void appendBodyElementText(StringBuilder text, IBodyElement e, boolean i } else if (e instanceof XWPFTable) { XWPFTable eTable = (XWPFTable) e; for (XWPFTableRow row : eTable.getRows()) { - for (XWPFTableCell cell : row.getTableCells()) { + List tableCells = row.getTableCells(); + for (int i = 0; i < tableCells.size(); i++) { + XWPFTableCell cell = tableCells.get(i); List localBodyElements = cell.getBodyElements(); - for (int i = 0; i < localBodyElements.size(); i++) { - boolean localIsLast = (i == localBodyElements.size() - 1); - appendBodyElementText(text, localBodyElements.get(i), localIsLast); + for (int j = 0; j < localBodyElements.size(); j++) { + boolean localIsLast = (j == localBodyElements.size() - 1); + appendBodyElementText(text, localBodyElements.get(j), localIsLast); + } + if (i < tableCells.size() - 1) { + text.append("\t"); } } + text.append('\n'); } if (!isLast) { diff --git a/poi-ooxml/src/test/java/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java b/poi-ooxml/src/test/java/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java index 6e5716549b9..893e6786e6b 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xwpf/extractor/TestXWPFWordExtractor.java @@ -27,10 +27,14 @@ Licensed to the Apache Software Foundation (ASF) under one or more import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; +import java.io.InputStream; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.poi.extractor.POITextExtractor; +import org.apache.poi.hwpf.extractor.Word6Extractor; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.util.StringUtil; import org.apache.poi.xwpf.XWPFTestDataSamples; import org.apache.poi.xwpf.usermodel.XWPFDocument; @@ -478,4 +482,41 @@ void bug55966() throws IOException { assertEquals(expected, actual); } } + + @Test + void testExtractorAddBreaksForNestedTable() throws Exception { + try (XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("NestedTables.docx")) { + String expected = "Table 1\n" + + "{{table(a)}}\t\n" + + "{{h}}Name\t\n" + + "{{name}}\t{{table(b)}}\t\n" + + "{{h}}Product\tFillableField\n" + + "{{Product}}\t{{t:t;r:y;l:\"text_field_1\";}} \n" + + "{{endtable}}\t\n" + + "\n" + + "\n" + + "{{endtable}}\t\n" + + "\n" + + "\n" + + "\n" + + "Table 2\n" + + "{{table(t1)}}\t\n" + + "{{table(t2)}}\n" + + "{{name}}\n" + + "{{endtable}}\n" + + "\n" + + "\t{{name}}\n" + + "\t\n" + + "{{endtable}}\t\n" + + "\n" + + "\n"; + + XWPFWordExtractor extractedDoc = new XWPFWordExtractor(doc); + + String actual = extractedDoc.getText(); + + extractedDoc.close(); + assertEquals(expected, actual); + } + } } diff --git a/test-data/document/NestedTables.docx b/test-data/document/NestedTables.docx new file mode 100644 index 00000000000..df38287eb40 Binary files /dev/null and b/test-data/document/NestedTables.docx differ