使用POI来做报表

如果你的项目要使用数据报表,Apache POI可以通过Exlce用来读取,合并和格式化你的数据

Apache POI就是用来读取word和Excle文档的java库,下面来看看使用方式

1. 添加maven依赖
<poi.version>3.15poi.version>
...
<dependency>
  <groupId>org.apache.poigroupId>
  <artifactId>poi-ooxmlartifactId>
  <version>${poi.version}version>
dependency>
2.基本使用
  • 实例XSSFWorkbook类来新建一个Excel 2007文件:

    Workbook wb = new XSSFWorkbook();
  • 如果要新建Excel 97-2003文件,实例化下面的类:

    Workbook wb = new HSSFWorkbook();
  • 下面是创建空表:

    Workbook wb = new XSSFWorkbook();
    //创建空的excel表
    String safeName = WorkbookUtil.createSafeSheetName("Population");
    Sheet sheet = wb.createSheet(safeName);
    FileOutputStream fileOut = new FileOutputStream("hello.xlsx");
    wb.write(fileOut);
    fileOut.close();
  • 创建一个行:

    int rowNum = 0;
    Row row = sheet.createRow((short)rowNum);
  • 往第一行添加内容,一般第一行我们可以作为标题行:

    row.createCell(0).setCellValue(ch.createRichTextString("Rank"));
    row.createCell(1).setCellValue(ch.createRichTextString("Country"));
    row.createCell(2).setCellValue(ch.createRichTextString("Total(persons)"));
    row.createCell(3).setCellValue(ch.createRichTextString("per sq.km"));
    row.createCell(4).setCellValue(ch.createRichTextString("Date"));
  • 效果:
    这里写图片描述

  • 自动拉开单元格大小:

    通过上图可以看出有些单元格的内容显示不全,通过下面代码控制自动放大单元格大小:

    for (short i = sheet.getRow(0).getFirstCellNum(),
      end = sheet.getRow(0).getLastCellNum() ; i < end ; i++) {
      sheet.autoSizeColumn(i);
    }
  • 单元格换行换行显示内容,如:

    Cell cell = row.createCell(2);
    cell.setCellValue("Total\r\n(persons)");

    一旦数据被填充到单元格里面,可以设置单元格的样式允许包装:

    CellStyle style = sheet.getWorkbook().createCellStyle();
    style.setWrapText(true);
    cell.setCellStyle(style);
  • 效果:
    使用POI来做报表_第1张图片

  • 多行添加:

    创建数组集合:

    List<List<String>> list = Arrays
      .asList(Arrays.asList("1","China","1,378,020,000","147.75","2016"),
      Arrays.asList("2","India","1,266,884,000","426.10","2016 WFB"),
      Arrays.asList("3","United States of America","323,128,000","35.32","2016"),
      Arrays.asList("4","Indonesia","257,453,000","142.12","2016"),
      Arrays.asList("5","Brazil","206,081,000","24.66","2016"));

    将数组集合添加到每行中:

    for (List arr : list) {
      row = sheet.createRow(rowNum); rowNum++;
      row.createCell(0).setCellValue(arr.get(0));
      row.createCell(1).setCellValue(arr.get(1));
      row.createCell(2).setCellValue(arr.get(2));
      row.createCell(3).setCellValue(arr.get(3));
      row.createCell(4).setCellValue(arr.get(4));
    }
  • 效果
    使用POI来做报表_第2张图片

  • 固定数字存储作为文本

    比如第一列定义为数字:

    int value = Integer.parseInt(arr.get(0));
    row.createCell(0).setCellValue(value);

    比如第三列为浮点型:

    double value = Double.parseDouble(arr.get(3));
    row.createCell(3).setCellValue(value);
  • 效果:
    使用POI来做报表_第3张图片

  • 使用数字格式解析:

    对整个字段的修复稍微复杂一些。数字值是用逗号进行格式化的,我们需要解析以获得该值。

    对整个字段的修复稍微复杂一些。数字值是用逗号进行格式化的,我们需要解析以获得该值。
    首先,我们使用正确的语言环境创建NumberFormatwith。我们存储了重复使用的数字格式(每次都不需要重新创建)。

    private NumberFormat fmt = NumberFormat.getInstance(Locale.US);
    Cell cell = row.createCell(2);
    String value = arr.get(2);
    try {
      Number n = fmt.parse(value);
      cell.setCellValue(n.intValue());
    } catch(java.text.ParseException ex) {
      System.err.println("Row " + rowNum + ": " + value + ": " +
                 ex.getMessage());
    }
  • 效果:
    使用POI来做报表_第4张图片

  • 设置单元格样式:

    CellStyle popStyle = workbook.createCellStyle();
    short format = (short)BuiltinFormats.getBuiltinFormat("#,##0");
    popStyle.setDataFormat(format);

    把上面设置好的样式设置到单元格中:

    Cell cell = row.createCell(2);
    String value = arr.get(2);
    try {
      Number n = fmt.parse(value);
      cell.setCellStyle(popStyle);
      cell.setCellValue(n.intValue());
    } catch(java.text.ParseException ex) {
      System.err.println("Row " + rowNum + ": " + value + ": " +
      ex.getMessage());
    }
  • 效果:
    使用POI来做报表_第5张图片

  • 其他格式

    如上图最后一列有数字也有数字字母结合的单元格我们怎么设置样式呢:

    我们需要的最后一点格式化是在日期列上删除“存储为文本的数字”。正如所看到的,有些行有一个整数值,有些行有一个非数值混合的值。我们将按以下方式处理该列。尝试解析一个数字的值,将其设置为一个数字,如果它失败,则将值设置为字符串。

    String value = arr.get(4);
    try {
      int year = Integer.parseInt(value);
      row.createCell(4).setCellValue(year);
    } catch(NumberFormatException ex) {
      row.createCell(4).setCellValue(value);
    }
  • 效果:
    使用POI来做报表_第6张图片

3.进一步使用

让我们看看如何将CSV转换成Excel电子表格。当您尝试导入CSV或文本文件时,Excel提供了数据导入向导的功能。这里,我们将向您展示如何使用Apache POI来解析CSVs并输出一个Excel电子表格。

Workbook wb = new XSSFWorkbook();
CreationHelper ch = wb.getCreationHelper();
String safeName = WorkbookUtil.createSafeSheetName("Population");
Sheet sheet = wb.createSheet(safeName);

try (InputStream in = new FileInputStream(csvFile);) {
    CSV csv = new CSV(true, ',', in);
    List colNames = null;
    if ( csv.hasNext() ) {
    colNames = new ArrayList(csv.next());
    Row row = sheet.createRow((short)0);
    for (int i = 0 ; i < colNames.size() ; i++) {
        String name = colNames.get(i);
        row.createCell(i).setCellValue(name);
    }
    }

    int rowNum = 0;
    while (csv.hasNext()) {
    List fields = csv.next();
    rowNum++;
    Row row = sheet.createRow((short)rowNum);

    /* First 5 fields are text. The next 2 are floating
     * point. */
    for (int i = 0 ; i < 5 ; i++) {
        String value = fields.get(i);
        row.createCell(i).setCellValue(value);
    }

    for (int i = 5 ; i < fields.size() ; i++) {
        /* Attempt to set as double. If that fails, set as
         * text. */
        try {
        double value = Double.parseDouble(fields.get(i));
        row.createCell(i).setCellValue(value);
        } catch(NumberFormatException ex) {
        String value = fields.get(i);
        row.createCell(i).setCellValue(value);
        }
    }
    }
}

for (short i = sheet.getRow(0).getFirstCellNum(),
     end = sheet.getRow(0).getLastCellNum() ; i < end ; i++) {
    sheet.autoSizeColumn(i);
}

FileOutputStream fileOut = new FileOutputStream(xlsFile);
wb.write(fileOut);
fileOut.close();
  • 效果:
    使用POI来做报表_第7张图片

  • 添加自动过滤头:

    为了自动打开对某些或所有数据列的过滤,使用setAutoFilter()方法。下面的代码将对所有列进行自动过滤。

    for (short i = sheet.getRow(0).getFirstCellNum(),
       end = sheet.getRow(0).getLastCellNum() ; i < end ; i++) {
      CellRangeAddress ca =
      new CellRangeAddress(0, rowNum,
                   sheet.getRow(0).getFirstCellNum(),
                   sheet.getRow(0).getLastCellNum());
      sheet.setAutoFilter(ca);
    }
  • 效果:
    使用POI来做报表_第8张图片

  • 日期格式:

    要将单元格格式化为日期,必须将单元格值设置为日期,并将日期格式与单元格关联。

    创建一个具有合适日期格式的单元格样式:

    Workbook wb = new XSSFWorkbook();
    CreationHelper ch = wb.getCreationHelper();
    CellStyle dateStyle = wb.createCellStyle();
    dateStyle.setDataFormat(ch.createDataFormat().getFormat("d-mmm-yy"));

    将文本解析为日期。并将单元格样式与下图相关联。创建和使用单元格样式非常麻烦。创建、存储和重用它以避免重新创建。

    SimpleDateFormat datefmt = new SimpleDateFormat("yyyy-MM-dd");
    ...
    String value = ...;
    Date date = datefmt.parse(value);
    Cell cell = row.createCell(i);
    cell.setCellValue(date);
    cell.setCellStyle(bdateStyle);
  • 单元格对齐选项

    Workbook wb = new XSSFWorkbook();
    CellStyle hcenter = wb.createCellStyle();
    hcenter.setAlignment(HorizontalAlignment.CENTER);
    
    CellStyle hright = wb.createCellStyle();
    hright.setAlignment(HorizontalAlignment.RIGHT);

    设置对每个单元格有效:

    Cell cell = row.createCell(i);
    cell.setCellStyle(hright); // as appropriate
    cell.setCellValue(value);
  • 效果:
    使用POI来做报表_第9张图片

  • 内容环绕

    CellStyle wrap = wb.createCellStyle();
    wrap.setWrapText(true);

你可能感兴趣的:(java进阶)