This is an automated email from the ASF dual-hosted git repository.
fanningpj pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git
The following commit(s) were added to refs/heads/trunk by this push:
new 4fb34ebeae Fix rules for table style application in XSLFTables. (#969)
4fb34ebeae is described below
commit 4fb34ebeae0d200cd36c4fbf3b2496aef9988298
Author: Jacobo Aragunde Pérez <[email protected]>
AuthorDate: Tue Dec 16 18:03:45 2025 +0100
Fix rules for table style application in XSLFTables. (#969)
* Fix rules for table style application in XSLFTables.
Table styles contain rules for first and last rows/columns, even and
odd rows/columns... When one of these rules is empty, we are supposed
to fall back to the "whole table" rules. The fallback must also be
applied for the format that's not explicitly specified in the specific
rules.
when the corresponding specific rule is missing some info.
Fallback must also be applied when the corresponding specific rule is
missing some info. A couple of examples from the reproducer/test file
included:
The included reproducer/test file contained a few problems related to
table style application:
* The second style for horizontal/vertical banding (band2H, band2V) was
never applied.
* In the table with horizontal banding enabled, the style band1H did
not set a font color, POI returned a null font color instead of the
color from wholeTable.
* In the table with horizontal banding enabled, the style band2H did
not set a background color, POI returned null instead of the color
specified in wholeTable.
This patches fixes the behaviors mentioned above, making POI behavior
match the one from MS Office and LibreOffice.
* Replace uses of java.util.list.getFirst().
---
.../apache/poi/xslf/usermodel/XSLFTableCell.java | 40 +++++++++--
.../apache/poi/xslf/usermodel/TestXSLFTable.java | 74 +++++++++++++++++++--
.../table-with-different-font-colors.pptx | Bin 0 -> 36562 bytes
3 files changed, 102 insertions(+), 12 deletions(-)
diff --git
a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
index 019679f9bf..c43483912a 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
@@ -438,7 +438,8 @@ public class XSLFTableCell extends XSLFTextShape implements
TableCell<XSLFShape,
}
CTTablePartStyle tps = getTablePartStyle(null);
- if (tps == null || !tps.isSetTcStyle()) {
+ if (tps == null || !tps.isSetTcStyle() ||
+ (!tps.getTcStyle().isSetFill() &&
!tps.getTcStyle().isSetFillRef())) {
tps = getTablePartStyle(TablePartStyle.wholeTbl);
if (tps == null || !tps.isSetTcStyle()) {
return null;
@@ -504,10 +505,18 @@ public class XSLFTableCell extends XSLFTextShape
implements TableCell<XSLFShape,
int br = row + (firstRow ? 1 : 0);
int bc = col + (firstCol ? 1 : 0);
- if (bandRow && (br & 1) == 0) {
- tps = TablePartStyle.band1H;
- } else if (bandCol && (bc & 1) == 0) {
- tps = TablePartStyle.band1V;
+ if (bandRow) {
+ if ((br & 1) == 0) {
+ tps = TablePartStyle.band1H;
+ } else {
+ tps = TablePartStyle.band2H;
+ }
+ } else if (bandCol) {
+ if ((bc & 1) == 0) {
+ tps = TablePartStyle.band1V;
+ } else {
+ tps = TablePartStyle.band2V;
+ }
}
}
@@ -734,6 +743,9 @@ public class XSLFTableCell extends XSLFTextShape implements
TableCell<XSLFShape,
@Override
public PaintStyle getFontColor() {
CTTableStyleTextStyle txStyle = getTextStyle();
+ if (!containsColor(txStyle)) {
+ txStyle = getFallbackTextStyle();
+ }
if (txStyle == null) {
// No table styling, so just use the text run output
return super.getFontColor();
@@ -798,11 +810,27 @@ public class XSLFTableCell extends XSLFTextShape
implements TableCell<XSLFShape,
}
}
+ private boolean containsColor(CTTableStyleTextStyle tcTxStyle) {
+ if (tcTxStyle == null) {
+ return false;
+ }
+ if (!tcTxStyle.isSetHslClr() && !tcTxStyle.isSetPrstClr() &&
!tcTxStyle.isSetSchemeClr()
+ && !tcTxStyle.isSetScrgbClr() && !tcTxStyle.isSetSrgbClr()
&& !tcTxStyle.isSetSysClr()) {
+ return false;
+ }
+ return true;
+ }
+
private CTTableStyleTextStyle getTextStyle() {
CTTablePartStyle tps = getTablePartStyle(null);
if (tps == null || !tps.isSetTcTxStyle()) {
- tps = getTablePartStyle(TablePartStyle.wholeTbl);
+ return getFallbackTextStyle();
}
+ return tps.getTcTxStyle();
+ }
+
+ private CTTableStyleTextStyle getFallbackTextStyle() {
+ CTTablePartStyle tps = getTablePartStyle(TablePartStyle.wholeTbl);
return (tps == null) ? null : tps.getTcTxStyle();
}
}
diff --git
a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTable.java
b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTable.java
index 88627ad6a1..827bed7243 100644
--- a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTable.java
+++ b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTable.java
@@ -36,12 +36,8 @@ import java.io.IOException;
import java.util.List;
import org.apache.poi.sl.draw.DrawTableShape;
-import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.sl.usermodel.Slide;
-import org.apache.poi.sl.usermodel.StrokeStyle;
+import org.apache.poi.sl.usermodel.*;
import org.apache.poi.sl.usermodel.TableCell.BorderEdge;
-import org.apache.poi.sl.usermodel.TextParagraph;
-import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.RandomSingleton;
import org.apache.poi.util.TempFile;
import org.apache.poi.xslf.XSLFTestDataSamples;
@@ -362,4 +358,70 @@ class TestXSLFTable {
}
}
-}
\ No newline at end of file
+ private void verifyTableCellStyleColors(XSLFTableCell cell, String text,
Color fontColor, Color fillColor) {
+ assertEquals(text, cell.getText());
+ PaintStyle colorText1 =
cell.getTextParagraphs().get(0).getTextRuns().get(0).getFontColor();
+ assertTrue(colorText1 instanceof PaintStyle.SolidPaint);
+ assertEquals(fontColor,
((PaintStyle.SolidPaint)colorText1).getSolidColor().getColor());
+ assertEquals(fillColor, cell.getFillColor());
+ }
+
+ @Test
+ void testTableCellStyle() throws IOException {
+ XMLSlideShow ppt =
XSLFTestDataSamples.openSampleDocument("table-with-different-font-colors.pptx");
+
+ // First slide: test row-related table styles
+
+ List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();
+ assertEquals(1, shapes.size());
+ assertTrue(shapes.get(0) instanceof XSLFTable);
+ XSLFTable tbl = (XSLFTable)shapes.get(0);
+ assertEquals(4, tbl.getNumberOfColumns());
+ assertEquals(4, tbl.getNumberOfRows());
+ assertNotNull(tbl.getCTTable());
+
+ // Yellow font color due to "first row" table style
+ verifyTableCellStyleColors(tbl.getRows().get(0).getCells().get(0),
"Text 1",
+ new Color(255, 255, 0), new Color(21, 96, 130));
+ // Dark green font color due to direct format
+ verifyTableCellStyleColors(tbl.getRows().get(0).getCells().get(2),
"Text 3",
+ new Color(0, 176, 80), new Color(21, 96, 130));
+ // Grey font color due to "even row" table style + fallback
+ verifyTableCellStyleColors(tbl.getRows().get(1).getCells().get(0),
"Text 5",
+ new Color(119, 119, 119), new Color(204, 210, 216));
+ // Light blue font color due to "odd row" table style
+ verifyTableCellStyleColors(tbl.getRows().get(2).getCells().get(0),
"Text 9",
+ new Color(0, 255, 255), new Color(231, 234, 237));
+ // Red font color due to direct format
+ verifyTableCellStyleColors(tbl.getRows().get(2).getCells().get(2),
"Text 11",
+ new Color(255, 0, 0), new Color(231, 234, 237));
+ // Blue font color due to "last row" table style
+ verifyTableCellStyleColors(tbl.getRows().get(3).getCells().get(0),
"Text 13",
+ new Color(0, 0, 255), new Color(21, 96, 130));
+
+ // Second slide: test column-related table styles
+
+ shapes = ppt.getSlides().get(1).getShapes();
+ assertEquals(1, shapes.size());
+ assertTrue(shapes.get(0) instanceof XSLFTable);
+ tbl = (XSLFTable)shapes.get(0);
+ assertEquals(4, tbl.getNumberOfColumns());
+ assertEquals(4, tbl.getNumberOfRows());
+ assertNotNull(tbl.getCTTable());
+
+ // Green font color due to "first column" table style
+ verifyTableCellStyleColors(tbl.getRows().get(0).getCells().get(0),
"Text 1",
+ new Color(0, 255, 0), new Color(21, 96, 130));
+ // Grey font color due to "even column" table style + fallback
+ verifyTableCellStyleColors(tbl.getRows().get(0).getCells().get(1),
"Text 2",
+ new Color(119, 119, 119), new Color(204, 210, 216));
+ // Light blue font color due to "odd column" table style
+ verifyTableCellStyleColors(tbl.getRows().get(0).getCells().get(2),
"Text 3",
+ new Color(0, 255, 255), new Color(231, 234, 237));
+ // Red font color due to "last column" table style
+ verifyTableCellStyleColors(tbl.getRows().get(0).getCells().get(3),
"Text 4",
+ new Color(255, 0, 0), new Color(21, 96, 130));
+
+ ppt.close();
+ }
+}
diff --git a/test-data/slideshow/table-with-different-font-colors.pptx
b/test-data/slideshow/table-with-different-font-colors.pptx
new file mode 100644
index 0000000000..6272f055eb
Binary files /dev/null and
b/test-data/slideshow/table-with-different-font-colors.pptx differ
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]