From 3e4aac476773763cc8f6186c485093e999ec2881 Mon Sep 17 00:00:00 2001 From: fakhrulsojib Date: Wed, 11 Mar 2026 18:38:20 +0600 Subject: [PATCH 1/2] Fix row style propagation bug in XSSFCell and SXSSFCell --- .../apache/poi/xssf/streaming/SXSSFCell.java | 40 ++++++--- .../apache/poi/xssf/usermodel/XSSFCell.java | 33 ++++--- .../poi/xssf/streaming/TestSXSSFRow.java | 90 ++++++++++++++++++- .../poi/xssf/usermodel/TestXSSFRow.java | 82 +++++++++++++++++ .../poi/ss/usermodel/BaseTestSheet.java | 4 +- 5 files changed, 222 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 c120e05a8a6..43f1334e73b 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 void setCellStyle(CellStyle style) } /** - * 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 * workbook.getCellStyleAt(0) @@ -593,24 +596,37 @@ public void setCellStyle(CellStyle style) @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 d9da22cefc2..d0f56ed0d8d 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 XSSFCellStyle getCellStyle() { 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 @@ private XSSFCellStyle getExplicitCellStyle() { } 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 00596484876..08974e0d2dd 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,14 +20,21 @@ 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; import java.io.IOException; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; /** * Tests for XSSFRow @@ -66,4 +73,85 @@ void testCellColumn() throws IOException { } } + @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 90d04efd6cd..a35736d8da8 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 @@ -500,4 +500,86 @@ private void writeToFile(Workbook wb) throws IOException { wb.write(fileOut); } } + + @Test + void testSetRowStylePropagatedToCells() throws IOException { + final 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"); + + workbook.close(); + } + + @Test + void testSetRowStylePropagatedAfterWrite() throws IOException { + final 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() + XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook); + workbook.close(); + + 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/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestSheet.java index 61aceb97cba..df303b85d81 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 @@ protected void defaultRowStyle() throws IOException { 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); From 7e69b484d8f52f53ec6fa71f0c247c9dec9a8ea2 Mon Sep 17 00:00:00 2001 From: "Md Fakhrul Islam (Sojib)" Date: Thu, 12 Mar 2026 19:18:53 +0600 Subject: [PATCH 2/2] 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 --- .../poi/xssf/streaming/TestSXSSFRow.java | 5 +- .../poi/xssf/usermodel/TestXSSFRow.java | 162 +++++++++--------- .../apache/poi/hssf/usermodel/HSSFCell.java | 18 +- .../poi/hssf/usermodel/TestHSSFCell.java | 61 +++++++ 4 files changed, 162 insertions(+), 84 deletions(-) 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 08974e0d2dd..cdf178017c6 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 @@ -34,7 +34,10 @@ import java.io.IOException; -import static org.junit.jupiter.api.Assertions.*; +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 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 a35736d8da8..22cf5f45d72 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 @@ void duplicateRows() throws IOException { } } + @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++) { @@ -500,86 +580,4 @@ private void writeToFile(Workbook wb) throws IOException { wb.write(fileOut); } } - - @Test - void testSetRowStylePropagatedToCells() throws IOException { - final 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"); - - workbook.close(); - } - - @Test - void testSetRowStylePropagatedAfterWrite() throws IOException { - final 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() - XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(workbook); - workbook.close(); - - 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/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFCell.java index b4d5f4b62ca..4e46848e0b4 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 void setCellStyle(HSSFCellStyle style) { /** * 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 HSSFCellStyle getCellStyle() { 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 48ef715a929..7d1b67f2be0 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 @@ void setFillForegroundColor() throws IOException { } } } + + @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"); + } + } }