Add getters and setters for XWPFTable indentation. (#843)

* Add getters and setters for XWPFTable indentation.

The element tblPr->tblInd represents "table indent from leading margin".
It 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). This
indentation should shift the table into the text margin by the specified
amount.

This value is specified in the units applied via its type attribute. Any
width value of type pct or auto for this element shall be ignored.

If this element 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. If the resulting justification on any table row is not
left, then this property shall be ignored.

To implement this property, we included a getter and a setter for the
property value, and another couple of getter/setter for the existence
(and validity) or absence of the property itself, for clients to know
they must fall back to the table style.

* Address reviewer comments.
This commit is contained in:
Jacobo Aragunde Pérez 2025-07-15 11:05:17 +02:00 committed by GitHub
parent d4fc5cd6c0
commit 73b2874824
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 139 additions and 5 deletions

View File

@ -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).
*
* <p>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).</p>
* <p>If the table alignment is not left/start, this property shall be ignored.</p>
*
* @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.
*
* <p>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.</p>
*
* @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.
*/

View File

@ -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());
}
}
}
@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());
}
}
}

Binary file not shown.