Как установить собственный цвет для HSSCell с помощью POI?

Я хотел бы установить собственный цвет для CellStyle в POI, но, похоже, он не применяется.

У меня есть следующий код:

HSSFWorkbook workBook = new HSSFWorkbook();
HSSFSheet sheet = workBook.createSheet("Bank Statement");

HSSFPalette palette = workBook.getCustomPalette();
palette.setColorAtIndex((short) 1, (byte) 60, (byte) 120, (byte) 216);

HSSFColor color = palette.findSimilarColor(60, 120, 216);

CellStyle cellStyleHeader = workBook.createCellStyle();
cellStyleHeader.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyleHeader.setFillForegroundColor(color);
cellStyleHeader.setFont(createHeaderFont(workBook));

HSSFCell cell = row.createCell(cellIndex);
cell.setCellType(CellType.STRING);
cell.setCellValue("Date");
cell.setCellStyle(style);

Цвет фона не применяется. Цвет белый. Значение color не равно нулю, но имеет разный цвет (при запуске через отладчик):

Как правильно установить собственный цвет?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, void setFillForegroundColor(Color color) не работает должным образом для HSSFColor.

В двоичном формате файла Excel (*.xls, HSSF) все цвета должны быть проиндексированы в цветовой палитре. Таким образом, пользовательский цвет должен перезаписывать цвет палитры по умолчанию. И чтобы задать цвет переднего плана заливки, следует использовать индекс, а не сам цвет. Так что void setFillForegroundColor(short bg) следует использовать для HSSF.

Следующий код работает для установки пользовательского цвета переднего плана заливки для XSSF, а также для HSSF. Для HSSF он перезаписывает HSSFColor.HSSFColorPredefined.LIME цвет в палитре.

import java.io.FileOutputStream;

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

public class CreateExcelCellFillCustomColor {

 public static void main(String[] args) throws Exception {

  byte[] rgb = new byte[]{(byte) 60, (byte) 120, (byte) 216};

  Workbook workbook = new HSSFWorkbook(); String filePath = "./Excel.xls";
  //Workbook workbook = new XSSFWorkbook(); String filePath = "./Excel.xlsx";

  CellStyle cellStyle = workbook.createCellStyle();
  cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
  if (workbook instanceof XSSFWorkbook) {
   XSSFColor color = new XSSFColor(rgb, null);
   cellStyle.setFillForegroundColor(color);
  } else if (workbook instanceof HSSFWorkbook) {
   HSSFWorkbook hssfworkbook = (HSSFWorkbook)workbook;
   HSSFPalette palette = hssfworkbook.getCustomPalette();
   palette.setColorAtIndex(HSSFColor.HSSFColorPredefined.LIME.getIndex(), rgb[0], rgb[1], rgb[2]);
   HSSFColor color = palette.findSimilarColor(rgb[0], rgb[1], rgb[2]);
   //cellStyle.setFillForegroundColor(color); // does not work correctly for HSSF
   cellStyle.setFillForegroundColor(color.getIndex());   
  }
  
  Sheet sheet = workbook.createSheet();
  Cell cell = sheet.createRow(0).createCell(0);
  cell.setCellStyle(cellStyle);
  cell.setCellValue("test");

  FileOutputStream out = new FileOutputStream(filePath);
  workbook.write(out);
  out.close();
  workbook.close();

 }

}

Спасибо, Аксель. Этот HSSFCellStyle setFillForegroundColor(color) основан на коде, который вы предоставили в bz.apache.org/bugzilla/show_bug.cgi?id=66052 — разница, похоже, заключается в том, что код, добавленный в POI, использует index2 вместо index — должны ли мы переключиться на индекс и игнорировать index2?

PJ Fanning 07.01.2023 16:08

@PJ Fanning: Извините, не могу помочь. Я отказался от попыток внести свой вклад в Apache POI. Следить за кодом в различных библиотеках и классах очень сложно, потому что часто отсутствует документация. Поэтому трудно сказать, какие побочные эффекты будут иметь изменения кода. В чем именно разница между HSSFColor.getIndex() и HSSFColor.getIndex2()? Вроде нигде не задокументировано.

Axel Richter 07.01.2023 17:31

Я сильно подозреваю, что разница возникает из низкоуровневых записей. Вероятно, начните с learn.microsoft.com/en-us/openspecs/office_file_formats/ms-x‌​ls/… , а затем прочитайте документы для записей, связанных со стилем.

Gagravarr 07.01.2023 23:28

@Gagravarr: Вас это больше беспокоит? Сомневаюсь. У меня есть. Я обнаружил, что Apache POI не соответствует документации Microsoft. 2.5.249 StyleXF -> icvFore (7 бит) -> Icv. Но это не то, что запрограммировал Apache POI.

Axel Richter 08.01.2023 06:53

Другие вопросы по теме

Похожие вопросы

Джексон десериализация LocalDateTime с пользовательским форматом в Java 11
Ошибка создания bean-компонента с именем: неудовлетворенная зависимость, выраженная через поле
Не удалось вызвать метод инициализации; вложенным исключением является org.hibernate.AnnotationException: mappedBy ссылается на неизвестное свойство целевого объекта:
Почему ленивое создание bean-компонентов приводит к классам с разными ссылками/хэш-кодами в SpringBoot?
Определите, происходит ли изменение JSpinner от ввода значения или нажатия на стрелку
Вычислить средневзвешенное значение из объектов с потоком Java
Вернуть автозакрывающийся объект внутри CompletableFuture и использовать его в whenComplete
Как убедиться, что 2 мяча удалены после столкновения?
Получить список всех моментов между двумя моментами в Scala
Пытаюсь снизить выносливость по мере увеличения таймера. Я хочу, чтобы он снижался на 2 каждые 10 секунд