You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2026/04/07 11:09:23 UTC
(poi) branch trunk updated: Fix Row.setRowStyle() not propagating styles to cells in XSSFCell and SXSSFCell (#1031)
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 b5d2426ca8 Fix Row.setRowStyle() not propagating styles to cells in XSSFCell and SXSSFCell (#1031)
b5d2426ca8 is described below
commit b5d2426ca8c6879c4e84e4050f69d77d554e8772
Author: Md Fakhrul Islam <fa...@gmail.com>
AuthorDate: Tue Apr 7 17:09:18 2026 +0600
Fix Row.setRowStyle() not propagating styles to cells in XSSFCell and SXSSFCell (#1031)
* Fix row style propagation bug in XSSFCell and SXSSFCell
* Fix HSSF style inheritance and update XSSF tests
- Add fallback to column and row styles for unstyled HSSF cells
- Convert XSSF workbook text fixtures to use try-with-resources
- Clean up test formatting and static JUnit assertions
---
.../org/apache/poi/xssf/streaming/SXSSFCell.java | 40 +++++++---
.../org/apache/poi/xssf/usermodel/XSSFCell.java | 33 +++++---
.../apache/poi/xssf/streaming/TestSXSSFRow.java | 91 ++++++++++++++++++++++
.../org/apache/poi/xssf/usermodel/TestXSSFRow.java | 80 +++++++++++++++++++
.../org/apache/poi/hssf/usermodel/HSSFCell.java | 18 ++++-
.../apache/poi/hssf/usermodel/TestHSSFCell.java | 61 +++++++++++++++
.../org/apache/poi/ss/usermodel/BaseTestSheet.java | 4 +-
7 files changed, 300 insertions(+), 27 deletions(-)
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFCell.java
index c120e05a8a..43f1334e73 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFCell.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/streaming/SXSSFCell.java
@@ -584,7 +584,10 @@ public class SXSSFCell extends CellBase {
}
/**
- * Return the cell's style.
+ * Return the cell's style. Since POI v5.2.3, this returns the column style if the
+ * cell has no style of its own. If no column default style is set, the row default style is checked.
+ * This method has always fallen back to return the default style
+ * if there is no other style to return.
*
* @return the cell's style. Never null. Default cell style has zero index and can be obtained as
* <code>workbook.getCellStyleAt(0)</code>
@@ -593,24 +596,37 @@ public class SXSSFCell extends CellBase {
@Override
public CellStyle getCellStyle()
{
- if (_style == null) {
- CellStyle style = getDefaultCellStyleFromColumn();
- if (style == null) {
- SXSSFWorkbook wb = getSheet().getWorkbook();
- style = wb.getCellStyleAt(0);
- }
- _style = style;
+ if (_style != null) {
+ return _style;
+ }
+ CellStyle style = getDefaultCellStyleFromColumn();
+ if (style == null) {
+ style = getDefaultCellStyleFromRow();
+ }
+ if (style == null) {
+ SXSSFWorkbook wb = getSheet().getWorkbook();
+ style = wb.getCellStyleAt(0);
}
- return _style;
+ return style;
}
private CellStyle getDefaultCellStyleFromColumn() {
- CellStyle style = null;
SXSSFSheet sheet = getSheet();
if (sheet != null) {
- style = sheet.getColumnStyle(getColumnIndex());
+ int idx = sheet._sh.getColumnHelper().getColDefaultStyle(getColumnIndex());
+ if (idx >= 0) {
+ return getSheet().getWorkbook().getCellStyleAt(idx);
+ }
}
- return style;
+ return null;
+ }
+
+ private CellStyle getDefaultCellStyleFromRow() {
+ SXSSFRow row = (SXSSFRow) getRow();
+ if (row != null && row.isFormatted()) {
+ return row.getRowStyle();
+ }
+ return null;
}
/**
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java
index d9da22cefc..d0f56ed0d8 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFCell.java
@@ -572,6 +572,12 @@ public final class XSSFCell extends CellBase {
if (style == null) {
style = getDefaultCellStyleFromColumn();
}
+ if (style == null) {
+ style = getDefaultCellStyleFromRow();
+ }
+ if (style == null && _stylesSource.getNumCellStyles() > 0) {
+ style = _stylesSource.getStyleAt(0);
+ }
return style;
}
@@ -587,24 +593,27 @@ public final class XSSFCell extends CellBase {
}
private XSSFCellStyle getDefaultCellStyleFromColumn() {
- XSSFCellStyle style = null;
XSSFSheet sheet = getSheet();
if (sheet != null) {
- style = (XSSFCellStyle) sheet.getColumnStyle(getColumnIndex());
+ int idx = sheet.getColumnHelper().getColDefaultStyle(getColumnIndex());
+ if (idx >= 0) {
+ return _stylesSource.getStyleAt(idx);
+ }
}
- return style;
+ return null;
+ }
+
+ private XSSFCellStyle getDefaultCellStyleFromRow() {
+ XSSFRow row = getRow();
+ if (row != null && row.isFormatted()) {
+ return row.getRowStyle();
+ }
+ return null;
}
protected void applyDefaultCellStyleIfNecessary() {
- XSSFCellStyle style = getExplicitCellStyle();
- if (style == null) {
- XSSFSheet sheet = getSheet();
- if (sheet != null) {
- XSSFCellStyle defaultStyle = getDefaultCellStyleFromColumn();
- if (defaultStyle != null) {
- setCellStyle(defaultStyle);
- }
- }
+ if (getExplicitCellStyle() == null) {
+ setCellStyle(getCellStyle());
}
}
diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFRow.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFRow.java
index 0059648487..cdf178017c 100644
--- a/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFRow.java
+++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFRow.java
@@ -20,7 +20,14 @@
package org.apache.poi.xssf.streaming;
import org.apache.poi.ss.tests.usermodel.BaseTestXRow;
+import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.SXSSFITestDataProvider;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFFont;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -28,6 +35,9 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
/**
* Tests for XSSFRow
@@ -66,4 +76,85 @@ public final class TestSXSSFRow extends BaseTestXRow {
}
}
+ @Test
+ void testSetRowStylePropagatedToCells() throws IOException {
+ try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
+ SXSSFSheet sheet = wb.createSheet("test");
+
+ // create a bold style
+ XSSFCellStyle boldStyle = (XSSFCellStyle) wb.createCellStyle();
+ XSSFFont boldFont = (XSSFFont) wb.createFont();
+ boldFont.setBold(true);
+ boldStyle.setFont(boldFont);
+
+ // apply style to row, then create cells
+ SXSSFRow row = sheet.createRow(0);
+ row.setRowStyle(boldStyle);
+
+ SXSSFCell cell0 = row.createCell(0);
+ cell0.setCellValue("Header A");
+ SXSSFCell cell1 = row.createCell(1);
+ cell1.setCellValue("Header B");
+
+ // cells without explicit style should inherit the row style via getCellStyle()
+ CellStyle cellStyle0 = cell0.getCellStyle();
+ assertNotNull(cellStyle0);
+ assertTrue(wb.getFontAt(cellStyle0.getFontIndex()).getBold(),
+ "cell should inherit bold font from row style");
+
+ CellStyle cellStyle1 = cell1.getCellStyle();
+ assertNotNull(cellStyle1);
+ assertTrue(wb.getFontAt(cellStyle1.getFontIndex()).getBold(),
+ "cell should inherit bold font from row style");
+
+ // a cell with an explicit style should NOT be overridden by row style
+ CellStyle plainStyle = wb.createCellStyle();
+ SXSSFCell cell2 = row.createCell(2);
+ cell2.setCellStyle(plainStyle);
+ cell2.setCellValue("Plain");
+
+ CellStyle cellStyle2 = cell2.getCellStyle();
+ assertFalse(wb.getFontAt(cellStyle2.getFontIndex()).getBold(),
+ "cell with explicit non-bold style should remain non-bold");
+ }
+ }
+
+ @Test
+ void testSetRowStylePropagatedAfterWrite() throws IOException {
+ try (SXSSFWorkbook wb = new SXSSFWorkbook()) {
+ SXSSFSheet sheet = wb.createSheet("test");
+
+ // create a bold style
+ XSSFCellStyle boldStyle = (XSSFCellStyle) wb.createCellStyle();
+ XSSFFont boldFont = (XSSFFont) wb.createFont();
+ boldFont.setBold(true);
+ boldStyle.setFont(boldFont);
+
+ // apply style to row, then create cells
+ SXSSFRow row = sheet.createRow(0);
+ row.setRowStyle(boldStyle);
+ row.createCell(0).setCellValue("Column A");
+ row.createCell(1).setCellValue("Column B");
+ row.createCell(2).setCellValue("Column C");
+
+ // write and read back — SXSSFITestDataProvider returns XSSFWorkbook
+ XSSFWorkbook wb2 = SXSSFITestDataProvider.instance.writeOutAndReadBack(wb);
+
+ XSSFSheet sheet2 = wb2.getSheet("test");
+ XSSFRow row2 = sheet2.getRow(0);
+ assertNotNull(row2);
+
+ for (int i = 0; i < 3; i++) {
+ XSSFCell cell = row2.getCell(i);
+ assertNotNull(cell, "cell " + i + " should exist after read-back");
+ XSSFCellStyle style = cell.getCellStyle();
+ assertNotNull(style, "cell " + i + " should have a style after read-back");
+ assertTrue(wb2.getFontAt(style.getFontIndex()).getBold(),
+ "cell " + i + " should be bold after write/read-back");
+ }
+
+ wb2.close();
+ }
+ }
+
}
diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFRow.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFRow.java
index 90d04efd6c..22cf5f45d7 100644
--- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFRow.java
+++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFRow.java
@@ -485,6 +485,86 @@ public final class TestXSSFRow extends BaseTestXRow {
}
}
+ @Test
+ void testSetRowStylePropagatedToCells() throws IOException {
+ try (XSSFWorkbook workbook = new XSSFWorkbook()) {
+ final XSSFSheet sheet = workbook.createSheet("test");
+
+ // create a bold style
+ XSSFCellStyle boldStyle = workbook.createCellStyle();
+ XSSFFont boldFont = workbook.createFont();
+ boldFont.setBold(true);
+ boldStyle.setFont(boldFont);
+
+ // apply style to row, then create cells
+ final XSSFRow row = sheet.createRow(0);
+ row.setRowStyle(boldStyle);
+
+ XSSFCell cell0 = row.createCell(0);
+ cell0.setCellValue("Header A");
+ XSSFCell cell1 = row.createCell(1);
+ cell1.setCellValue("Header B");
+
+ // cells without explicit style should inherit the row style via getCellStyle()
+ XSSFCellStyle cellStyle0 = cell0.getCellStyle();
+ assertNotNull(cellStyle0);
+ assertTrue(workbook.getFontAt(cellStyle0.getFontIndex()).getBold(),
+ "cell should inherit bold font from row style");
+
+ XSSFCellStyle cellStyle1 = cell1.getCellStyle();
+ assertNotNull(cellStyle1);
+ assertTrue(workbook.getFontAt(cellStyle1.getFontIndex()).getBold(),
+ "cell should inherit bold font from row style");
+
+ // a cell with an explicit style should NOT be overridden by row style
+ XSSFCellStyle plainStyle = workbook.createCellStyle();
+ XSSFCell cell2 = row.createCell(2);
+ cell2.setCellStyle(plainStyle);
+ cell2.setCellValue("Plain");
+
+ XSSFCellStyle cellStyle2 = cell2.getCellStyle();
+ assertFalse(workbook.getFontAt(cellStyle2.getFontIndex()).getBold(),
+ "cell with explicit non-bold style should remain non-bold");
+ }
+ }
+
+ @Test
+ void testSetRowStylePropagatedAfterWrite() throws IOException {
+ try (XSSFWorkbook workbook = new XSSFWorkbook()) {
+ final XSSFSheet sheet = workbook.createSheet("test");
+
+ // create a bold style
+ XSSFCellStyle boldStyle = workbook.createCellStyle();
+ XSSFFont boldFont = workbook.createFont();
+ boldFont.setBold(true);
+ boldStyle.setFont(boldFont);
+
+ // apply style to row, then create cells
+ final XSSFRow row = sheet.createRow(0);
+ row.setRowStyle(boldStyle);
+ row.createCell(0, CellType.STRING).setCellValue("Column A");
+ row.createCell(1, CellType.STRING).setCellValue("Column B");
+ row.createCell(2, CellType.STRING).setCellValue("Column C");
+
+ // write and read back — exercises onDocumentWrite() ->
+ // applyDefaultCellStyleIfNecessary()
+ try (XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook)) {
+ XSSFSheet sheet2 = wb2.getSheet("test");
+ XSSFRow row2 = sheet2.getRow(0);
+ assertNotNull(row2);
+
+ for (int i = 0; i < 3; i++) {
+ XSSFCell cell = row2.getCell(i);
+ assertNotNull(cell, "cell " + i + " should exist after read-back");
+ XSSFCellStyle style = cell.getCellStyle();
+ assertNotNull(style, "cell " + i + " should have a style after read-back");
+ assertTrue(wb2.getFontAt(style.getFontIndex()).getBold(),
+ "cell " + i + " should be bold after write/read-back");
+ }
+ }
+ }
+ }
+
private void fillData(int startAtRow, Sheet sheet) {
Row header = sheet.createRow(0);
for (int rownum = startAtRow; rownum < 2; rownum++) {
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java
index b4d5f4b62c..4e46848e0b 100644
--- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java
+++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java
@@ -978,7 +978,8 @@ public class HSSFCell extends CellBase {
/**
* get the style for the cell. This is a reference to a cell style contained in the workbook
- * object.
+ * object. If the cell does not have an explicit style assigned, this method will fall back
+ * to returning the column or row style (if any).
* @see org.apache.poi.hssf.usermodel.HSSFWorkbook#getCellStyleAt(int)
*/
@Override
@@ -986,6 +987,21 @@ public class HSSFCell extends CellBase {
{
short styleIndex=_record.getXFIndex();
ExtendedFormatRecord xf = _book.getWorkbook().getExFormatAt(styleIndex);
+
+ if (styleIndex == 0x0f) {
+ // Fallback to column style
+ HSSFCellStyle colStyle = _sheet.getColumnStyle(getColumnIndex());
+ if (colStyle != null) {
+ return colStyle;
+ }
+
+ // Fallback to row style
+ HSSFCellStyle rowStyle = getRow().getRowStyle();
+ if (rowStyle != null) {
+ return rowStyle;
+ }
+ }
+
return new HSSFCellStyle(styleIndex, xf, _book);
}
diff --git a/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFCell.java b/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFCell.java
index 48ef715a92..7d1b67f2be 100644
--- a/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFCell.java
+++ b/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFCell.java
@@ -441,4 +441,65 @@ final class TestHSSFCell extends BaseTestCell {
}
}
}
+
+ @Test
+ void testGetCellStyleFallbackToColumnStyle() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFSheet sheet = wb.createSheet();
+ HSSFRow row = sheet.createRow(0);
+ HSSFCell cell = row.createCell(0);
+
+ HSSFCellStyle colStyle = wb.createCellStyle();
+ colStyle.setFillBackgroundColor((short) 10);
+ sheet.setDefaultColumnStyle(0, colStyle);
+
+ assertEquals(colStyle, cell.getCellStyle(), "Should fallback to column style");
+ }
+ }
+
+ @Test
+ void testGetCellStyleFallbackToRowStyle() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFSheet sheet = wb.createSheet();
+ HSSFRow row = sheet.createRow(0);
+ HSSFCell cell = row.createCell(0);
+
+ HSSFCellStyle rowStyle = wb.createCellStyle();
+ rowStyle.setFillBackgroundColor((short) 10);
+ row.setRowStyle(rowStyle);
+
+ assertEquals(rowStyle, cell.getCellStyle(), "Should fallback to row style");
+ }
+ }
+
+ @Test
+ void testGetCellStyleNoFallbackWhenExplicitStyleAssigned() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFSheet sheet = wb.createSheet();
+ HSSFRow row = sheet.createRow(0);
+ HSSFCell cell = row.createCell(0);
+
+ HSSFCellStyle rowStyle = wb.createCellStyle();
+ rowStyle.setFillBackgroundColor((short) 10);
+ row.setRowStyle(rowStyle);
+
+ HSSFCellStyle explicitStyle = wb.createCellStyle();
+ explicitStyle.setFillBackgroundColor((short) 20);
+ cell.setCellStyle(explicitStyle);
+
+ assertEquals(explicitStyle, cell.getCellStyle(), "Should use explicit cell style, not row style");
+ }
+ }
+
+ @Test
+ void testGetCellStyleNoRowOrColumnStyle() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFSheet sheet = wb.createSheet();
+ HSSFRow row = sheet.createRow(0);
+ HSSFCell cell = row.createCell(0);
+
+ HSSFCellStyle defaultStyle = cell.getCellStyle();
+ assertEquals(0x0f, defaultStyle.getIndex(), "Should return default style when no fallback exists");
+ }
+ }
}
diff --git a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java
index 61aceb97cb..df303b85d8 100644
--- a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java
+++ b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java
@@ -701,8 +701,8 @@ public abstract class BaseTestSheet {
Cell cell = r0.createCell(0);
CellStyle style2 = cell.getCellStyle();
assertNotNull(style2);
- //current implementations mean that cells inherit column style but not row style
- assertNotEquals(style.getIndex(), style2.getIndex(), "style should not match");
+ //cells should now inherit row style (just like column style)
+ assertEquals(style.getIndex(), style2.getIndex(), "style should match");
try (Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb)) {
Sheet wb2Sheet = wb2.getSheetAt(0);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org