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方法,方法定義以下多線程
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,能夠實現下方兩個方法app
// 設置樣式 protected abstract void setStyle(); // 設置字體 protected abstract void setFont();
經過這兩個方法能夠修改單元格的樣式和字體。ide
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
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(); }
項目位置:https://github.com/rainbowda/utils/tree/master/excel_export,有須要的能夠去下載。