1. 程式人生 > 其它 >Hutool工具包Excel工具使用

Hutool工具包Excel工具使用

技術標籤:實操經驗總結# 程式碼編寫java

參考自:https://blog.csdn.net/qq_43230007/article/details/107216171

一、匯入依賴

<!-- hutool工具類依賴-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.3</version>
</dependency>

<!--POI依賴,對office進行操作-->
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency>

二、寫入Excel

Hutool將Excel寫出封裝為ExcelWriter,原理為包裝了Workbook物件,每次呼叫merge(合併單元格)或者write(寫出資料)方法後只是將資料寫入到Workbook,並不寫出檔案,只有呼叫flush或者close方法後才會真正寫出檔案。由於機制原因,在寫出結束後需要關閉ExcelWriter物件,呼叫close方法即可關閉,此時才會釋放Workbook物件資源,否則帶有資料的Workbook一直會常駐記憶體。程式碼如下所示:


通過write()方法寫出,write方法如下

public ExcelWriter write(Iterable<?> data) {
    return this.write(data, 0 == this.getCurrentRow());
}

可以看見,引數為實現了Iterable介面的型別。Collection介面實現了該介面,所以,List和Map都可以作為引數。

public interface Collection<E> extends Iterable<E> {

1.寫出List資料

1.1 製造我們的rows集合物件

List<
String>
row1 = CollUtil.newArrayList("aa", "bb", "cc", "dd"); List<String> row2 = CollUtil.newArrayList("aa1", "bb1", "cc1", "dd1"); List<String> row3 = CollUtil.newArrayList("aa2", "bb2", "cc2", "dd2"); List<String> row4 = CollUtil.newArrayList("aa3", "bb3", "cc3", "dd3"); List<String> row5 = CollUtil.newArrayList("aa4", "bb4", "cc4", "dd4"); List<List<String>> rows = CollUtil.newArrayList(row1, row2, row3, row4, row5);

1.2 將我們的物件寫出

//通過工具類建立writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeTest.xlsx");
//通過構造方法建立writer
//ExcelWriter writer = new ExcelWriter("d:/writeTest.xls");

//跳過當前行,既第一行,非必須,在此演示用
writer.passCurrentRow();

//合併單元格後的標題行,使用預設標題樣式
writer.merge(row1.size() - 1, "測試標題");
//一次性寫出內容,強制輸出標題
writer.write(rows, true);
//關閉writer,釋放記憶體
writer.close();

2. 寫出Map資料

1.1 製造我們的Map物件

Map<String, Object> row1 = new LinkedHashMap<>();
row1.put("姓名", "張三");
row1.put("年齡", 23);
row1.put("成績", 88.32);
row1.put("是否合格", true);
row1.put("考試日期", DateUtil.date());

Map<String, Object> row2 = new LinkedHashMap<>();
row2.put("姓名", "李四");
row2.put("年齡", 33);
row2.put("成績", 59.50);
row2.put("是否合格", false);
row2.put("考試日期", DateUtil.date());

ArrayList<Map<String, Object>> rows = CollUtil.newArrayList(row1, row2);

1.2 寫出我們的rows物件

// 通過工具類建立writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeMapTest.xlsx");
// 合併單元格後的標題行,使用預設標題樣式
writer.merge(row1.size() - 1, "一班成績單");
// 一次性寫出內容,使用預設樣式,強制輸出標題
writer.write(rows, true);
// 關閉writer,釋放記憶體
writer.close();

3. 寫出我們的Bean物件

1.1 製造我們的Bean資料

TestBean bean1 = new TestBean();
bean1.setName("張三");
bean1.setAge(22);
bean1.setPass(true);
bean1.setScore(66.30);
bean1.setExamDate(DateUtil.date());

TestBean bean2 = new TestBean();
bean2.setName("李四");
bean2.setAge(28);
bean2.setPass(false);
bean2.setScore(38.50);
bean2.setExamDate(DateUtil.date());

List<TestBean> rows = CollUtil.newArrayList(bean1, bean2);

1.2 寫出我們的Rows物件

// 通過工具類建立writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeBeanTest.xlsx");
// 合併單元格後的標題行,使用預設標題樣式
writer.merge(4, "一班成績單");
// 一次性寫出內容,使用預設樣式,強制輸出標題
writer.write(rows, true);
// 關閉writer,釋放記憶體
writer.close();

4. 自定義Bean的key別名

// 通過工具類建立writer
ExcelWriter writer = ExcelUtil.getWriter("d:/writeBeanTest.xlsx");

//自定義標題別名
writer.addHeaderAlias("name", "姓名");
writer.addHeaderAlias("age", "年齡");
writer.addHeaderAlias("score", "分數");
writer.addHeaderAlias("isPass", "是否通過");
writer.addHeaderAlias("examDate", "考試時間");

// 合併單元格後的標題行,使用預設標題樣式
writer.merge(4, "一班成績單");
// 一次性寫出內容,使用預設樣式,強制輸出標題
writer.write(rows, true);
// 關閉writer,釋放記憶體
writer.close();

5. 寫出到IO流

// 通過工具類建立writer,預設建立xls格式
ExcelWriter writer = ExcelUtil.getWriter();
//建立xlsx格式的
//ExcelWriter writer = ExcelUtil.getWriter(true);
// 一次性寫出內容,使用預設樣式,強制輸出標題
writer.write(rows, true);
//out為OutputStream,需要寫出到的目標流
writer.flush(out);
// 關閉writer,釋放記憶體
writer.close();

6. 寫出到客戶端下載(寫出到Servlet)

1.1 寫出xls

// 通過工具類建立writer,預設建立xls格式
ExcelWriter writer = ExcelUtil.getWriter();
// 一次性寫出內容,使用預設樣式,強制輸出標題
writer.write(rows, true);
//out為OutputStream,需要寫出到的目標流

//response為HttpServletResponse物件
response.setContentType("application/vnd.ms-excel;charset=utf-8"); 
//test.xls是彈出下載對話方塊的檔名,不能為中文,中文請自行編碼
response.setHeader("Content-Disposition","attachment;filename=test.xls"); 
ServletOutputStream out=response.getOutputStream(); 

writer.flush(out, true);
// 關閉writer,釋放記憶體
writer.close();
//此處記得關閉輸出Servlet流
IoUtil.close(out);

1.2 寫出xlsx

ExcelWriter writer = ExcelUtil.getWriter(true);
writer.write(rows, true);

response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); 
response.setHeader("Content-Disposition","attachment;filename=test.xlsx"); 

writer.flush(out, true);
writer.close();
IoUtil.close(out);

Writer方法的使用補充

1. 設定單元格背景色

// 定義單元格背景色
StyleSet style = writer.getStyleSet();
// 第二個引數表示是否也設定頭部單元格背景
style.setBackgroundColor(IndexedColors.RED, false);
Copy to clipboardErrorCopied

2. 自定義字型

ExcelWriter writer = ...;
//設定內容字型
Font font = writer.createFont();
font.setBold(true);
font.setColor(Font.COLOR_RED); 
font.setItalic(true); 
//第二個引數表示是否忽略頭部樣式
writer.getStyleSet().setFont(font, true);
Copy to clipboardErrorCopied

3. 寫出多個sheet

//初始化時定義表名
ExcelWriter writer = new ExcelWriter("d:/aaa.xls", "表1");
//切換sheet,此時從第0行開始寫
writer.setSheet("表2");
...
writer.setSheet("表3");
...
Copy to clipboardErrorCopied

4. 更詳細的定義樣式

在Excel中,由於樣式物件個數有限制,因此Hutool根據樣式種類分為4個樣式物件,使相同型別的單元格可以共享樣式物件。樣式按照類別存在於StyleSet中,其中包括:

頭部樣式 headCellStyle
普通單元格樣式 cellStyle
數字單元格樣式 cellStyleForNumber
日期單元格樣式 cellStyleForDate
其中cellStyleForNumber cellStyleForDate用於控制數字和日期的顯示方式。

因此我們可以使用以下方式獲取CellStyle物件自定義指定種類的樣式:

StyleSet style = writer.getStyleSet();
CellStyle cellStyle = style.getHeadCellStyle();
...

三、讀取Excel

1.讀取Excel中所有行和列,都用列表表示

ExcelReader reader = ExcelUtil.getReader("d:/aaa.xlsx");
List<List<Object>> readAll = reader.read();

2.讀取為Map列表,預設第一行為標題行,Map中的key為標題,value為標題對應的單元格值。

ExcelReader reader = ExcelUtil.getReader("d:/aaa.xlsx");
List<Map<String,Object>> readAll = reader.readAll();

3.讀取為Bean列表,Bean中的欄位名為標題,欄位值為標題對應的單元格值。

ExcelReader reader = ExcelUtil.getReader("d:/aaa.xlsx");
List<Person> all = reader.readAll(Person.class);

示例

  • 讀取方法
public void readExcel(){
    ExcelReader reader = ExcelUtil.getReader("H:\\user.xlsx");
    List<UserDTO> userDTOS = reader.readAll(UserDTO.class);
    //日誌輸出讀取到的資訊
    log.info(userDTOS.toString());
}
  • UserDTO類如下
@Data
public class UserDTO {
    @NotNull(message = "使用者id不能為空")
    private Integer id;

    @NotNull(message = "使用者名稱不能為空")
    @Size(min = 4, max = 16, message = "使用者名稱長度錯誤")
    private String userName;

    @NotNull(message = "密碼不能為空")
    @Size(min = 4, max = 16, message = "密碼長度錯誤")
    private String loginPassword;

    @NotNull(message = "郵箱不能為空")
    @Email(message = "郵箱格式錯誤")
    private String email;


    @NotNull(message = "日期不能為空")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private Date createDate;
}
  • excel如下

    在這裡插入圖片描述