介紹
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物件) |
---|---|---|---|
塵心 | 0 | 2018-08-08 14:59:11 | [舞刀,弄槍] |
千月 | 1 | 2018-08-08 14:59:11 | [唱歌,跳舞] |
需要轉換為下方內容
姓名 | 性別 | 出生日期 | 愛好 |
---|---|---|---|
塵心 | 女 | 2018-08-08 14:59:11 | 舞刀,弄槍 |
千月 | 男 | 2018-08-08 14:59:11 | 唱歌,跳舞 |
實體類如下
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();
}
複製程式碼
專案位置:github.com/rainbowda/u…,有需要的可以去下載。