java經過POI和easypoi實現Excel的導出

前言

在工做常常會遇到excel導出報表的功能,本身也作過一些,而後在項目裏看到同事封裝的一個excel導出工具類,着實不錯,拿來分享一下。而後,又在網上看到一個使用easypoi實現cxcel導出的博客,因而本身也仿着搞了一下,在這也分享一下。

使用POI實現excel導出

  • 首先,引入jar包,這是POI須要的jar包。
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>
  • 下面是主要的實現方法。

定義一個函數式接口,用於自定義格式。java

package com.mz.util;

import java.io.IOException;

/**
 * @version V1.0
 * @Description:
 * @date 2018/10/31 17:16
 */
@FunctionalInterface
public interface ExportConsumer<ByteArrayOutputStream, Workbook, List> {
    /**
     *自定義導出數據拼裝
     * @param fileOut 輸出流
     * @param wb workbook對象
     * @param listData 數據集
     * @throws IOException
     */
    void accept(ByteArrayOutputStream fileOut, Workbook wb, List listData) throws IOException;
}
  • 工具類主要方法
package com.mz.util;

import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class POIExportUtil {

 /**
  * 導出excel
  *
  * @param fileOut    輸出流
  * @param wb         excel workbook對象
  * @param listData 須要導出的數據
  * @param consumer   自定義導出excel的格式
  * @param fileName   文件名
  * @return ResponseEntity
  * @throws IOException
  */
 public static <T> ResponseEntity<byte[]> exportExcel(ByteArrayOutputStream fileOut,
                                                        Workbook wb,
                                                        List<T> listData,
                                                        String fileName,
                                                        ExportConsumer<ByteArrayOutputStream, Workbook, List<T>> consumer) throws IOException {
      consumer.accept(fileOut, wb, listData);
      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

      headers.setContentDispositionFormData("attachment", new String((fileName + ".xls").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
      return new ResponseEntity<>(fileOut.toByteArray(), headers, HttpStatus.OK);
    }
}
  • 使用案例,頁面經過<a>標籤訪便可。
//表頭字段名
    private static final String[] COLUMN_NAMES = {"序號", "單號/流水號", "PNR", "業務類", "發生時間", "付款科目", "總金額",
            "預存款期初金額", "預存款發生金額", "預存款期末金額", "授信期初金額", "授信發生金額", "授信期末金額",
            "協議欠款期初金額", "協議欠款發生金額", "協議欠款期末金額", "分銷商", "操做員"};



 /**
     * 導出流水報表
     * @param request
     * @return
     */
    @Override
    public ResponseEntity exportExcel(TradDetailRequest request) {
        ByteArrayOutputStream fileout = new ByteArrayOutputStream();
        try {
            //數據庫的數據
            List<B2bTradedetail> tradeDetailForExport = tradedetailMapper.getTradeDetailForExport(request);
            //建立workbook對象
            Workbook wb = new HSSFWorkbook();
            return POIExportUtil.exportExcel(fileout, wb, tradeDetailForExport, "流水記錄報表",
                    (out, workbook, data) -> createCell(wb, data).write(fileout));
        } catch (Exception e) {
            LOGGER.error("B2bTradedetailServiceImpl.exportExcel:" + e.getMessage());
            return new ResponseEntity<>("導出錯誤!\\n" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        } finally {
            try {
                fileout.close();
            } catch (IOException e) {
                LOGGER.error("B2bTradedetailServiceImpl.exportExcel 輸出流關閉錯誤" + e.getMessage());
            }
        }
    }

    /**
     * 設置excel標題和數據
     * @param wb
     * @param data
     * @return
     */
    private Workbook createCell(Workbook wb, List<B2bTradedetail> data) {
        String safeName = WorkbookUtil.createSafeSheetName("sheet1");
        Sheet sheet = wb.createSheet(safeName);
        //第一行標題
        Row title = sheet.createRow(0);
        for (int i = 0; i < COLUMN_NAMES.length; i++) {
            title.createCell(i).setCellValue(COLUMN_NAMES[i]);
        }
        //插入數據
        data.forEach(b2bTradedetail -> {
            Row row = sheet.createRow(data.indexOf(b2bTradedetail) + 1);
            row.createCell(0).setCellValue(data.indexOf(b2bTradedetail) + 1);
            row.createCell(1).setCellValue(b2bTradedetail.getDealno());
            row.createCell(2).setCellValue(b2bTradedetail.getPnrno());
            row.createCell(3).setCellValue(b2bTradedetail.getOperatetypeno());
            row.createCell(4).setCellValue(b2bTradedetail.getCreatetime());
            row.createCell(5).setCellValue(b2bTradedetail.getPaytypeno());
            row.createCell(6).setCellValue(b2bTradedetail.getTotalmoney());
            row.createCell(7).setCellValue(b2bTradedetail.getAccountbefore());
            row.createCell(8).setCellValue(b2bTradedetail.getAccountmoney());
            row.createCell(9).setCellValue(b2bTradedetail.getAccountafter());
            row.createCell(10).setCellValue(b2bTradedetail.getCreditbefore());
            row.createCell(11).setCellValue(b2bTradedetail.getCreditmoney());
            row.createCell(12).setCellValue(b2bTradedetail.getCreditafter());
            row.createCell(13).setCellValue(b2bTradedetail.getProtocoldebtbefore());
            row.createCell(14).setCellValue(b2bTradedetail.getProtocoldebtmoney());
            row.createCell(15).setCellValue(b2bTradedetail.getProtocoldebtafter());
            row.createCell(16).setCellValue(b2bTradedetail.getCompid());
            row.createCell(17).setCellValue(b2bTradedetail.getOperatorid());
        });
        return wb;
    }

使用easypoi實現,這裏直接是一個工具類和使用案例,關於這個教程能夠參考easypoi教程

  • 先導入jar包
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-base</artifactId>
    <version>3.2.0</version>
</dependency>

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-web</artifactId>
    <version>3.2.0</version>
</dependency>

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-annotation</artifactId>
    <version>3.2.0</version>
</dependency>
  • 一個實體類,報表的主要數據。
package com.mz.entity;

import cn.afterturn.easypoi.excel.annotation.Excel;

import java.io.Serializable;
import java.util.Date;

/**
 * @version V1.0
 * @Description:
 * @date 2018/10/31 15:31
 */
public class StudentEntity implements Serializable {

    /**
     * id
     */
    private String id;
    /**
     * 學生姓名
     */
    @Excel(name = "姓名", isImportField = "true_st")
    private String name;
    /**
     * 學生性別
     */
    @Excel(name = "性別", replace = { "男_1", "女_2" }, isImportField = "true_st")
    private int sex;

    @Excel(name = "出生日期", databaseFormat = "yyyyMMddHHmmss", format = "yyyy-MM-dd", isImportField = "true_st")
    private Date birthday;

    @Excel(name = "進校日期", databaseFormat = "yyyyMMddHHmmss", format = "yyyy-MM-dd")
    private Date registrationDate;

    public StudentEntity(String id, String name, int sex, Date birthday, Date registrationDate) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.birthday = birthday;
        this.registrationDate = registrationDate;
    }

    //省略setter getter方法
  • 工具類方法,包含兩個excel的方法,沒有測試過。
package com.mz.util;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * @version V1.0
 * @Description: Excel導出工具類
 * @date 2018/10/31 19:16
 */
public class ExportExcelUtil {
    /**
     * 
     * @param list 數據集合
     * @param title 內容標題
     * @param sheetName excel名稱
     * @param pojoClass 實體類
     * @param fileName 導出的文件名
     * @param isCreateHeader 是否建立excel表頭
     * @param response 響應
     */
    public static void exportExcel(List<?> list,
                                   String title,
                                   String sheetName,
                                   Class<?> pojoClass,
                                   String fileName,
                                   boolean isCreateHeader,
                                   HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setCreateHeadRows(isCreateHeader);
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    /**
     * 導出
     * @param list 數據集合
     * @param title 內容標題
     * @param sheetName excel名稱
     * @param pojoClass 實體類
     * @param fileName 導出的文件名
     * @param response 響應
     */
    public static void exportExcel(List<?> list,
                                   String title,
                                   String sheetName,
                                   Class<?> pojoClass,
                                   String fileName,
                                   HttpServletResponse response){
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
    }

    /**
     * 導出 無內容標題和excel表名
     * @param list
     * @param pojoClass
     * @param fileName
     * @param response
     */
    public static void exportExcel(List<?> list,
                                   Class<?> pojoClass,
                                   String fileName,
                                   HttpServletResponse response) {
        defaultExport(list, pojoClass, fileName, response, new ExportParams());
    }

    /**
     * 導出
     * @param list 數據集合
     * @param fileName 導出的文件名
     * @param response 響應
     */
    public static void exportExcel(List<Map<String, Object>> list,
                                   String fileName,
                                   HttpServletResponse response){
        defaultExport(list, fileName, response);
    }

    /**
     *
     * @param list 數據集合
     * @param pojoClass  實體類
     * @param fileName  導出的文件名
     * @param response 響應
     * @param exportParams
     */
    private static void defaultExport(List<?> list,
                                      Class<?> pojoClass,
                                      String fileName,
                                      HttpServletResponse response,
                                      ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams,pojoClass,list);
        if (workbook != null) {
            doExport(fileName, response, workbook);
        }
    }

    /**
     *
     * @param list 數據集合
     * @param fileName 導出的文件名
     * @param response 響應
     */
    private static void defaultExport(List<Map<String, Object>> list,
                                      String fileName,
                                      HttpServletResponse response) {
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        if (workbook != null){
            doExport(fileName, response, workbook);
        }
    }

    /**
     * 導出
     * @param fileName  導出的文件名
     * @param response 響應
     * @param workbook 工做表
     */
    private static void doExport(String fileName,
                                      HttpServletResponse response,
                                      Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new NormalException(e.getMessage());
        }
    }


    /**
     *
     * @param filePath
     * @param titleRows
     * @param headerRows
     * @param pojoClass
     * @param <T>
     * @return
     */
    public static <T> List<T> importExcel(String filePath,
                                          Integer titleRows,
                                          Integer headerRows,
                                          Class<T> pojoClass) {
        if (StringUtils.isBlank(filePath)){
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        }catch (NoSuchElementException e){
            throw new NormalException("模板不能爲空");
        } catch (Exception e) {
            e.printStackTrace();
            throw new NormalException(e.getMessage());
        }
        return list;
    }

    /**
     *
     * @param file
     * @param titleRows
     * @param headerRows
     * @param pojoClass
     * @param <T>
     * @return
     */
    public static <T> List<T> importExcel(MultipartFile file,
                                          Integer titleRows,
                                          Integer headerRows,
                                          Class<T> pojoClass){
        if (file == null){
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        }catch (NoSuchElementException e){
            throw new NormalException("excel文件不能爲空");
        } catch (Exception e) {
            throw new NormalException(e.getMessage());
        }
        return list;
    }

}
  • 使用案例,能夠寫一個Controller直接經過瀏覽器訪問。
@RequestMapping(value = "/")
    public void getname(HttpServletResponse response) {
        List<StudentEntity> list = new ArrayList<>();
        StudentEntity studentEntity = new StudentEntity("a","路飛",1,new Date(),new Date());
        StudentEntity studentEntity1 = new StudentEntity("a","路飛",1,new Date(),new Date());
        StudentEntity studentEntity2 = new StudentEntity("a","路飛",1,new Date(),new Date());
        StudentEntity studentEntity3 = new StudentEntity("a","路飛",1,new Date(),new Date());
        StudentEntity studentEntity4 = new StudentEntity("a","路飛",1,new Date(),new Date());
        list.add(studentEntity);
        list.add(studentEntity1);
        list.add(studentEntity2);
        list.add(studentEntity3);
        list.add(studentEntity4);

                ExportExcelUtil.exportExcel(list, StudentEntity.class, "學生報表", response);



//      response.setHeader("content-Type", "application/vnd.ms-excel");
//      response.setHeader("Content-Disposition", "attachment;filename=" + System.currentTimeMillis() + ".xls");
//      response.setCharacterEncoding("UTF-8");

//      Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("","學生"),
//              StudentEntity.class, list);

//      ExportExcelUtil.exportExcel(list,"學生信息", "學生",StudentEntity.class,
//              "學生報表", true, response);

//      if (workbook != null) {
//          try {
//              workbook.write(response.getOutputStream());
//          } catch (IOException e) {
//              e.printStackTrace();
//          }
//      }
        //return "Hello Spring Boot";
    }

*導入報表使用web

<form id="loginForm" method="post" action="/import" enctype="multipart/form-data">
        <ul>
            <li>
                <span>上&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;傳:</span>
                <span class="input">
               <input type="file" id="file" name="file"/>
                </span>
                <input type="submit" placeholder="提交">
            </li>
        </ul>
    </form> 

@RequestMapping(value = "/import", method = RequestMethod.POST)
    public void importExcel(@RequestParam("file") MultipartFile file) {
        System.out.println("進來了");
        System.out.println("名字:" + file.getName());
        List<StudentEntity> personList = ExportExcelUtil.importExcel(file, 0,1, StudentEntity.class);
        System.out.println(personList.size());
        personList.forEach(stu -> {
            System.out.println(stu.getName() + " " + stu.getRegistrationDate() + " " + stu.getSex());
        });
        System.out.println("導入數據一共【"+personList.size()+"】行");
    }

小結

報表在工做中遇到的還算多,總結一下方便之後使用。
相關文章
相關標籤/搜索