Bug 56525

Summary: XSSFSheet.getColumnStyle doesn't conform to Sheet.getColumnStyle API doc
Product: POI Reporter: Tim Meagher <tmeagher>
Component: XSSFAssignee: POI Developers List <dev>
Status: NEW ---    
Severity: normal    
Priority: P2    
Version: 3.8-FINAL   
Target Milestone: ---   
Hardware: PC   
OS: All   
Attachments: Fix XSSFSheet.getColumnStyle to abide to javadoc
Fix XSSFSheet.getColumnStyle to abide to javadoc

Description Tim Meagher 2014-05-14 17:32:01 UTC
NOTE: Haven't tested against newest version (or maybe I did but can't recall), but couldn't find anything in changelog to indicate it's been fixed.

XSSFSheet.getColumnStyle behaves differently than the corresponding method on HSSFSheet & what the API doc for Sheet says it should do.

The javadoc for org.apache.poi.ss.usermodel.Sheet states for getColumnStyle(int):

"Returns the CellStyle that applies to the given (0 based) column, or null if no style has been set for that column"

For XSSFSheet, however, if no cell style has been set for the column, then a new style is created and returned.
HSSFSheet conforms to the API doc, whereas XSSFSheet does not.

Reasoning/Why this causes problems:
Essentially, I want to use a Excel file as a "template" (though not a xlt/xltx, just a normal xls/xlsx) and write to a new spreadsheet, just taking the formatting from the template. If the "template" spreadsheet contains cell formatting, I want to preserve that formatting. In order to do this, I need to check if there is a style applied on the existing cell, then row, then column - although I guess the row then column ordering doesn't matter.
According to the API, I should just be able to check if, in the template, the "template"'s Sheet.getColumnStyle(col) returns null.
However if it came from an XLSX format, then the XSSFSheet will always return a style, which I then have to compare against what is returned from Workbook.createCellStyle to see if this is different from the default before working out if there really was a cell style applied for this column.

Also, it just breaks the API contract doesn't it?
Comment 1 Tim Meagher 2014-05-14 17:37:32 UTC
*** Bug 56524 has been marked as a duplicate of this bug. ***
Comment 2 Javen O'Neal 2016-10-18 16:35:52 UTC
Correct. XSSFSheet#getColumnStyle returns the default column style rather than returning null.
As a workaround, you could check of the index of the returned style == 0. Unfortunately, there is a setDefaultColumnStyle method in the Sheet interface but not a getDefaultColumnStyle method (though ColumnHelper offers something similar). Furthermore, I'm unsure if XSSFSheet.getColumnStyle on an unstyled column returns the correct default column style after setDefaultColumnStyle has been called.

> /**
>  * Returns the CellStyle that applies to the given
>  *  (0 based) column, or null if no style has been
>  *  set for that column
>  */
> @Override
> public CellStyle getColumnStyle(int column) {
>     int idx = columnHelper.getColDefaultStyle(column);
>     return getWorkbook().getCellStyleAt((short)(idx == -1 ? 0 : idx));
> }

> /**
>  * Returns the HSSFCellStyle that applies to the given
>  * (0 based) column, or null if no style has been
>  * set for that column
>  */
> @Override
> public HSSFCellStyle getColumnStyle(int column) {
>     short styleIndex = _sheet.getXFIndexForColAt((short) column);
>     if (styleIndex == 0xf) {
>         // None set
>         return null;
>     }
>     ExtendedFormatRecord xf = _book.getExFormatAt(styleIndex);
>     return new HSSFCellStyle(styleIndex, xf, _book);
> }
Comment 3 Javen O'Neal 2016-10-18 16:38:57 UTC
Created attachment 34385 [details]
Fix XSSFSheet.getColumnStyle to abide to javadoc
Comment 4 Javen O'Neal 2016-10-19 07:26:50 UTC
Created attachment 34389 [details]
Fix XSSFSheet.getColumnStyle to abide to javadoc

I'm a bit hesitant to commit this because it does change the current behavior, even if it is inconsistent with the javadoc and with HSSF.