Получение Excel заливки цветов с помощью Apache POI - PullRequest
0 голосов
/ 25 августа 2018

Я использую Apache POI 3.17 для чтения книги Excel 2013.Рабочая книга создается и редактируется пользователями непосредственно в Excel.Затем я запускаю программу на Java 8, которая использует POI для чтения и обработки книги.

Некоторые ячейки имеют цветовую кодировку, поэтому мне нужно получить цвет заливки.Во многих случаях это работает нормально, но есть набор серых / серебряных цветов, где он не работает, и я не уверен, почему.

Например, ячейки Excel выглядят так:

Excel sample

Мой код для получения цвета заливки:

private String getFillColor(XSSFCell cell) {
    String fColorString = "None";
    if (cell != null) {
        XSSFCellStyle cellStyle = cell.getCellStyle();

        short sColorFore = cellStyle.getFillForegroundColor();
        short sColorBack = cellStyle.getFillBackgroundColor();
        XSSFColor xColorFore =  cellStyle.getFillForegroundColorColor();
        XSSFColor xColorBack =  cellStyle.getFillBackgroundColorColor();

        String s = "";
        s += " indexFore=" + sColorFore;
        s += " indexBack=" + sColorBack;
        s += " colorFore=" + ((xColorFore == null) ? "Null" : xColorFore.getARGBHex());
        s += " colorBack=" + ((xColorBack == null) ? "Null" : xColorBack.getARGBHex());
        System.out.println("Cell=" + cell.getAddress() + " " + cell.getStringCellValue() + s);

        if (xColorFore != null) {
            fColorString = xColorFore.getARGBHex();
        }8
    }
    return fColorString;
}

Результаты этого при вызове для каждой из примерных ячеек Excelвыше:

Ячейка = BBH52 Розовый indexFore = 0 indexBack = 64 colorFore = FFF79646 colorBack = ноль

Ячейка = BBH53 Нет заполнения indexFore = 64 indexBack = 64 colorFore = Null colorBack =Null

Ячейка = BBH54 Серый 1 indexFore = 0 indexBack = 64 colorFore = FFFFFFFF colorBack = null

Ячейка = BBH55 Grey 2 indexFore = 0 indexBack = 64 colorFore = FFFFFFFF colorBack = null

Ячейка = BBH56 Серый 3 indexFore = 0 indexBack = 64 colorFore = FFFFFFFF colorBack = null

Ячейка = BBH57 Grey 4 indexFore = 0 indexBack = 64 colorFore = FFFFFFFF colorBack = null

Ячейка= BBH58 Серый 5 indexFore = 0 indexBack = 64 colorFore = FFFFFFFF colorBack = ноль

Cell = BBH59 White indexFore = 0 indexBack = 64 colorFore = FFFFFFFF colorBack = null

Есть идеи, почему все оттенки серого и белого переводятся в шестнадцатеричное значение FFFFFFFF?Есть ли более правильный способ доступа к фактическому цвету заливки?Спасибо.

1 Ответ

0 голосов
/ 26 августа 2018

«Книга Excel 2013» - это книга, хранящаяся в формате Office Open XML.Там у цветов может быть дополнительный 4-й альфа-канал, но также может быть установлено свойство ColorType.Tint .Таким образом, на самом деле все оттенки серого RGB белый FFFFFF с различным набором tint.Например, в xl/styles.xml значение Grey 1:

...
<fill>
 <patternFill patternType="solid">
  <fgColor theme="0" tint="-0.0499893185216834"/>
  <bgColor indexed="64"/>
 </patternFill>
</fill>
...

Цвет темы 0 - белый FFFFFF, а tint -0.0499893185216834 затемняет этот цвет от белого до серого.

Поэтому мы должны принять во внимание tint.К счастью apache poi ExtendedColor предоставляет для этого метод getRGBWithTint .

Так что следующий пример правильно получает цвета заливки, даже если для них установлено tint:

import java.io.FileInputStream;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.hssf.util.HSSFColor;

public class ReadExcelColorHavingTint {

 private static String getFillColorHex(Cell cell) throws Exception { 
  String fillColorString = "none";
  if (cell != null) {
   CellStyle cellStyle = cell.getCellStyle();
   Color color =  cellStyle.getFillForegroundColorColor();
   if (color instanceof XSSFColor) {
    XSSFColor xssfColor = (XSSFColor)color;
    byte[] argb = xssfColor.getARGB();
    fillColorString = "[" + (argb[0]&0xFF) + ", " + (argb[1]&0xFF) + ", " + (argb[2]&0xFF) + ", " + (argb[3]&0xFF) + "]";
    if (xssfColor.hasTint()) {
     fillColorString += " * " + xssfColor.getTint();
     byte[] rgb = xssfColor.getRGBWithTint();
     fillColorString += " = [" + (argb[0]&0xFF) + ", " + (rgb[0]&0xFF) + ", " + (rgb[1]&0xFF) + ", " + (rgb[2]&0xFF) + "]" ;
    }
   } else if (color instanceof HSSFColor) {
    HSSFColor hssfColor = (HSSFColor)color;
    short[] rgb = hssfColor.getTriplet();
    fillColorString = "[" + rgb[0] + ", " + rgb[1] + ", "  + rgb[2] + "]";
   }
  }
  return fillColorString;
 }

 public static void main(String[] args) throws Exception {
  Workbook workbook = WorkbookFactory.create(new FileInputStream("workbook.xlsx"));
  //Workbook workbook = WorkbookFactory.create(new FileInputStream("workbook.xls"));
  Sheet sheet = workbook.getSheetAt(0);
  for (Row row : sheet) {
   for (Cell cell : row) {

    System.out.println("Cell=" + cell.getAddress() + " " + cell.toString() + " " + getFillColorHex(cell));

   }
  }
 }

}
...