diff --git a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTable.java b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTable.java index bbd43447d3..dc4d0e4116 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTable.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFTable.java @@ -295,7 +295,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { public void setWidth(int width) { CTTblPr tblPr = getTblPr(); CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW(); - tblWidth.setW(new BigInteger(Integer.toString(width))); + tblWidth.setW(BigInteger.valueOf(width)); tblWidth.setType(STTblWidth.DXA); } @@ -306,6 +306,80 @@ public class XWPFTable implements IBodyElement, ISDTContents { return ctTbl.sizeOfTrArray(); } + /** + * Get the indentation value in 20ths of a point (twips). + * + *

This element specifies the indentation which shall be added before the leading edge of + * the current table in the document (the left edge in a left-to-right table, and the right + * edge in a right-to-left table).

+ *

If the table alignment is not left/start, this property shall be ignored.

+ * + * @see boolean hasIndent() + * @return indentation value as an integer (20ths of a point) + */ + public int getIndent() { + CTTblPr tblPr = getTblPr(false); + if (tblPr.isSetTblInd()) { + STTblWidth.Enum typeValue = tblPr.getTblInd().getType(); + if (typeValue == null) { + // "§17.4.87: If [type] is omitted, then its value shall be assumed to be dxa" + typeValue = STTblWidth.DXA; + } + switch (typeValue.intValue()) { + case STTblWidth.INT_DXA: + return (int) Units.toDXA(POIXMLUnits.parseLength(tblPr.getTblInd().xgetW())); + case STTblWidth.INT_NIL: + // "§17.18.90: [nil] Specifies that the current width is zero, regardless of + // any width value specified on the parent element" + return 0; + case STTblWidth.INT_PCT: + case STTblWidth.INT_AUTO: + // "§17.4.50: Any width value of type pct or auto for this element shall be ignored" + return 0; + } + } + return 0; + } + + /** + * Set the indentation in 20ths of a point (twips). + * @see int getIndent() + * @param indent Indentation value (20ths of a point) + */ + public void setIndent(int indent) { + CTTblPr tblPr = getTblPr(); + CTTblWidth tblInd = tblPr.isSetTblInd() ? tblPr.getTblInd() : tblPr.addNewTblInd(); + tblInd.setW(BigInteger.valueOf(indent)); + tblInd.setType(STTblWidth.DXA); + } + + /** + * Check if some indentation value is set for the table. + * + *

If this attribute is omitted, then the table shall inherit the table indentation from + * the associated table style. If table indentation is never specified in the style hierarchy, + * no indentation shall be added to the parent table.

+ * + * @return true if the indent value is set and is valid, false if it is not set or shall be + * ignored (e.g. due to invalid type). + */ + public boolean hasIndent() { + CTTblPr tblPr = getTblPr(false); + // According to §17.4.50, values with type pct or auto shall be ignored. + return tblPr.isSetTblInd() && tblPr.getTblInd().getType() != STTblWidth.PCT + && tblPr.getTblInd().getType() != STTblWidth.AUTO; + } + + /** + * Removes the table indentation attribute from a table + */ + public void removeIndent() { + CTTblPr tPr = getTblPr(false); + if (tPr != null && tPr.isSetTblInd()) { + tPr.unsetTblInd(); + } + } + /** * Returns CTTblPr object for table. Creates it if it does not exist. */ diff --git a/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFTable.java b/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFTable.java index 67e911c15a..3539dac261 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFTable.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFTable.java @@ -16,9 +16,7 @@ ==================================================================== */ package org.apache.poi.xwpf.usermodel; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.*; import java.io.IOException; import java.math.BigInteger; @@ -586,4 +584,66 @@ class TestXWPFTable { assertNull(tbl.getTableAlignment()); } } -} \ No newline at end of file + + @Test + public void testGetTableIndent() throws Exception { + // open an empty document + try (XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("table-indent.docx")) { + + XWPFTable table1 = doc.getTableArray(0); + // Indent not present in the document + assertFalse(table1.hasIndent()); + assertEquals(0, table1.getIndent()); + + XWPFTable table2 = doc.getTableArray(1); + // Valid indent value with type dxa + assertTrue(table2.hasIndent()); + assertEquals(732, table2.getIndent()); + + XWPFTable table3 = doc.getTableArray(2); + // Indent is of type "nil" + assertTrue(table3.hasIndent()); + assertEquals(0, table3.getIndent()); + + XWPFTable table4 = doc.getTableArray(3); + // Indent is of type "pct" which should be ignored + assertFalse(table4.hasIndent()); + assertEquals(0, table4.getIndent()); + + XWPFTable table5 = doc.getTableArray(4); + // Indent is of type "auto" which should be ignored + assertFalse(table5.hasIndent()); + assertEquals(0, table5.getIndent()); + + XWPFTable table6 = doc.getTableArray(5); + // Valid indent value with empty type (defaults to dxa) + assertTrue(table6.hasIndent()); + assertEquals(732, table6.getIndent()); + + XWPFTable table7 = doc.getTableArray(6); + // Valid indent value, negative values are allowed + assertTrue(table7.hasIndent()); + assertEquals(-500, table7.getIndent()); + } + } + + @Test + void testSetGetTableIndent() throws IOException { + try (XWPFDocument doc = new XWPFDocument()) { + XWPFTable tbl = doc.createTable(1, 1); + assertFalse(tbl.hasIndent()); + tbl.setIndent(100); + assertTrue(tbl.hasIndent()); + assertEquals(100, tbl.getIndent()); + tbl.setIndent(0); + assertTrue(tbl.hasIndent()); + assertEquals(0, tbl.getIndent()); + tbl.setIndent(-100); + assertTrue(tbl.hasIndent()); + assertEquals(-100, tbl.getIndent()); + tbl.removeIndent(); + assertFalse(tbl.hasIndent()); + assertEquals(0, tbl.getIndent()); + } + } +} diff --git a/test-data/document/table-indent.docx b/test-data/document/table-indent.docx new file mode 100644 index 0000000000..c4306aa937 Binary files /dev/null and b/test-data/document/table-indent.docx differ