From ee866292d9632903ecd80fb6e27435c598e3ed50 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Fri, 8 Jul 2011 14:58:08 +0000 Subject: [PATCH] Fix bug #51469 - XSSF support for row styles, to match existing HSSF functionality git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1144348 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../apache/poi/hssf/usermodel/HSSFRow.java | 7 +++ src/java/org/apache/poi/ss/usermodel/Row.java | 20 +++++++- .../apache/poi/xssf/streaming/SXSSFRow.java | 42 ++++++++++++++-- .../apache/poi/xssf/streaming/SXSSFSheet.java | 4 ++ .../apache/poi/xssf/usermodel/XSSFRow.java | 49 +++++++++++++++++++ .../apache/poi/ss/usermodel/BaseTestRow.java | 38 ++++++++++++++ 7 files changed, 156 insertions(+), 5 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index f3d998c96..4e9eb3789 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 51469 - XSSF support for row styles, to match existing HSSF functionality 51476 - Correct XSSF cell formatting in HTML export 51486 - XWPF support for adding new footnotes 48065 - Problems with save output of HWPF (losing formatting) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java index 4d8102867..2397129bf 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java @@ -24,6 +24,7 @@ import org.apache.poi.hssf.record.CellValueRecordInterface; import org.apache.poi.hssf.record.ExtendedFormatRecord; import org.apache.poi.hssf.record.RowRecord; import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.SpreadsheetVersion; @@ -593,6 +594,12 @@ public final class HSSFRow implements Row { row.setFormatted(true); row.setXFIndex(style.getIndex()); } + /** + * Applies a whole-row cell styling to the row. + */ + public void setRowStyle(CellStyle style) { + setRowStyle((HSSFCellStyle)style); + } /** * @return cell iterator of the physically defined cells. diff --git a/src/java/org/apache/poi/ss/usermodel/Row.java b/src/java/org/apache/poi/ss/usermodel/Row.java index a1db2fb36..5d93f6492 100644 --- a/src/java/org/apache/poi/ss/usermodel/Row.java +++ b/src/java/org/apache/poi/ss/usermodel/Row.java @@ -17,7 +17,6 @@ package org.apache.poi.ss.usermodel; -import java.lang.Iterable; import java.util.Iterator; /** @@ -177,6 +176,25 @@ public interface Row extends Iterable { */ float getHeightInPoints(); + /** + * Is this row formatted? Most aren't, but some rows + * do have whole-row styles. For those that do, you + * can get the formatting from {@link #getRowStyle()} + */ + boolean isFormatted(); + + /** + * Returns the whole-row cell styles. Most rows won't + * have one of these, so will return null. Call + * {@link #isFormatted()} to check first. + */ + CellStyle getRowStyle(); + + /** + * Applies a whole-row cell styling to the row. + */ + void setRowStyle(CellStyle style); + /** * @return Cell iterator of the physically defined cells. Note element 4 may * actually be row cell depending on how many are defined! diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java index ad7383661..52735db7f 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java @@ -17,13 +17,15 @@ package org.apache.poi.xssf.streaming; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; - import java.util.Iterator; import java.util.NoSuchElementException; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; + /** * Streaming version of XSSFRow implementing the "BigGridDemo" strategy. * @@ -34,6 +36,7 @@ public class SXSSFRow implements Row SXSSFSheet _sheet; SXSSFCell[] _cells; int _maxColumn=-1; + short _style=-1; short _height=-1; boolean _zHeight = false; @@ -330,6 +333,37 @@ public class SXSSFRow implements Row { return (float)(_height==-1?getSheet().getDefaultRowHeightInPoints():(float)_height/20.0); } + + /** + * Is this row formatted? Most aren't, but some rows + * do have whole-row styles. For those that do, you + * can get the formatting from {@link #getRowStyle()} + */ + public boolean isFormatted() { + return _style > -1; + } + /** + * Returns the whole-row cell style. Most rows won't + * have one of these, so will return null. Call + * {@link #isFormatted()} to check first. + */ + public CellStyle getRowStyle() { + if(!isFormatted()) return null; + + return getSheet().getWorkbook().getCellStyleAt(_style); + } + + /** + * Applies a whole-row cell styling to the row. + */ + public void setRowStyle(CellStyle style) { + if(style == null) { + _style = -1; + return; + } else { + _style = style.getIndex(); + } + } /** * @return Cell iterator of the physically defined cells. Note element 4 may diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java index bb5d8ac81..d19770a91 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java @@ -1317,6 +1317,10 @@ public class SXSSFSheet implements Sheet, Cloneable _out.write(" customHeight=\"true\" ht=\""+row.getHeightInPoints()+"\""); if(row.getZeroHeight()) _out.write(" hidden=\"true\""); + if(row.isFormatted()) { + _out.write(" s=\"" + row._style + "\""); + _out.write(" customFormat=\"1\""); + } _out.write(">\n"); this._rownum = rownum; _rowContainedNullCells=false; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java index 2fbcd19f1..9ed76da09 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java @@ -22,12 +22,14 @@ import java.util.TreeMap; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellReference; import org.apache.poi.util.Internal; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import org.apache.poi.xssf.model.CalculationChain; +import org.apache.poi.xssf.model.StylesTable; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; @@ -355,6 +357,53 @@ public class XSSFRow implements Row, Comparable { } + /** + * Is this row formatted? Most aren't, but some rows + * do have whole-row styles. For those that do, you + * can get the formatting from {@link #getRowStyle()} + */ + public boolean isFormatted() { + return _row.isSetS(); + } + /** + * Returns the whole-row cell style. Most rows won't + * have one of these, so will return null. Call + * {@link #isFormatted()} to check first. + */ + public XSSFCellStyle getRowStyle() { + if(!isFormatted()) return null; + + StylesTable stylesSource = getSheet().getWorkbook().getStylesSource(); + if(stylesSource.getNumCellStyles() > 0) { + return stylesSource.getStyleAt((int)_row.getS()); + } else { + return null; + } + } + + /** + * Applies a whole-row cell styling to the row. + * If the value is null then the style information is removed, + * causing the cell to used the default workbook style. + */ + public void setRowStyle(CellStyle style) { + if(style == null) { + if(_row.isSetS()) { + _row.unsetS(); + _row.unsetCustomFormat(); + } + } else { + StylesTable styleSource = getSheet().getWorkbook().getStylesSource(); + + XSSFCellStyle xStyle = (XSSFCellStyle)style; + xStyle.verifyBelongsToStylesSource(styleSource); + + long idx = styleSource.putStyle(xStyle); + _row.setS(idx); + _row.setCustomFormat(true); + } + } + /** * Remove the Cell from this row. * diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestRow.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestRow.java index 51f8db91b..da40cd076 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestRow.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestRow.java @@ -386,4 +386,42 @@ public abstract class BaseTestRow extends TestCase { assertTrue(cell2 == it.next()); assertEquals(Cell.CELL_TYPE_STRING, cell5.getCellType()); } + + public void testRowStyle() { + Workbook workbook = _testDataProvider.createWorkbook(); + Sheet sheet = workbook.createSheet("test"); + Row row1 = sheet.createRow(0); + Row row2 = sheet.createRow(1); + + // Won't be styled currently + assertEquals(false, row1.isFormatted()); + assertEquals(false, row2.isFormatted()); + assertEquals(null, row1.getRowStyle()); + assertEquals(null, row2.getRowStyle()); + + // Style one + CellStyle style = workbook.createCellStyle(); + style.setDataFormat((short)4); + row2.setRowStyle(style); + + // Check + assertEquals(false, row1.isFormatted()); + assertEquals(true, row2.isFormatted()); + assertEquals(null, row1.getRowStyle()); + assertEquals(style, row2.getRowStyle()); + + // Save, load and re-check + workbook = _testDataProvider.writeOutAndReadBack(workbook); + sheet = workbook.getSheetAt(0); + + row1 = sheet.getRow(0); + row2 = sheet.getRow(1); + style = workbook.getCellStyleAt(style.getIndex()); + + assertEquals(false, row1.isFormatted()); + assertEquals(true, row2.isFormatted()); + assertEquals(null, row1.getRowStyle()); + assertEquals(style, row2.getRowStyle()); + assertEquals(4, style.getDataFormat()); + } }