org.apache.poi 4.0
removed the XSSFColor
constructor that just uses java.awt.Color
. In org.apache.poi 3.7
it was very easy to create the object by just writing
Color inputColor = Color.RED;
XSSFColor test = new XSSFColor(inputColor);
However, this constructor no longer works in 4.0. The documentation at https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/usermodel/XSSFColor.html shows several other constructors, but ideally i want to change as few lines as possible.
So, my question is, what is the best way to create an XSSFColor
from a java.awt.Color
now (in apache poi 4.0)?
As requested in the comments, here is my test code using the suggestion style.setFillForegroundColor(new XSSFColor(java.awt.Color.RED, null));
Opening this with LibreOffice 6.1 yields an Error (Attempt to repair, which then fails). Commented out the POI 3.7 version which works normally.
@Test
public void testPOI40() throws FileNotFoundException, IOException {
Workbook workbook = new XSSFWorkbook();
XSSFSheet fSheet = (XSSFSheet) workbook.createSheet("new Sheet");
XSSFRow hRow = fSheet.createRow((short) 0);
//header
String[] astrHeaders = new String[]{"Header1", "Header2", "Header3", "Header4"};
for (int col = 0; col < astrHeaders.length; col++) {
XSSFCell cell = hRow.createCell((short) col);
XSSFCellStyle tempHeaderStyle = (XSSFCellStyle) workbook.createCellStyle();
tempHeaderStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
tempHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cell.setCellValue(astrHeaders[col]);
cell.setCellStyle(tempHeaderStyle);
}
//body
Double[] astrContent = new Double[]{1.3, 0.3, 0.87, 1.0};
Color[] colors = new Color[] {Color.RED,Color.BLUE,Color.WHITE,Color.GREEN};
XSSFRow fRow = fSheet.createRow((short) 1);
for (int iCol = 0; iCol < 4; iCol++) {
XSSFCell cell = fRow.createCell((short) iCol);
XSSFCellStyle tempBodyStyle = (XSSFCellStyle) workbook.createCellStyle();
cell.setCellValue(astrContent[iCol]);
//working with POI 3.17
//tempBodyStyle.setFillForegroundColor(new XSSFColor(colors[iCol]));
tempBodyStyle.setFillForegroundColor(new XSSFColor(colors[iCol],null));
tempBodyStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cell.setCellStyle(tempBodyStyle);
}
FileOutputStream fileOut = new FileOutputStream(new File("testfile.xlsx"));
BufferedOutputStream bos = new BufferedOutputStream(fileOut);
workbook.write(bos);
fileOut.close();
}
Solution:
Replaced fileout.close();
with bos.close();
and it works. So tempBodyStyle.setFillForegroundColor(new XSSFColor(Color.RED,null));
as suggested in the comments by Alex Richter is a good solution & will accept this as answer.
If you are wrapping the
FileOutputStream
in anBufferedOutputStream
but do closing then only the innerFileOutputStream
but not theBufferedOutputStream
, then theBufferedOutputStream
remains open and the file will not have all bytes in.That's why the damaging of the file.
So the damaging has noting to do with constructing the
XSSFColor
. The constructorstyle.setFillForegroundColor(new XSSFColor(java.awt.Color.RED, null));
works.Do instead:
It might had worked in former apache poi versions because
XSSFWorkbook.write
had closed all streams when it was ready. This it does not more. And this is correct becausewrite
should not closing streams.But since
POIXMLDocument
implementsjava.io.Closeable
at leastworkbook.close()
should closing all streams. But that also it does not. So explicitly closing all streams is necessary inapache poi 4.0.0
.