From: PJ Fanning Date: Fri, 1 Jul 2022 13:14:52 +0000 (+0000) Subject: [bug-51037] apply default column style if no style set X-Git-Tag: REL_5_2_3~212 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=86cc8d1b4b4e84470d45a67a4abb7a034612fd6a;p=poi.git [bug-51037] apply default column style if no style set git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1902391 13f79535-47bb-0310-9956-ffa450edef68 --- 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 84b8006457..dd96f37256 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 @@ -576,14 +576,27 @@ public class SXSSFCell extends CellBase { @Override public CellStyle getCellStyle() { - if(_style == null){ - SXSSFWorkbook wb = (SXSSFWorkbook)getRow().getSheet().getWorkbook(); - return wb.getCellStyleAt(0); + if (_style == null) { + CellStyle style = getDefaultCellStyleFromColumn(); + if (style == null) { + SXSSFWorkbook wb = getSheet().getWorkbook(); + style = wb.getCellStyleAt(0); + } + return style; } else { return _style; } } + private CellStyle getDefaultCellStyleFromColumn() { + CellStyle style = null; + SXSSFSheet sheet = getSheet(); + if (sheet != null) { + style = sheet.getColumnStyle(getColumnIndex()); + } + return style; + } + /** * {@inheritDoc} */ 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 7ec3020bda..23e33a2497 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 @@ -549,20 +549,55 @@ public final class XSSFCell 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. */ @Override public XSSFCellStyle getCellStyle() { + XSSFCellStyle style = getExplicitCellStyle(); + if (style == null) { + style = getDefaultCellStyleFromColumn(); + } + return style; + } + + private XSSFCellStyle getExplicitCellStyle() { + XSSFCellStyle style = null; + if(_stylesSource.getNumCellStyles() > 0) { + if (_cell.isSetS()) { + long idx = _cell.getS(); + style = _stylesSource.getStyleAt(Math.toIntExact(idx)); + } + } + return style; + } + + private XSSFCellStyle getDefaultCellStyleFromColumn() { XSSFCellStyle style = null; - if(_stylesSource.getNumCellStyles() > 0){ - long idx = _cell.isSetS() ? _cell.getS() : 0; - style = _stylesSource.getStyleAt(Math.toIntExact(idx)); + XSSFSheet sheet = getSheet(); + if (sheet != null) { + style = (XSSFCellStyle) sheet.getColumnStyle(getColumnIndex()); } return style; } + protected void applyDefaultCellStyleIfNecessary() { + XSSFCellStyle style = getExplicitCellStyle(); + if (style == null) { + XSSFSheet sheet = getSheet(); + if (sheet != null) { + XSSFCellStyle defaultStyle = getDefaultCellStyleFromColumn(); + if (defaultStyle != null) { + setCellStyle(defaultStyle); + } + } + } + } + /** *

Set the style for the cell. The style should be an XSSFCellStyle created/retrieved from * the XSSFWorkbook.

diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java index 227260a26e..8203f6d6c9 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFRow.java @@ -562,6 +562,7 @@ public class XSSFRow implements Row, Comparable { Iterator it = _cells.values().iterator(); for (CTCell ctCell : cArrayOrig) { XSSFCell cell = it.next(); + cell.applyDefaultCellStyleIfNecessary(); // we want to compare on identity here on purpose // as we want to ensure that both lists contain the diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java index 3cbce8e004..11b95d2ee7 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/helpers/ColumnHelper.java @@ -179,6 +179,9 @@ public class ColumnHelper { * as 1 based. */ public CTCol getColumn1Based(long index1, boolean splitColumns) { + if (worksheet.sizeOfColsArray() == 0) { + return null; + } CTCols cols = worksheet.getColsArray(0); // Fetching the array is quicker than working on the new style diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java index dac5bbc746..6a56854ecc 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/streaming/TestSXSSFSheet.java @@ -21,7 +21,6 @@ package org.apache.poi.xssf.streaming; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; @@ -33,7 +32,6 @@ import org.apache.poi.xssf.SXSSFITestDataProvider; 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; @@ -102,12 +100,6 @@ public final class TestSXSSFSheet extends BaseTestXSheet { // properties on Cells... } - @Disabled - @Override - protected void defaultColumnStyle() { - //TODO column styles are not yet supported by XSSF - } - @Test void overrideFlushedRows() throws IOException { try (Workbook wb = new SXSSFWorkbook(3)) { diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java index a9dbe077ec..1c3690f101 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java @@ -48,20 +48,29 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { } // override some tests which do not work for SXSSF - @Override @Disabled("cloneSheet() not implemented") + @Override + @Disabled("cloneSheet() not implemented") protected void bug18800() { /* cloneSheet() not implemented */ } - @Override @Disabled("cloneSheet() not implemented") + + @Override + @Disabled("cloneSheet() not implemented") protected void bug22720() { /* cloneSheet() not implemented */ } - @Override @Disabled("Evaluation is not fully supported") + + @Override + @Disabled("Evaluation is not fully supported") protected void bug47815() { /* Evaluation is not supported */ } - @Override @Disabled("Evaluation is not fully supported") + + @Override + @Disabled("Evaluation is not fully supported") protected void bug46729_testMaxFunctionArguments() { /* Evaluation is not supported */ } - @Override @Disabled("Reading data is not supported") + + @Override + @Disabled("Reading data is not supported") protected void bug57798() { /* Reading data is not supported */ } /** * Setting repeating rows and columns shouldn't break - * any print settings that were there before + * any print settings that were there before */ @Test void bug49253() throws Exception { @@ -105,7 +114,7 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { // does not work try (SXSSFWorkbook wb = new SXSSFWorkbook()) { assertThrows(RuntimeException.class, () -> writeWorkbook(wb, SXSSFITestDataProvider.instance), - "this is not implemented yet"); + "this is not implemented yet"); } } @@ -124,9 +133,9 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { writeRow(sheet, rowIndex++, 80d, "INDEX(A2:A7, MATCH(FALSE, ISBLANK(A2:A7), 0))"); writeRow(sheet, rowIndex++, 30d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B2, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); writeRow(sheet, rowIndex++, 30d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B3, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); - writeRow(sheet, rowIndex++, 2d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B4, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); + writeRow(sheet, rowIndex++, 2d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B4, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); writeRow(sheet, rowIndex++, 30d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B5, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); - writeRow(sheet, rowIndex, 2d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B6, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); + writeRow(sheet, rowIndex, 2d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B6, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); /*FileOutputStream fileOut = new FileOutputStream(filename); wb.write(fileOut); @@ -156,7 +165,7 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { void test62872() throws Exception { final int COLUMN_COUNT = 300; final int ROW_COUNT = 600000; - final int TEN_MINUTES = 1000*60*10; + final int TEN_MINUTES = 1000 * 60 * 10; SXSSFWorkbook workbook = new SXSSFWorkbook(100); workbook.setCompressTempFiles(true); @@ -176,7 +185,7 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { cell = row.createCell(j - 1); //make some noise - cell.setCellValue(new Date(i*TEN_MINUTES+(j*TEN_MINUTES)/COLUMN_COUNT)); + cell.setCellValue(new Date(i * TEN_MINUTES + (j * TEN_MINUTES) / COLUMN_COUNT)); } i++; } @@ -299,7 +308,7 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { assertEquals(value, cell.getStringCellValue()); // so far so good - try (UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()){ + try (UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) { wb.write(bos); try (XSSFWorkbook testWb = new XSSFWorkbook(bos.toInputStream())) { @@ -313,4 +322,49 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { } } } + + @Test + void testBug51037() throws IOException { + try (SXSSFWorkbook wb = new SXSSFWorkbook()) { + CellStyle blueStyle = wb.createCellStyle(); + blueStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex()); + blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + CellStyle pinkStyle = wb.createCellStyle(); + pinkStyle.setFillForegroundColor(IndexedColors.PINK.getIndex()); + pinkStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + Sheet s1 = wb.createSheet("Pretty columns"); + + s1.setDefaultColumnStyle(4, blueStyle); + s1.setDefaultColumnStyle(6, pinkStyle); + + Row r3 = s1.createRow(3); + r3.createCell(0).setCellValue("The"); + r3.createCell(1).setCellValue("quick"); + r3.createCell(2).setCellValue("brown"); + r3.createCell(3).setCellValue("fox"); + r3.createCell(4).setCellValue("jumps"); + r3.createCell(5).setCellValue("over"); + r3.createCell(6).setCellValue("the"); + r3.createCell(7).setCellValue("lazy"); + r3.createCell(8).setCellValue("dog"); + Row r7 = s1.createRow(7); + r7.createCell(1).setCellStyle(pinkStyle); + r7.createCell(8).setCellStyle(blueStyle); + + assertEquals(blueStyle.getIndex(), r3.getCell(4).getCellStyle().getIndex()); + assertEquals(pinkStyle.getIndex(), r3.getCell(6).getCellStyle().getIndex()); + + try (UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) { + wb.write(bos); + try (XSSFWorkbook wb2 = new XSSFWorkbook(bos.toInputStream())) { + XSSFSheet wb2Sheet = wb2.getSheetAt(0); + XSSFRow wb2R3 = wb2Sheet.getRow(3); + assertEquals(blueStyle.getIndex(), wb2R3.getCell(4).getCellStyle().getIndex()); + assertEquals(pinkStyle.getIndex(), wb2R3.getCell(6).getCellStyle().getIndex()); + } + } + } + } } diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 0762dbbe8f..5f5bd2f484 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -35,6 +35,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.LocalDateTime; @@ -3641,4 +3642,49 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertDouble(fe, cell, "A1+\"1:30\"", DateUtil.getExcelDate(expected)); } } + + @Test + void testBug51037() throws IOException { + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFCellStyle blueStyle = wb.createCellStyle(); + blueStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex()); + blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + XSSFCellStyle pinkStyle = wb.createCellStyle(); + pinkStyle.setFillForegroundColor(IndexedColors.PINK.getIndex()); + pinkStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + + Sheet s1 = wb.createSheet("Pretty columns"); + + s1.setDefaultColumnStyle(4, blueStyle); + s1.setDefaultColumnStyle(6, pinkStyle); + + Row r3 = s1.createRow(3); + r3.createCell(0).setCellValue("The"); + r3.createCell(1).setCellValue("quick"); + r3.createCell(2).setCellValue("brown"); + r3.createCell(3).setCellValue("fox"); + r3.createCell(4).setCellValue("jumps"); + r3.createCell(5).setCellValue("over"); + r3.createCell(6).setCellValue("the"); + r3.createCell(7).setCellValue("lazy"); + r3.createCell(8).setCellValue("dog"); + Row r7 = s1.createRow(7); + r7.createCell(1).setCellStyle(pinkStyle); + r7.createCell(8).setCellStyle(blueStyle); + + assertEquals(blueStyle.getIndex(), r3.getCell(4).getCellStyle().getIndex()); + assertEquals(pinkStyle.getIndex(), r3.getCell(6).getCellStyle().getIndex()); + + try (UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream()) { + wb.write(bos); + try (XSSFWorkbook wb2 = new XSSFWorkbook(bos.toInputStream())) { + XSSFSheet wb2Sheet = wb2.getSheetAt(0); + XSSFRow wb2R3 = wb2Sheet.getRow(3); + assertEquals(blueStyle.getIndex(), wb2R3.getCell(4).getCellStyle().getIndex()); + assertEquals(pinkStyle.getIndex(), wb2R3.getCell(6).getCellStyle().getIndex()); + } + } + } + } } \ No newline at end of file diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFSheet.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFSheet.java index 964e9a7d8e..f863afd8a4 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFSheet.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFSheet.java @@ -18,7 +18,6 @@ package org.apache.poi.xssf.usermodel; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.apache.poi.xssf.XSSFTestDataSamples.openSamplePackage; import static org.apache.poi.xssf.XSSFTestDataSamples.openSampleWorkbook; import static org.apache.poi.xssf.XSSFTestDataSamples.writeOutAndReadBack; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -77,7 +76,6 @@ import org.apache.poi.util.LocaleUtil; import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.model.CalculationChain; -import org.apache.poi.xssf.model.Comments; import org.apache.poi.xssf.model.CommentsTable; import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.streaming.SXSSFWorkbook; @@ -108,12 +106,6 @@ public final class TestXSSFSheet extends BaseTestXSheet { super(XSSFITestDataProvider.instance); } - //TODO column styles are not yet supported by XSSF - @Override - protected void defaultColumnStyle() { - //super.defaultColumnStyle(); - } - @Test void existingHeaderFooter() throws IOException { try (XSSFWorkbook wb1 = XSSFTestDataSamples.openSampleWorkbook("45540_classic_Header.xlsx")) { 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 6c069f0539..bb70fa1c8f 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 @@ -671,7 +671,45 @@ public abstract class BaseTestSheet { Cell cell = row.createCell(0); CellStyle style2 = cell.getCellStyle(); assertNotNull(style2); - assertEquals(style.getIndex(), style2.getIndex(), "style should match"); + assertEquals(style.getIndex(), style2.getIndex(), "style2 should match"); + + try (Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb)) { + Sheet wb2Sheet = wb2.getSheetAt(0); + assertNotNull(wb2Sheet.getColumnStyle(0)); + assertEquals(style.getIndex(), wb2Sheet.getColumnStyle(0).getIndex()); + + Row wb2R0 = wb2Sheet.getRow(0); + Cell wb2Cell = wb2R0.getCell(0); + CellStyle style3 = wb2Cell.getCellStyle(); + assertNotNull(style3); + assertEquals(style.getIndex(), style3.getIndex(), "style3 should match"); + } + + } + } + + @Test + protected void defaultRowStyle() throws IOException { + try (Workbook wb = _testDataProvider.createWorkbook()) { + CellStyle style = wb.createCellStyle(); + Sheet sheet = wb.createSheet(); + Row r0 = sheet.createRow(0); + r0.setRowStyle(style); + assertNotNull(r0.getRowStyle()); + assertEquals(style.getIndex(), r0.getRowStyle().getIndex()); + + 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"); + + try (Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb)) { + Sheet wb2Sheet = wb2.getSheetAt(0); + Row wb2R0 = wb2Sheet.getRow(0); + assertNotNull(wb2R0.getRowStyle()); + assertEquals(style.getIndex(), wb2R0.getRowStyle().getIndex()); + } } }