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]

Reply via email to