Apache POI 4.0: XSSFColor от java.awt.Color - PullRequest
0 голосов
/ 09 ноября 2018

org.apache.poi 4.0 удален конструктор XSSFColor, который просто использует java.awt.Color. В org.apache.poi 3.7 было очень легко создать объект, просто написав

Color inputColor = Color.RED;
XSSFColor test = new XSSFColor(inputColor);

Однако этот конструктор больше не работает в 4.0. Документация по https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/usermodel/XSSFColor.html показывает несколько других конструкторов, но в идеале я хочу изменить как можно меньше строк.

Итак, мой вопрос: как лучше всего создать XSSFColor из java.awt.Color сейчас (в apache poi 4.0)?


Как и просили в комментариях, вот мой тестовый код с предложением style.setFillForegroundColor(new XSSFColor(java.awt.Color.RED, null)); Открытие этого с помощью LibreOffice 6.1 приводит к ошибке (попытка исправить, которая затем не удается). Прокомментирована версия POI 3.7, которая работает нормально.

@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();
}

Решение:
Заменил fileout.close(); на bos.close(); и все работает. Так что tempBodyStyle.setFillForegroundColor(new XSSFColor(Color.RED,null));, как предложено в комментариях Алекса Рихтера, является хорошим решением и примет это как ответ.

1 Ответ

0 голосов
/ 09 ноября 2018

Если вы оборачиваете FileOutputStream в BufferedOutputStream, но закрываете его, то только внутренний FileOutputStream, но не BufferedOutputStream, тогда BufferedOutputStream остается открытым, и в файле не будут все байты.

Вот почему повреждение файла.

Так что нанесение ущерба не имеет ничего общего с созданием XSSFColor. Конструктор style.setFillForegroundColor(new XSSFColor(java.awt.Color.RED, null)); работает.

Вместо этого:

...
FileOutputStream fileOut = new FileOutputStream(new File("testfile.xlsx"));
BufferedOutputStream bos = new BufferedOutputStream(fileOut);
workbook.write(bos); 
bos.close();
workbook.close();
...

Возможно, он работал в прежних версиях apache poi, потому что XSSFWorkbook.write закрыл все потоки, когда он был готов. Это не более того. И это правильно, потому что write не должен закрывать потоки.

Но поскольку POIXMLDocument реализует java.io.Closeable, по крайней мере workbook.close() должен закрывать все потоки. Но это также не так. Поэтому явное закрытие всех потоков необходимо в apache poi 4.0.0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...