excel導出工具java
整個項目的代碼結構以下git
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導出能夠分爲幾步github
首先實例化ExportExcel工具類,我這裏提供了三個構造函數spring
public ExportExcel() public ExportExcel(SXSSFWorkbook workbook) public ExportExcel(SXSSFWorkbook workbook, AbstractCellStyle titleCellStyle, AbstractCellStyle dataCellStyle) 複製代碼
一般使用的是無參構造函數。另外兩個都須要本身實例化workbook對象,有三個參數的構造函數,須要傳入workbook、標題行樣式對象、數據行樣式對象。關於樣式對象下方有說明。springboot
實例化ExportExcel工具類以後,須要調用exportExcel方法,方法定義以下bash
public void exportExcel(String sheetName, BaseParam baseParam, OutputStream out)
複製代碼
參數名稱 | 參數內容 |
---|---|
sheetName | 工做表(sheet)的名稱 |
baseParam | 繼承BaseParam的導出參數對象(後面會說明) |
out | OutputStream對象、例如FileOutputStream |
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();
複製代碼
經過這兩個方法能夠修改單元格的樣式和字體。app
BaseParam類代碼以下ide
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
public class ColumnParam{
private String headerName;
private String fieldName;
private DataExportConversion conversion;//數據轉換
//Set Get Constructor
}
複製代碼
屬性名稱 | 屬性內容 |
---|---|
headerName | 標題名稱 |
fieldName | 實體類對應的屬性名 |
conversion | 數據轉換對象 |
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個列參數
先寫一個生成數據的方法,以下
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到文件
@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();
}
複製代碼
@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…,有須要的能夠去下載。