使用POI來做報表

如果你的項目要使用數據報表,Apache POI可以通過Exlce用來讀取,合併和格式化你的數據

Apache POI就是用來讀取word和Excle文檔的java庫,下面來看看使用方式

1. 添加maven依賴
<poi.version>3.15</poi.version>
...
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <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);
  • 效果:
    這裏寫圖片描述

  • 多行添加:

    創建數組集合:

    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<String> 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));
    }
  • 效果
    這裏寫圖片描述

  • 固定數字存儲作爲文本

    比如第一列定義爲數字:

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

    比如第三列爲浮點型:

    double value = Double.parseDouble(arr.get(3));
    row.createCell(3).setCellValue(value);
  • 效果:
    這裏寫圖片描述

  • 使用數字格式解析:

    對整個字段的修復稍微複雜一些。數字值是用逗號進行格式化的,我們需要解析以獲得該值。

    對整個字段的修復稍微複雜一些。數字值是用逗號進行格式化的,我們需要解析以獲得該值。
    首先,我們使用正確的語言環境創建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());
    }
  • 效果:
    這裏寫圖片描述

  • 設置單元格樣式:

    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());
    }
  • 效果:
    這裏寫圖片描述

  • 其他格式

    如上圖最後一列有數字也有數字字母結合的單元格我們怎麼設置樣式呢:

    我們需要的最後一點格式化是在日期列上刪除“存儲爲文本的數字”。正如所看到的,有些行有一個整數值,有些行有一個非數值混合的值。我們將按以下方式處理該列。嘗試解析一個數字的值,將其設置爲一個數字,如果它失敗,則將值設置爲字符串。

    String value = arr.get(4);
    try {
      int year = Integer.parseInt(value);
      row.createCell(4).setCellValue(year);
    } catch(NumberFormatException ex) {
      row.createCell(4).setCellValue(value);
    }
  • 效果:
    這裏寫圖片描述

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<String> colNames = null;
    if ( csv.hasNext() ) {
    colNames = new ArrayList<String>(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<String> 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();
  • 效果:
    這裏寫圖片描述

  • 添加自動過濾頭:

    爲了自動打開對某些或所有數據列的過濾,使用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);
    }
  • 效果:
    這裏寫圖片描述

  • 日期格式:

    要將單元格格式化爲日期,必須將單元格值設置爲日期,並將日期格式與單元格關聯。

    創建一個具有合適日期格式的單元格樣式:

    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);
  • 效果:
    這裏寫圖片描述

  • 內容環繞

    CellStyle wrap = wb.createCellStyle();
    wrap.setWrapText(true);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章