Hutool工具包Excel工具使用
參考自: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如下