Я хотел бы установить собственный цвет для 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
не равно нулю, но имеет разный цвет (при запуске через отладчик):
Как правильно установить собственный цвет?
Кажется, 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();
}
}
@PJ Fanning: Извините, не могу помочь. Я отказался от попыток внести свой вклад в Apache POI. Следить за кодом в различных библиотеках и классах очень сложно, потому что часто отсутствует документация. Поэтому трудно сказать, какие побочные эффекты будут иметь изменения кода. В чем именно разница между HSSFColor.getIndex()
и HSSFColor.getIndex2()
? Вроде нигде не задокументировано.
Я сильно подозреваю, что разница возникает из низкоуровневых записей. Вероятно, начните с learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/… , а затем прочитайте документы для записей, связанных со стилем.
@Gagravarr: Вас это больше беспокоит? Сомневаюсь. У меня есть. Я обнаружил, что Apache POI не соответствует документации Microsoft. 2.5.249 StyleXF -> icvFore (7 бит) -> Icv. Но это не то, что запрограммировал Apache POI.
Спасибо, Аксель. Этот HSSFCellStyle setFillForegroundColor(color) основан на коде, который вы предоставили в bz.apache.org/bugzilla/show_bug.cgi?id=66052 — разница, похоже, заключается в том, что код, добавленный в POI, использует index2 вместо index — должны ли мы переключиться на индекс и игнорировать index2?