Skip to content

Fix Row.setRowStyle() not propagating styles to cells in XSSFCell and SXSSFCell#1031

Open
fakhrulsojib wants to merge 2 commits intoapache:trunkfrom
fakhrulsojib:bug-69973-propagate-row-style
Open

Fix Row.setRowStyle() not propagating styles to cells in XSSFCell and SXSSFCell#1031
fakhrulsojib wants to merge 2 commits intoapache:trunkfrom
fakhrulsojib:bug-69973-propagate-row-style

Conversation

@fakhrulsojib
Copy link

Summary

Row.setRowStyle() does not propagate styles to cells via Cell.getCellStyle(). This is a regression from POI 3.17 affecting both XSSFCell and SXSSFCell.

Bugzilla: https://bz.apache.org/bugzilla/show_bug.cgi?id=69973
Related: Bug 66679, Bug 56011

Root Cause

Three issues in XSSFCell.getCellStyle() (and mirrored in SXSSFCell):

  1. Fallback chain is explicit → column — row is never checked
  2. getDefaultCellStyleFromColumn() uses XSSFSheet.getColumnStyle() which converts "no column style" (-1) into the default style (0), so it never returns null — blocking any further fallback
  3. applyDefaultCellStyleIfNecessary() (called during workbook.write()) only checks column style

Changes

XSSFCell.java / SXSSFCell.java:

  • getCellStyle() — new 4-step fallback: explicit → column → row → default(0)
  • getDefaultCellStyleFromColumn() — use ColumnHelper.getColDefaultStyle() directly, return null when no explicit column style
  • getDefaultCellStyleFromRow() — new helper using row.isFormatted() / row.getRowStyle()
  • applyDefaultCellStyleIfNecessary() — simplified to reuse getCellStyle() fallback chain

TestXSSFRow.java / TestSXSSFRow.java:

  • testSetRowStylePropagatedToCells — verifies in-memory inheritance + explicit style not overridden
  • testSetRowStylePropagatedAfterWrite — verifies style persistence through write/read-back cycle

Test Results

Suite Tests Result
TestXSSFRow 28 (26 + 2 new)
TestXSSFCell 85 ✅ No regressions
TestSXSSFRow 16 (14 + 2 new)
TestSXSSFCell 56 ✅ No regressions

@fakhrulsojib fakhrulsojib force-pushed the bug-69973-propagate-row-style branch from 19a9abe to 3e4aac4 Compare March 12, 2026 11:23
@pjfanning
Copy link
Member

pjfanning commented Mar 12, 2026

@fakhrulsojib don't squash your commits. I can squash them when the PR is merged.
The advantage to my approach is that I can see your individual commits and don't have to re-read the entire PR changeset every time you make a small change.

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.*;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use explicit imports, not wildcards

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use explicit imports.

@pjfanning
Copy link
Member

One test is broken.

Test defaultRowStyle() FAILED

  org.opentest4j.AssertionFailedError: style should match ==> expected: <21> but was: <15>

- 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
@fakhrulsojib fakhrulsojib force-pushed the bug-69973-propagate-row-style branch from b07c8e5 to 7e69b48 Compare March 12, 2026 14:30
@fakhrulsojib
Copy link
Author

@pjfanning ,

My bad — forgot to build the full project before pushing.
Fixed now. Also updated HSSFCell to match the pattern used by the others.

Sorry for the two force pushes too. Bad habit :(

@fakhrulsojib fakhrulsojib requested a review from pjfanning March 12, 2026 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants