Как повторно использовать шрифты в Apache POI?

Каждый вызов "workbook.createFont()" добавляет новый шрифт в книгу. Есть ли удобный способ повторно использовать эти шрифты?

Очевидно, я могу повторно использовать объект шрифта в программе. Но когда я снова открываю Java-программу, мне нужен способ вернуть объект Font.

Хотя можно использовать "workbook.getNumberOfFonts()" и "workbook.getFontAt(i)", использование этих методов не очень удобно.

Мой обходной путь:
Я добавляю CustomProperty при создании шрифта, который содержит соответствующий номер шрифта.

Map<String, Font> fonts = new HashMap<>();

CustomProperties customProps  = workbook.getProperties().getCustomProperties(); 

if(customProps.contains("arial_12_b")) {
    short index = customProps.getProperty("arial_12_b").getI2();
    fonts.put("arial_12_b", workbook.getFontAt(index));
} else {                                
    Font font = workbook.createFont();
    font.setFontName("Arial");
    font.setFontHeightInPoints((short)12);
    font.setBold(true);

    customProps.addProperty("arial_12_b", font.getIndex());

    fonts.put("arial_12_b", font);
}

CellStyle решил ту же проблему с помощью класса CellUtil, который проверяет, существует ли CellStyle, и создает его, если его нет. Есть ли что-то похожее на шрифт?

С наилучшими пожеланиями
AFoeee

1 ответ

Решение

Можно было бы предоставить метод, который использует Workbook.findFont для достижения того, о чем вы спрашиваете. Чтобы быть очень похожим на CellUtil.setCellStyleProperties, он мог бы использовать Map<FontProperty, Object> fontproperties установить свойства шрифта где FontProperty перечисление всех свойств Workbook.findFont в настоящее время проверяет. Это BOLD, COLOR, FONTHEIGHT, FONTNAME, ITALIC, STRIKEOUT, TYPEOFFSET, UNDERLINE на данный момент.

Пример:

 //method for getting current font from cell
 private static Font getFont(Cell cell) {
  Workbook wb = cell.getRow().getSheet().getWorkbook();
  CellStyle style = cell.getCellStyle();
  return wb.getFontAt(style.getFontIndex());
 }

 private enum FontProperty {
  BOLD, COLOR, FONTHEIGHT, FONTNAME, ITALIC, STRIKEOUT, TYPEOFFSET, UNDERLINE
 }

 //method for getting font having special settings additional to given source font
 private static Font getFont(Workbook wb, Font fontSrc, Map<FontProperty, Object> fontproperties) {
  boolean isBold = fontSrc.getBold();
  short color = fontSrc.getColor();
  short fontHeight = fontSrc.getFontHeight();
  String fontName = fontSrc.getFontName();
  boolean isItalic = fontSrc.getItalic();
  boolean isStrikeout = fontSrc.getStrikeout();
  short typeOffset = fontSrc.getTypeOffset();
  byte underline = fontSrc.getUnderline();

  for (FontProperty property : fontproperties.keySet()) {
   switch (property) {
    case BOLD:
     isBold = (boolean)fontproperties.get(property);
    break;
    case COLOR:
     color = (short)fontproperties.get(property);
    break;
    case FONTHEIGHT:
     fontHeight = (short)fontproperties.get(property);
    break;
    case FONTNAME:
     fontName = (String)fontproperties.get(property);
    break;
    case ITALIC:
     isItalic = (boolean)fontproperties.get(property);
    break;
    case STRIKEOUT:
     isStrikeout = (boolean)fontproperties.get(property);
    break;
    case TYPEOFFSET:
     typeOffset = (short)fontproperties.get(property);
    break;
    case UNDERLINE:
     underline = (byte)fontproperties.get(property);
    break;
   }
  }

  Font font = wb.findFont(isBold, color, fontHeight, fontName, isItalic, isStrikeout, typeOffset, underline);
  if (font == null) {
   font = wb.createFont();
   font.setBold(isBold);
   font.setColor(color);
   font.setFontHeight(fontHeight);
   font.setFontName(fontName);
   font.setItalic(isItalic);
   font.setStrikeout(isStrikeout);
   font.setTypeOffset(typeOffset);
   font.setUnderline(underline);
  }

  return font;
 }

В этом коде Workbook.findFont используется для поиска шрифта, уже имеющего все свойства. Только если это не найдено (if (font == null)) тогда будет создан новый шрифт.

Как пользоваться:

  //set new cell D6 having special font settings
  row = CellUtil.getRow(5, sheet);
  cell = CellUtil.getCell(row, 3);
  fontproperties = new HashMap<FontProperty, Object>();
  fontproperties.put(FontProperty.BOLD, true);
  fontproperties.put(FontProperty.COLOR, IndexedColors.BLUE.getIndex());
  fontproperties.put(FontProperty.FONTHEIGHT, (short)(20*20));
  fontproperties.put(FontProperty.FONTNAME, "Courier New");
  fontproperties.put(FontProperty.STRIKEOUT, true);
  fontproperties.put(FontProperty.UNDERLINE, Font.U_DOUBLE);
  font = getFont(wb, getFont(cell), fontproperties);
  styleproperties = new HashMap<String, Object>();
  styleproperties.put(CellUtil.FONT, font.getIndex());
  CellUtil.setCellStyleProperties(cell, styleproperties);
  cell.setCellValue("new cell");

См. Как отформатировать ячейку Excel в качестве даты в Apache POI для полного примера.

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