Есть много проблем с вашим кодом, что приводит к множеству разных проблем. Так что ответ будет немного длинным.
Сначала о том, как структурирована книга Excel:
Рабочая книга состоит как минимум из одного, но может быть нескольких листов, каждый из которых имеет несколько строк, каждый из которых имеет несколько ячеек. Каждая клетка может иметь стиль. Но настройки стиля хранятся не в ячейке, а в таблице стилей (таблица стилей) на уровне рабочей книги. Таким образом, стили хранятся в ячейках, строках и даже листах. Несколько ячеек могут иметь одинаковый сохраненный стиль, если они имеют одинаковый вид. То же самое для цветов. Цвета также хранятся на уровне рабочей книги. И, к сожалению, в формате *.xls
BIFF
цвета ограничены индексированными цветами в цветовой палитре. В BIFF8
имеется 49 (индекс 16–64) в пользовательской записи ПАЛИТРА, плюс еще несколько. Эти 49 могут быть перезаписаны, но их нельзя увеличить.
Теперь к вашему коду:
Вы выписываете всю книгу каждый раз, когда меняете ячейку в строке листа. Вы не должны этого делать. Вместо этого вы должны выписать рабочую книгу один раз, если с ней покончено.
Вы создаете новый стиль ячейки для каждой ячейки, в которой вам нужно надеть стиль. Вы не должны этого делать. Excel *.xls
ограничен примерно 4000 различными комбинациями форматов ячеек. Поэтому вам нужно проверить, присутствует ли нужный вам стиль в рабочей книге. Это может быть очень утомительно, но есть CellUtil , который вы уже нашли и уже используете в своем коде. Это обеспечивает setCellStyleProperties
, который «пытается найти существующий CellStyle, который соответствует текущему стилю ячейки и свойствам стилей в свойствах. Новый стиль создается, если рабочая книга не содержит соответствующий стиль.».
Сначала вы ищете, существует ли нужный цвет. Это хорошо. Но если нет, вы перезаписываете всегда один и тот же индекс цвета GOLD
. Поскольку цвета также сохраняются на уровне книги, только последнее перезаписанное значение цвета будет сохранено как GOLD
. Вам нужно перезаписать разных цветовых индексов, если в книге должны храниться разные цвета.
Пример:
Источник Excel:
Код:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellUtil;
import java.util.Map;
import java.util.HashMap;
public class ExcelSetHSSFCellStyleColors {
static void giveGradientToColumn(HSSFSheet sheet, int columnIndex, double minimum, double maximum) throws Exception {
DataFormatter formatter = new DataFormatter(java.util.Locale.US);
short colorIndex = 16; //color indexes 0 to 15 should not be overwritten
HSSFPalette palette = sheet.getWorkbook().getCustomPalette();
for (Row row : sheet) {
Cell cell = CellUtil.getCell(row, columnIndex);
String cellContent = formatter.formatCellValue(cell);
System.out.println(cellContent);
String percentValue = cellContent.split("%")[0];
double value = Double.NaN;
try {
value = Double.valueOf(percentValue);
} catch(Exception e){
//percentValue was not numeric
}
if (!Double.isNaN(value) && value >= minimum && value <= maximum){
double ratio = (value - minimum) / (maximum - minimum);
byte r = (byte)Math.round(Math.max(0, 255 * (1 - ratio)));
byte b = 0;
byte g = (byte)Math.round(Math.max(0, 255 - (int)b - (int)r));
System.out.println(ratio + " " + String.format("%02X", r) + ":" + String.format("%02X", g) + ":" + String.format("%02X", b));
HSSFColor hssfColor = palette.findColor(r, g, b);
if (hssfColor == null /*&& colorIndex < 64*/) {
palette.setColorAtIndex(colorIndex, r, g, b);
hssfColor = palette.getColor(colorIndex);
colorIndex++;
}
System.out.println("got color: " + ((hssfColor!=null)?hssfColor.getIndex() + ": " + hssfColor.getHexString():hssfColor)); //if not a index available, hssfColor may be null
if (hssfColor != null) {
Map<String, Object> styleproperties = styleproperties = new HashMap<String, Object>();
styleproperties.put(CellUtil.FILL_FOREGROUND_COLOR, hssfColor.getIndex());
styleproperties.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
CellUtil.setCellStyleProperties(cell, styleproperties);
}
}
}
}
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelTest.xls"));
HSSFSheet sheet = (HSSFSheet)workbook.getSheetAt(0);
giveGradientToColumn(sheet, 5, 10, 90);
workbook.write(new FileOutputStream("ExcelTestNew.xls"));
workbook.close();
}
}
Результат:
Отказ от ответственности:
Код протестирован и работает с использованием последней стабильной версии 3.17
из apache poi
. Ваш код использовал более старую версию (я знаю, потому что использовал HSSFColor.GOLD.index
).
Кстати:
Что я действительно хотел бы предложить, так это обновить формат файла Excel до современного формата *.xlsx
Office Open XML
. Мало того, что ограничение по цвету прошло, вы можете просто использовать Условное форматирование с Цветовые шкалы , что, вероятно, удовлетворяет вашим требованиям еще лучше.