Apache-poi: автоматическая установка размера со слитыми ячейками и выделение шрифта - PullRequest
0 голосов
/ 23 октября 2019

Я новичок в этом и просто играю с apache-poi, чтобы сгенерировать лист Excel с некоторыми фиктивными данными, вот мой класс, и я поражен несколькими вещами, лучшими практиками ?? enter image description here

  1. Автоматически устанавливать размер с объединенными ячейками в строке.
  2. Шрифт жирным шрифтом -> Для всех ячеек в первой строке.

класс:

package com.example.TestProject.process;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class WriteExcelDemo {

    public static void main(
            String[] args) {

        // Blank workbook
        XSSFWorkbook workbook = new XSSFWorkbook();

        // Create a blank sheet
        XSSFSheet sheet = workbook.createSheet("Employee Data");

        // This data needs to be written (Object[])
        Map<String, Object[]> data = new TreeMap<String, Object[]>();
        data.put("1", new Object[] {"ID", "NAME", "LASTNAME"});
        data.put("2", new Object[] {1, "Amit", "Shukla"});
        data.put("3", new Object[] {2, "Lokesh", "Gupta"});
        data.put("4", new Object[] {3, "John", "Adwards"});
        data.put("5", new Object[] {4, "Brian", "Schultz"});

        // Iterate over data and write to sheet
        Set<String> keyset = data.keySet();
        int rownum = 0;
        for (String key : keyset) {
            Row row = sheet.createRow(rownum++);
            Object[] objArr = data.get(key);
            int cellnum = 0;
            for (Object obj : objArr) {
                Cell cell = row.createCell(cellnum++);
                if (obj instanceof String)
                    cell.setCellValue((String) obj);
                else if (obj instanceof Integer)
                    cell.setCellValue((Integer) obj);
            }
        }
        try {
            // Write the workbook in file system
            FileOutputStream out = new FileOutputStream(new File("howtodoinjava_demo.xlsx"));
            workbook.write(out);
            out.close();

            System.out.println("howtodoinjava_demo.xlsx written successfully on disk.");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

1 Ответ

1 голос
/ 24 октября 2019

Для авторазмера столбцов есть Sheet.autoSizeColumn . Там вы можете указать, следует ли рассматривать содержимое объединенных ячеек или игнорировать их. По умолчанию игнорируются объединенные ячейки. Но ваш вопрос не совсем ясен в этом вопросе, поскольку ваш код вообще не объединяет ячейки.

Для стиля строки есть Row.setRowStyle . Excel принимает этот стиль, когда в эту строку добавляются новые ячейки. Но apache poi не ведет себя так. Он всегда использует стиль ячейки по умолчанию для новых созданных ячеек. Поэтому нам нужен метод CellStyle getPreferredCellStyle(Cell cell), который получает предпочтительный стиль ячейки для данной ячейки, как это сделал бы Excel.

И, так как вы спрашиваете о передовой практике, пожалуйста, используйте org.apache.poi.ss.usermodel.* до тех пор, покакак возможно. Таким образом, код способен обрабатывать HSSF и XSSF без особых изменений.

Пример:

import java.io.File;
import java.io.FileOutputStream;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFCell;

public class WriteExcelDemo {

 static 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;
 }

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

  // Blank workbook XSSF or HSSF
  Workbook workbook = new XSSFWorkbook();
  //Workbook workbook = new HSSFWorkbook();

  // Create needed cell styles on workbook level
  Font boldFont = workbook.createFont();
  boldFont.setBold(true);
  CellStyle headerRowStyle = workbook.createCellStyle();
  headerRowStyle.setFont(boldFont);


  // This data needs to be written (Object[])
  Map<String, Object[]> data = new TreeMap<String, Object[]>();
  data.put("1", new Object[] {"ID", "NAME", "LASTNAME"});
  data.put("2", new Object[] {1, "Amit", "Shukla"});
  data.put("3", new Object[] {2, "Lokesh", "Gupta"});
  data.put("4", new Object[] {3, "John", "Adwards"});
  data.put("5", new Object[] {4, "Brian", "Schultz"});

  // Create a blank sheet
  Sheet sheet = workbook.createSheet("Employee Data");

  // Iterate over data and write to sheet
  Set<String> keyset = data.keySet();
  int rownum = 0;
  for (String key : keyset) {
   Row row = sheet.createRow(rownum++);
   if (rownum == 1) row.setRowStyle(headerRowStyle); // row style for first row; Excel takes that style when new cells are added to this row
   Object[] objArr = data.get(key);
   int cellnum = 0;
   for (Object obj : objArr) {
    Cell cell = row.createCell(cellnum++);
    cell.setCellStyle(getPreferredCellStyle(cell)); // set the preferred cell style for the new cell as Excel would do
    if (obj instanceof String)
     cell.setCellValue((String) obj);
    else if (obj instanceof Integer)
     cell.setCellValue((Integer) obj);
   }
  }

  for (int c = 0; c < data.get("1").length; c++) {
   //sheet.autoSizeColumn(c); // autosize, merged cells should be ignored
   sheet.autoSizeColumn(c, true); // autosize, merged cells should be considered
  }

  // Write the workbook in file system
  String filepath = (workbook instanceof XSSFWorkbook)?"./howtodoinjava_demo.xlsx":"./howtodoinjava_demo.xls";
  FileOutputStream out = new FileOutputStream(new File(filepath));
  workbook.write(out);
  out.close();
  workbook.close();

  System.out.println("howtodoinjava_demo.xlsx written successfully on disk.");
 }
}
...