1. 程式人生 > >EasyPOI 教程以及完整工具類的使用

EasyPOI 教程以及完整工具類的使用

因為專案的原因需要用到POI來操作Excel 文件,以前都是直接使用POI來操作的,但是最近聽到easypoi的存在,所以自己簡單的嘗試了下! 別說,他還真的挺好用的

Easypoi介紹

Easypoi 為誰而開發

  • 不太熟悉poi的
  • 不想寫太多重複太多的
  • 只是簡單的匯入匯出的
  • 喜歡使用模板的

都可以使用easypoi

Easypoi的目標是什麼 Easypoi的目標不是替代poi,而是讓一個不懂匯入匯出的快速使用poi完成Excel和word的各種操作,而不是看很多api才可以完成這樣工作

為什麼會寫Easypoi

以前的以前(歲月真TMD的快)我雖然寫了不少程式碼但還是很少寫poi,然後跳到一家公司之後就和業務人員聊上了,來這個需要個報表,這個報表樣式是這樣的,這個表頭是這樣的,就這樣我寫了大量的poi程式碼,每次都是大量的篇幅,copy to copy,無聊的一逼,然後加入了jeecg,jeecg中有一個小的工具類,雖然我也不知道是誰寫的,然是可以用註解搞定最簡單的匯出,突然豁然開朗,我可以完善,讓我從報表的苦海當中脫離出來,這樣我花了一週的時間做了第一個版本支援匯入匯出放到了jeecg,發現還是不錯的,慢慢的用的人越來越多,我就把這塊獨立出來了,再然後有人提出了模板,然後就加入了模板功能,提出了word的需求,加入了word的功能,後來工作忙了雖然沒再參與jeecg,但還是一直維持這easypoi的更新,根據見識的增長也不斷的重構這程式碼,直到現在

獨特的功能

  • 基於註解的匯入匯出,修改註解就可以修改Excel
  • 支援常用的樣式自定義
  • 基於map可以靈活定義的表頭欄位
  • 支援一堆多的匯出,匯入
  • 支援模板的匯出,一些常見的標籤,自定義標籤
  • 支援HTML/Excel轉換,如果模板還不能滿足使用者的變態需求,請用這個功能
  • 支援word的匯出,支援圖片,Excel

使用

  • 1.easypoi 父包--作用大家都懂得
  • 2.easypoi-annotation 基礎註解包,作用與實體物件上,拆分後方便maven多工程的依賴管理
  • 3.easypoi-base 匯入匯出的工具包,可以完成Excel匯出,匯入,Word的匯出,Excel的匯出功能
  • 4.easypoi-web 耦合了spring-mvc 基於AbstractView,極大的簡化spring-mvc下的匯出功能
  • 5.sax 匯入使用xercesImpl這個包(這個包可能造成奇怪的問題哈),word匯出使用poi-scratchpad,都作為可選包了

如果不使用spring mvc的便捷福利,直接引入easypoi-base 就可以了,easypoi-annotation

如果使用maven,請使用如下座標

<dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>3.1.0</version>
        </dependency>

註解

註解介紹

easypoi起因就是Excel的匯入匯出,最初的模板是實體和Excel的對應,model--row,filed--col 這樣利用註解我們可以和容易做到excel到匯入匯出 經過一段時間發展,現在註解有5個類分別是

  • @Excel 作用到filed上面,是對Excel一列的一個描述
  • @ExcelCollection 表示一個集合,主要針對一對多的匯出,比如一個老師對應多個科目,科目就可以用集合表示
  • @ExcelEntity 表示一個繼續深入匯出的實體,但他沒有太多的實際意義,只是告訴系統這個物件裡面同樣有匯出的欄位
  • @ExcelIgnore 和名字一樣表示這個欄位被忽略跳過這個導匯出
  • @ExcelTarget 這個是作用於最外層的物件,描述這個物件的id,以便支援一個物件可以針對不同匯出做出不同處理

@Excel

這個是必須使用的註解,如果需求簡單隻使用這一個註解也是可以的,涵蓋了常用的Excel需求,需要大家熟悉這個功能,主要分為基礎,圖片處理,時間處理,合併處理幾塊,name_id是上面講的id用法,這裡就不累言了

屬性 型別 預設值 功能

name

String

null

列名,支援name_id

needMerge

boolean

fasle

是否需要縱向合併單元格(用於含有list中,單個的單元格,合併list建立的多個row)

orderNum

String

"0"

列的排序,支援name_id

replace

String[]

{}

值得替換 匯出是{a_id,b_id} 匯入反過來

savePath

String

"upload"

匯入檔案儲存路徑,如果是圖片可以填寫,預設是upload/className/ IconEntity這個類對應的就是upload/Icon/

type

int

1

匯出型別 1 是文字 2 是圖片,3 是函式,10 是數字 預設是文字

width

double

10

列寬

height

double

10

列高,後期打算統一使用@ExcelTarget的height,這個會被廢棄,注意

isStatistics

boolean

fasle

自動統計資料,在追加一行統計,把所有資料都和輸出 這個處理會吞沒異常,請注意這一點

isHyperlink

boolean

false

超連結,如果是需要實現介面返回物件

isImportField

boolean

true

校驗欄位,看看這個欄位是不是匯入的Excel中有,如果沒有說明是錯誤的Excel,讀取失敗,支援name_id

exportFormat

String

""

匯出的時間格式,以這個是否為空來判斷是否需要格式化日期

importFormat

String

""

匯入的時間格式,以這個是否為空來判斷是否需要格式化日期

format

String

""

時間格式,相當於同時設定了exportFormat 和 importFormat

databaseFormat

String

"yyyyMMddHHmmss"

匯出時間設定,如果欄位是Date型別則不需要設定 資料庫如果是string 型別,這個需要設定這個資料庫格式,用以轉換時間格式輸出

numFormat

String

""

數字格式化,引數是Pattern,使用的物件是DecimalFormat

imageType

int

1

匯出型別 1 從file讀取 2 是從資料庫中讀取 預設是檔案 同樣匯入也是一樣的

suffix

String

""

文字字尾,如% 90 變成90%

isWrap

boolean

true

是否換行 即支援\n

mergeRely

int[]

{}

合併單元格依賴關係,比如第二列合併是基於第一列 則{0}就可以了

mergeVertical

boolean

fasle

縱向合併內容相同的單元格

fixedIndex

int

-1

對應excel的列,忽略名字

isColumnHidden

boolean

false

匯出隱藏列

@ExcelTarget

限定一個到處實體的註解,以及一些通用設定,作用於最外面的實體

屬性 型別 預設值 功能

value

String

null

定義ID

height

double

10

設定行高

fontSize

short

11

設定文字大小

@ExcelEntity

標記是不是匯出excel 標記為實體類,一遍是一個內部屬性類,標記是否繼續穿透,可以自定義內部id

屬性 型別 預設值 功能

id

String

null

定義ID

@ExcelCollection

一對多的集合註解,用以標記集合是否被資料以及集合的整體排序

屬性 型別 預設值 功能

id

String

null

定義ID

name

String

null

定義集合列名,支援nanm_id

orderNum

int

0

排序,支援name_id

type

Class<?>

ArrayList.class

匯入時建立物件使用

@ExcelIgnore

忽略這個屬性,多使用需迴圈引用中,無需多解釋吧^^

 接下來就是實戰了:

首先是實體類:

接下來是工具類的編寫:

package com.example.easypoi.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;

/**
 * @Auther: lijiawei
 * @Date: 2018/7/23 12:08
 * @Description: Excle 檔案匯入匯出Util(easypoi)
 */
public class EasyPoiUtil {
   /**
    * 功能描述:複雜匯出Excel,包括檔名以及表名。建立表頭
    *
    * @author 李家威
    * @date 2018/7/23 13:07
    * @param list 匯出的實體類
    * @param title 表頭名稱
    * @param sheetName sheet表名
    * @param pojoClass 對映的實體類
    * @param isCreateHeader 是否建立表頭
    * @param fileName
    * @param response
    * @return 
   */
    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);
    }


    /**
     * 功能描述:複雜匯出Excel,包括檔名以及表名,不建立表頭
     *
     * @author 李家威
     * @date 2018/7/23 13:07
     * @param list 匯出的實體類
     * @param title 表頭名稱
     * @param sheetName sheet表名
     * @param pojoClass 對映的實體類
     * @param fileName
     * @param response
     * @return
     */
    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));
    }

    /**
     * 功能描述:Map 集合匯出
     *
     * @author 李家威
     * @date 2018/7/23 16:14
     * @param list 實體集合
     * @param fileName 匯出的檔名稱
     * @param response
     * @return
    */
    public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        defaultExport(list, fileName, response);
    }

    /**
     * 功能描述:預設匯出方法
     *
     * @author 李家威
     * @date 2018/7/23 15:33
     * @param list 匯出的實體集合
     * @param fileName 匯出的檔名
     * @param pojoClass pojo實體
     * @param exportParams ExportParams封裝實體
     * @param response
     * @return
     */
    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
            downLoadExcel(fileName, response, workbook);
        }
    }

    /**
     * 功能描述:Excel匯出
     *
     * @author 李家威
     * @date 2018/7/23 15:35
     * @param fileName 檔名稱
     * @param response
     * @param workbook Excel物件
     * @return
    */
    private static void downLoadExcel(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"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new  RuntimeException(e);
        }
    }

    /**
     * 功能描述:預設匯出方法
     *
     * @author 李家威
     * @date 2018/7/23 15:33
     * @param list 匯出的實體集合
     * @param fileName 匯出的檔名
     * @param response
     * @return
    */
    private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        if (workbook != null) ;
        downLoadExcel(fileName, response, workbook);
    }
    
    
    /**
     * 功能描述:根據檔案路徑來匯入Excel
     *
     * @author 李家威
     * @date 2018/7/23 14:17 
     * @param filePath 檔案路徑
     * @param titleRows 表標題的行數
     * @param headerRows 表頭行數
     * @param pojoClass Excel實體類
     * @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 RuntimeException("模板不能為空");
        } catch (Exception e) {
            e.printStackTrace();

        }
        return list;
    }

    /**
     * 功能描述:根據接收的Excel檔案來匯入Excel,並封裝成實體類
     *
     * @author 李家威
     * @date 2018/7/23 14:17
     * @param file 上傳的檔案
     * @param titleRows 表標題的行數
     * @param headerRows 表頭行數
     * @param pojoClass Excel實體類
     * @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 RuntimeException("excel檔案不能為空");
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());

        }
        return list;
    }


}

下面是測試類以及結果:

就此,easypoi 的工作就完成了 是不是很簡單