介紹
excel導出工具
整個項目的代碼結構如下
com
\---utils
+---demo # 案例相關
| | ExcelExportApplication.java # springboot啟動類
| |
| +---bean
| | DemoBean.java # 測試bean
| |
| +---controller
| | ExcelExportController.java # 測試url通路彈出下載下傳excel檔案和導出excel到檔案
| |
| \---exportParam
| | DemoExportParam.java # 導出參數
| |
| \---dataConversion
| HobbyConversion.java # 愛好屬性導出轉換類
| SexConversion.java # 性别屬性導出轉換類
|
\---excelExport # 導出工具包
| AsyncExportExcel.java #多線程導出
| ExportExcel.java # 導出工具類
|
+---data
| BaseParam.java # 基礎導出參數類
|
+---dataConversion
| DataExportConversion.java # 屬性導出轉換接口
|
+---defaultDataHandle # 預設的資料處理
| AbstractDataHandler.java
| BooleanDataHandler.java
| DataHandlerFactory.java
| DateDataHandler.java
| StringDataHandler.java
|
\---style # 預設的樣式
AbstractCellStyle.java
DefaultDataCellStyle.java
DefaultTitleCellStyle.java
簡單的來說excel導出可以分為幾步
- 獲得需要導出的資料
- 設定excel的工作表(sheet)名稱
- 設定目前工作表的第一行,也就是标題行
- 将資料逐行填充,有需要的資料進行轉換
使用
ExportExcel工具類
首先執行個體化ExportExcel工具類,我這裡提供了三個構造函數
public ExportExcel()
public ExportExcel(SXSSFWorkbook workbook)
public ExportExcel(SXSSFWorkbook workbook, AbstractCellStyle titleCellStyle, AbstractCellStyle dataCellStyle)
通常使用的是無參構造函數。另外兩個都需要自己執行個體化workbook對象,有三個參數的構造函數,需要傳入workbook、标題行樣式對象、資料行樣式對象。關于樣式對象下方有說明。
執行個體化ExportExcel工具類之後,需要調用exportExcel方法,方法定義如下
public void exportExcel(String sheetName, BaseParam baseParam, OutputStream out)
參數名稱 | 參數内容 |
---|---|
sheetName | 工作表(sheet)的名稱 |
baseParam | 繼承BaseParam的導出參數對象(後面會說明) |
out | OutputStream對象、例如FileOutputStream |
樣式抽象類AbstractCellStyle
public abstract class AbstractCellStyle {
Workbook workbook;
CellStyle style;
Font font;
public AbstractCellStyle(Workbook workbook) {
this.workbook = workbook;
style = workbook.createCellStyle();
font = workbook.createFont();
}
protected abstract void setStyle();
protected abstract void setFont();
public CellStyle getCellStyle() {
style.setFont(font);
return style;
}
}
通過繼承樣式抽象類AbstractCellStyle,可以實作下方兩個方法
// 設定樣式
protected abstract void setStyle();
// 設定字型
protected abstract void setFont();
通過這兩個方法可以修改單元格的樣式和字型。
基礎導出參數類BaseParam
BaseParam類代碼如下
public class BaseParam {
public List data = new ArrayList<>();
public List<ColumnParam> columnParams = new ArrayList<>();
//Set Get Constructor
/**
* 資料行參數
*/
public class ColumnParam{```}
}
屬性
可以看到BaseParam類有兩個屬性
public List data = new ArrayList<>();
public List<ColumnParam> columnParams = new ArrayList<>();
data毫無疑問是存放需要導出的資料,而columnParams是存放每一列的資料,現在來看看内部類ColumnParam
内部類ColumnParam
public class ColumnParam{
private String headerName;
private String fieldName;
private DataExportConversion conversion;//資料轉換
//Set Get Constructor
}
屬性名稱 | 屬性内容 |
---|---|
headerName | 标題名稱 |
fieldName | 實體類對應的屬性名 |
conversion | 資料轉換對象 |
資料轉換接口DataExportConversion
public interface DataExportConversion<T> {
String transferData(T data);
}
比如說,擷取出來的資料是0、1,然後你需要将資料轉換成女、男,那麼就可以實作資料轉換接口DataExportConversion,自定義轉換輸出的格式,代碼如下
public class SexConversion implements DataExportConversion<Integer> {
@Override
public String transferData(Integer data) {
if (0 == data){
return "女";
} else if (1 == data){
return "男";
}
return "不詳";
}
}
案例
場景
原始資料如下
姓名 | 性别 | 出生日期 | 愛好(List對象) |
---|---|---|---|
塵心 | 2018-08-08 14:59:11 | [舞刀,弄槍] | |
千月 | 1 | [唱歌,跳舞] |
需要轉換為下方内容
愛好 | |||
---|---|---|---|
女 | 舞刀,弄槍 | ||
男 | 唱歌,跳舞 |
實體類如下
public class DemoBean {
//姓名
private String name;
//性别,0->女,1->男
private Integer sex;
//出生日期
private Date birthday;
//愛好
private List<String> hobbies;
//Set Get
}
資料轉換
可以看到有兩個屬性需要轉換,分别是性别和愛好。性别的資料轉換上面已經有了,就不貼出來了,下面是愛好的資料轉換
public class HobbyConversion implements DataExportConversion<List<String>> {
@Override
public String transferData(List<String> data) {
StringBuilder hobby = new StringBuilder();
for (String s:data){
hobby.append(s).append(",");
}
//移除最後一個逗号
if (hobby.length() >= 1){
hobby.deleteCharAt(hobby.length()-1);
}
return hobby.toString();
}
}
導出參數類
資料轉換類寫好了之後,開始編寫導出參數類,代碼如下
public class DemoExportParam extends BaseParam {
public DemoExportParam(List<DemoBean> list) {
setData(list);
setColumnParam();
}
private void setColumnParam() {
columnParams.add(new ColumnParam("姓名","name"));
columnParams.add(new ColumnParam("性别","sex", new SexConversion()));
columnParams.add(new ColumnParam("出生日期","birthday"));
columnParams.add(new ColumnParam("愛好","hobbies", new HobbyConversion()));
}
}
在執行個體化DemoExportParam時,需要傳入導出的資料,同時設定每一列對應的列參數ColumnParam。
可以看到總共有4個列參數
- 第一列标題名稱為姓名,對應的屬性名稱為name
- 第二列标題名稱為性别,對應的屬性名稱為sex,還有資料轉換對象SexConversion
- 第三列标題名稱為出生日期,對應的屬性名稱為birthday
- 第四列标題名稱為愛好,對應的屬性名稱為hobbies,資料轉換對象HobbyConversion
導出
先寫一個生成資料的方法,如下
private List<DemoBean> getDemoBeanList(){
DemoBean man = new DemoBean();
DemoBean woman = new DemoBean();
String[] manHobbys = {"舞刀", "弄槍"};
String[] womanHobbys = {"唱歌", "跳舞"};
man.setName("塵心").setBirthday(new Date()).setSex(0).setHobbies(Arrays.asList(manHobbys));
woman.setName("千月").setBirthday(new Date()).setSex(1).setHobbies(Arrays.asList(womanHobbys));
//将兩個bean添加到list中
List<DemoBean> list = new ArrayList<>();
list.add(man);
list.add(woman);
return list;
}
接下來有兩種資料導出方式,一種是url通路彈出下載下傳excel檔案,另外一種是導出excel到檔案
url通路彈出下載下傳excel檔案
@ResponseBody
@RequestMapping("/export")
public void exportByWeb(HttpServletResponse response) throws IOException {
OutputStream out = new BufferedOutputStream(response.getOutputStream());
response.reset();
String headStr = "attachment; filename=" + URLEncoder.encode("導出demo.xlsx", "utf-8");
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", headStr);
//獲得導出資料
List<DemoBean> list = getDemoBeanList();
DemoExportParam demoExportParam = new DemoExportParam(list);
ExportExcel exportExcel = new ExportExcel();
exportExcel.exportExcel("demo", demoExportParam, response.getOutputStream());
out.flush();
out.close();
}
導出excel到檔案
@Test
public void exportByFile() throws IOException {
File file = new File("F:\\導出demo.xlsx");
FileOutputStream out = new FileOutputStream(file);
//獲得導出資料
List<DemoBean> list = getDemoBeanList();
DemoExportParam demoExportParam = new DemoExportParam(list);
ExportExcel exportExcel = new ExportExcel();
exportExcel.exportExcel("demo", demoExportParam, out);
out.flush();
out.close();
}
項目位置:
https://github.com/rainbowda/utils/tree/master/excel_export,有需要的可以去下載下傳。