Использование POI для определения и установки ширины столбца и применения переноса текста на основе этой ширины - PullRequest
0 голосов
/ 12 января 2020

Java 8 и Apache POI 4.1.x здесь. Мне нужно:

  1. Прочитать в файле шаблона Excel, который содержит только одну строку предварительно стилизованных столбцов заголовка
  2. Записать List<Fizz> (список POJO) в новый файл Excel, который использует этот шаблон

Я делаю это потому, что в шаблоне Excel много сложных стилей, и поэтому просто использовать существующий в качестве входных данных шаблона было намного проще, чем я пытаясь вручную сгенерировать стили с помощью POI и CellUtil.

У меня это отлично работает, например, так:

List<Fizz> fizzes = getSomehow();

InputStream inp = this.getClass().getClassLoader().getResource("my-template.xlsx").openStream();
Workbook workbook = WorkbookFactory.create(inp);
Sheet sheet = workbook.getSheetAt(0);

// the header is at row = 0 (0-based rows)
// so start writing the list on the row=1 (1st data/non-header row)
int rowNum = 1;
for (Fizz fizz : fizzes) {
  Row nextRow = sheet.createRow(rowNum);

  Cell itemNumber = nextRow.createCell(0);
  itemNumber.setCellValue(fizz.getItemNumber());

  Cell description = nextRow.createCell(1);
  description.setCellValue(fizz.getDescription());

  rowNum++;

}

// resize the columns appropriately
for (int c = 0; c < 2; c++) {
    sheet.autoSizeColumn(c);
}

// export to file system
FileOutputStream fos = new FileOutputStream("some-output.xlsx");
workbook.write(fos);

fos.close();
inp.close();
workbook.close();

Все отлично работает, за одним исключением: часто Fizz#description довольно длинный, иногда длиной в сотни символов. Поскольку в моем коде нет использования переноса текста, и поскольку я использую autoSizeColumn для всех столбцов, POI устанавливает ширину столбца Description равной длине самого длинного описания.

Вместо этого я сейчас хочу остановить , используя autoSizeColumn (я думаю!) И вместо этого:

Принудительно использовать выходной файл (в нашем случае "some-output.xlsx") ) Description ширина столбца, равная ширине столбца Description файла входного шаблона. Так что если столбец Description в my-template.xlsx равен, скажем, 54, то я хочу, чтобы столбец Description some-output.xlsx также был 54.

Если описание Fizz текущей строки слишком длинное для этой ширины, я Я хочу применить перенос текста так, чтобы столбец оставался фиксированным (опять же, в данном случае, 54), но чтобы описание вписывалось в него.

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

Любые идеи о том, что я могу сделать, чтобы сделать sh это?

1 Ответ

1 голос
/ 13 января 2020

Первый подход

Установите стиль ячейки текста обтекания для всего столбца описания (столбец B) в вашем шаблоне, используя Excel s GUI. Затем используйте следующий метод getPreferredCellStyle, чтобы получить стиль ячейки этого столбца и установить его в качестве предпочтительного стиля ячейки для каждой ячейки в столбце описания (столбец B).

 CellStyle getPreferredCellStyle(Cell cell) {
  // a method to get the preferred cell style for a cell
  // this is either the already applied cell style
  // or if that not present, then the row style (default cell style for this row)
  // or if that not present, then the column style (default cell style for this column)
  CellStyle cellStyle = cell.getCellStyle();
  // if no explicit cell style applied then cellStyle.getIndex() is 0 for XSSF
  // or 15 (0xF = the index to the default ExtendedFormatRecord (0xF)) for HSSF
  if ((cell instanceof XSSFCell && cellStyle.getIndex() == 0) || (cell instanceof HSSFCell && cellStyle.getIndex() == 15)) cellStyle = cell.getRow().getRowStyle();
  if (cellStyle == null) cellStyle = cell.getSheet().getColumnStyle(cell.getColumnIndex());
  if (cellStyle == null) cellStyle = cell.getCellStyle();
  return cellStyle;
 }

Затем

...
Cell description = nextRow.createCell(1);
description.setCellValue(fizz.getDescription());
description.setCellStyle(getPreferredCellStyle(description));
...

Второй подход

Используйте CellUtil для установки стиля переноса текста для каждой ячейки в столбце описания.

...
Cell description = nextRow.createCell(1);
description.setCellValue(fizz.getDescription());
CellUtil.setCellStyleProperty(description, CellUtil.WRAP_TEXT, true);
...

Для обоих подходов

Не задавайте autoSizeColumn для столбца описания (столбец B). В вашем примере только авторазмер столбца 0 (A), но не столбец 1 (B):

...
sheet.autoSizeColumn(0);
...

Таким образом, ширина столбца столбца B остается неизменной, как ширина в шаблон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...