Springboot使用POI實(shí)現(xiàn)導(dǎo)出Excel文件示例
前面講述了使用POI導(dǎo)出Word文件和讀取Excel文件,這兩個(gè)例子都相對(duì)簡(jiǎn)單,接下來(lái)要講述的使用POI導(dǎo)出Excel文件要復(fù)雜得多,內(nèi)容也會(huì)比較長(zhǎng)。
創(chuàng)建表頭信息
表頭信息用于自動(dòng)生成表頭結(jié)構(gòu)及排序
public class ExcelHeader implements Comparable<ExcelHeader>{ /** * excel的標(biāo)題名稱 */ private String title; /** * 每一個(gè)標(biāo)題的順序 */ private int order; /** * 說(shuō)對(duì)應(yīng)方法名稱 */ private String methodName; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } public int compareTo(ExcelHeader o) { return order>o.order?1:(order<o.order?-1:0); } public ExcelHeader(String title, int order, String methodName) { super(); this.title = title; this.order = order; this.methodName = methodName; } }
表頭信息的Annotation
/** * 用來(lái)在對(duì)象的get方法上加入的annotation,通過(guò)該annotation說(shuō)明某個(gè)屬性所對(duì)應(yīng)的標(biāo)題 * Created by 鐘述林 on 2016/10/29 0:14. */ @Retention(RetentionPolicy.RUNTIME) public @interface ExcelResources { /** * 屬性的標(biāo)題名稱 * @return */ String title(); /** * 在excel的順序 * @return */ int order() default 9999; }
創(chuàng)建數(shù)據(jù)實(shí)體
public class WebDto { //網(wǎng)站名稱 private String name; //網(wǎng)址 private String url; //用戶名 private String username; //密碼 private String password; //日均訪問(wèn)量 private Integer readCount; public WebDto(String name, String url, String username, String password, Integer readCount) { this.name = name; this.url = url; this.username = username; this.password = password; this.readCount = readCount; } public WebDto() {} @Override public String toString() { return "WebDto{" + "name='" + name + '\'' + ", url='" + url + '\'' + ", username='" + username + '\'' + ", password='" + password + '\'' + ", readCount=" + readCount + '}'; } @ExcelResources(title="網(wǎng)站名稱",order=1) public String getName() { return name; } public void setName(String name) { this.name = name; } @ExcelResources(title="網(wǎng)址",order=2) public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } @ExcelResources(title="用戶名",order=3) public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @ExcelResources(title="密碼",order=4) public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @ExcelResources(title="日均訪問(wèn)量",order=5) public Integer getReadCount() { return readCount; } public void setReadCount(Integer readCount) { this.readCount = readCount; } }
注意:這里使用到了@ExcelResources來(lái)自動(dòng)識(shí)別表頭信息及序號(hào)
獲取模板文件的工具類
public class TemplateFileUtil { public static FileInputStream getTemplates(String tempName) throws FileNotFoundException { return new FileInputStream(ResourceUtils.getFile("classpath:excel-templates/"+tempName)); } }
注意:從這里可以看出,所有的Excel模板文件都放在resources/excel-templates/目錄下。
模板工具類
通過(guò)此類可以自動(dòng)復(fù)制表樣式等功能
/** * 該類實(shí)現(xiàn)了基于模板的導(dǎo)出 * 如果要導(dǎo)出序號(hào),需要在excel中定義一個(gè)標(biāo)識(shí)為sernums * 如果要替換信息,需要傳入一個(gè)Map,這個(gè)map中存儲(chǔ)著要替換信息的值,在excel中通過(guò)#來(lái)開(kāi)頭 * 要從哪一行那一列開(kāi)始替換需要定義一個(gè)標(biāo)識(shí)為datas * 如果要設(shè)定相應(yīng)的樣式,可以在該行使用styles完成設(shè)定,此時(shí)所有此行都使用該樣式 * 如果使用defaultStyls作為表示,表示默認(rèn)樣式,如果沒(méi)有defaultStyles使用datas行作為默認(rèn)樣式 * Created by 鐘述林 393156105@qq.com on 2016/10/28 23:38. */ public class ExcelTemplate { /** * 數(shù)據(jù)行標(biāo)識(shí) */ public final static String DATA_LINE = "datas"; /** * 默認(rèn)樣式標(biāo)識(shí) */ public final static String DEFAULT_STYLE = "defaultStyles"; /** * 行樣式標(biāo)識(shí) */ public final static String STYLE = "styles"; /** * 插入序號(hào)樣式標(biāo)識(shí) */ public final static String SER_NUM = "sernums"; private static ExcelTemplate et = new ExcelTemplate(); private Workbook wb; private Sheet sheet; /** * 數(shù)據(jù)的初始化列數(shù) */ private int initColIndex; /** * 數(shù)據(jù)的初始化行數(shù) */ private int initRowIndex; /** * 當(dāng)前列數(shù) */ private int curColIndex; /** * 當(dāng)前行數(shù) */ private int curRowIndex; /** * 當(dāng)前行對(duì)象 */ private Row curRow; /** * 最后一行的數(shù)據(jù) */ private int lastRowIndex; /** * 默認(rèn)樣式 */ private CellStyle defaultStyle; /** * 默認(rèn)行高 */ private float rowHeight; /** * 存儲(chǔ)某一方所對(duì)于的樣式 */ private Map<Integer,CellStyle> styles; /** * 序號(hào)的列 */ private int serColIndex; private ExcelTemplate(){ } public static ExcelTemplate getInstance() { return et; } /** * 從classpath路徑下讀取相應(yīng)的模板文件 * @param path * @return */ public ExcelTemplate readTemplateByClasspath(String path) { try { wb = new HSSFWorkbook(TemplateFileUtil.getTemplates(path)); initTemplate(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("讀取模板不存在!請(qǐng)檢查"); } return this; } /** * 將文件寫到相應(yīng)的路徑下 * @param filepath */ public void writeToFile(String filepath) { FileOutputStream fos = null; try { fos = new FileOutputStream(filepath); wb.write(fos); } catch (FileNotFoundException e) { e.printStackTrace(); throw new RuntimeException("寫入的文件不存在"); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("寫入數(shù)據(jù)失敗:"+e.getMessage()); } finally { try { if(fos!=null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 將文件寫到某個(gè)輸出流中 * @param os */ public void wirteToStream(OutputStream os) { try { wb.write(os); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("寫入流失敗:"+e.getMessage()); } } /** * 從某個(gè)路徑來(lái)讀取模板 * @param path * @return */ public ExcelTemplate readTemplateByPath(String path) { try { wb = new HSSFWorkbook(TemplateFileUtil.getTemplates(path)); initTemplate(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("讀取模板不存在!請(qǐng)檢查"); } return this; } /** * 創(chuàng)建相應(yīng)的元素,基于String類型 * @param value */ public void createCell(String value) { Cell c = curRow.createCell(curColIndex); setCellStyle(c); c.setCellValue(value); curColIndex++; } public void createCell(int value) { Cell c = curRow.createCell(curColIndex); setCellStyle(c); c.setCellValue((int)value); curColIndex++; } public void createCell(Date value) { Cell c = curRow.createCell(curColIndex); setCellStyle(c); c.setCellValue(value); curColIndex++; } public void createCell(double value) { Cell c = curRow.createCell(curColIndex); setCellStyle(c); c.setCellValue(value); curColIndex++; } public void createCell(boolean value) { Cell c = curRow.createCell(curColIndex); setCellStyle(c); c.setCellValue(value); curColIndex++; } public void createCell(Calendar value) { Cell c = curRow.createCell(curColIndex); setCellStyle(c); c.setCellValue(value); curColIndex++; } public void createCell(BigInteger value) { Cell c = curRow.createCell(curColIndex); setCellStyle(c); c.setCellValue(value==null?0:value.intValue()); curColIndex++; } /** * 設(shè)置某個(gè)元素的樣式 * @param c */ private void setCellStyle(Cell c) { if(styles.containsKey(curColIndex)) { c.setCellStyle(styles.get(curColIndex)); } else { c.setCellStyle(defaultStyle); } } /** * 創(chuàng)建新行,在使用時(shí)只要添加完一行,需要調(diào)用該方法創(chuàng)建 */ public void createNewRow() { if(lastRowIndex>curRowIndex&&curRowIndex!=initRowIndex) { sheet.shiftRows(curRowIndex, lastRowIndex, 1,true,true); lastRowIndex++; } curRow = sheet.createRow(curRowIndex); curRow.setHeightInPoints(rowHeight); curRowIndex++; curColIndex = initColIndex; } /** * 插入序號(hào),會(huì)自動(dòng)找相應(yīng)的序號(hào)標(biāo)示的位置完成插入 */ public void insertSer() { int index = 1; Row row = null; Cell c = null; for(int i=initRowIndex;i<curRowIndex;i++) { row = sheet.getRow(i); c = row.createCell(serColIndex); setCellStyle(c); c.setCellValue(index++); } } /** * 根據(jù)map替換相應(yīng)的常量,通過(guò)Map中的值來(lái)替換#開(kāi)頭的值 * @param datas */ public void replaceFinalData(Map<String,String> datas) { if(datas==null) return; for(Row row:sheet) { for(Cell c:row) { // if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; String str = c.getStringCellValue().trim(); if(str.startsWith("#")) { if(datas.containsKey(str.substring(1))) { c.setCellValue(datas.get(str.substring(1))); } } } } } /** * 基于Properties的替換,依然也是替換#開(kāi)始的 * @param prop */ public void replaceFinalData(Properties prop) { if(prop==null) return; for(Row row:sheet) { for(Cell c:row) { // if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; String str = c.getStringCellValue().trim(); if(str.startsWith("#")) { if(prop.containsKey(str.substring(1))) { c.setCellValue(prop.getProperty(str.substring(1))); } } } } } private void initTemplate() { sheet = wb.getSheetAt(0); initConfigData(); lastRowIndex = sheet.getLastRowNum(); curRow = sheet.createRow(curRowIndex); } /** * 初始化數(shù)據(jù)信息 */ private void initConfigData() { boolean findData = false; boolean findSer = false; for(Row row:sheet) { if(findData) break; for(Cell c:row) { // if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; String str = c.getStringCellValue().trim(); if(str.equals(SER_NUM)) { serColIndex = c.getColumnIndex(); findSer = true; } if(str.equals(DATA_LINE)) { initColIndex = c.getColumnIndex(); initRowIndex = row.getRowNum(); curColIndex = initColIndex; curRowIndex = initRowIndex; findData = true; defaultStyle = c.getCellStyle(); rowHeight = row.getHeightInPoints(); initStyles(); break; } } } if(!findSer) { initSer(); } } /** * 初始化序號(hào)位置 */ private void initSer() { for(Row row:sheet) { for(Cell c:row) { // if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; String str = c.getStringCellValue().trim(); if(str.equals(SER_NUM)) { serColIndex = c.getColumnIndex(); } } } } /** * 初始化樣式信息 */ private void initStyles() { styles = new HashMap<Integer, CellStyle>(); for(Row row:sheet) { for(Cell c:row) { // if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; String str = c.getStringCellValue().trim(); if(str.equals(DEFAULT_STYLE)) { defaultStyle = c.getCellStyle(); } if(str.equals(STYLE)) { styles.put(c.getColumnIndex(), c.getCellStyle()); } } } } }
操作工具類
/** * 該類實(shí)現(xiàn)了將一組對(duì)象轉(zhuǎn)換為Excel表格,并且可以從Excel表格中讀取到一組List對(duì)象中 * 該類利用了BeanUtils框架中的反射完成 * 使用該類的前提,在相應(yīng)的實(shí)體對(duì)象上通過(guò)ExcelReources來(lái)完成相應(yīng)的注解 * Created by 鐘述林 393156105@qq.com on 2016/10/29 0:15. */ public class ExcelUtil { private static ExcelUtil eu = new ExcelUtil(); private ExcelUtil(){} public static ExcelUtil getInstance() { return eu; } /** * 處理對(duì)象轉(zhuǎn)換為Excel * @param template * @param objs * @param clz * @param isClasspath * @return */ private ExcelTemplate handlerObj2Excel (String template, List objs, Class clz, boolean isClasspath) { ExcelTemplate et = ExcelTemplate.getInstance(); try { if(isClasspath) { et.readTemplateByClasspath(template); } else { et.readTemplateByPath(template); } List<ExcelHeader> headers = getHeaderList(clz); Collections.sort(headers); //輸出標(biāo)題 et.createNewRow(); for(ExcelHeader eh:headers) { et.createCell(eh.getTitle()); } //輸出值 for(Object obj:objs) { et.createNewRow(); for(ExcelHeader eh:headers) { // Method m = clz.getDeclaredMethod(mn); // Object rel = m.invoke(obj); et.createCell(BeanUtils.getProperty(obj,getMethodName(eh))); } } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return et; } /** * 根據(jù)標(biāo)題獲取相應(yīng)的方法名稱 * @param eh * @return */ private String getMethodName(ExcelHeader eh) { String mn = eh.getMethodName().substring(3); mn = mn.substring(0,1).toLowerCase()+mn.substring(1); return mn; } /** * 將對(duì)象轉(zhuǎn)換為Excel并且導(dǎo)出,該方法是基于模板的導(dǎo)出,導(dǎo)出到流 * @param datas 模板中的替換的常量數(shù)據(jù) * @param template 模板路徑 * @param os 輸出流 * @param objs 對(duì)象列表 * @param clz 對(duì)象的類型 * @param isClasspath 模板是否在classPath路徑下 */ public void exportObj2ExcelByTemplate(Map<String,String> datas, String template, OutputStream os, List objs, Class clz, boolean isClasspath) { try { ExcelTemplate et = handlerObj2Excel(template, objs, clz, isClasspath); et.replaceFinalData(datas); et.wirteToStream(os); os.flush(); os.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 將對(duì)象轉(zhuǎn)換為Excel并且導(dǎo)出,該方法是基于模板的導(dǎo)出,導(dǎo)出到一個(gè)具體的路徑中 * @param datas 模板中的替換的常量數(shù)據(jù) * @param template 模板路徑 * @param outPath 輸出路徑 * @param objs 對(duì)象列表 * @param clz 對(duì)象的類型 * @param isClasspath 模板是否在classPath路徑下 */ public void exportObj2ExcelByTemplate(Map<String,String> datas,String template,String outPath,List objs,Class clz,boolean isClasspath) { ExcelTemplate et = handlerObj2Excel(template, objs, clz, isClasspath); et.replaceFinalData(datas); et.writeToFile(outPath); } /** * 將對(duì)象轉(zhuǎn)換為Excel并且導(dǎo)出,該方法是基于模板的導(dǎo)出,導(dǎo)出到流,基于Properties作為常量數(shù)據(jù) * @param prop 基于Properties的常量數(shù)據(jù)模型 * @param template 模板路徑 * @param os 輸出流 * @param objs 對(duì)象列表 * @param clz 對(duì)象的類型 * @param isClasspath 模板是否在classPath路徑下 */ public void exportObj2ExcelByTemplate(Properties prop, String template, OutputStream os, List objs, Class clz, boolean isClasspath) { ExcelTemplate et = handlerObj2Excel(template, objs, clz, isClasspath); et.replaceFinalData(prop); et.wirteToStream(os); } /** * 將對(duì)象轉(zhuǎn)換為Excel并且導(dǎo)出,該方法是基于模板的導(dǎo)出,導(dǎo)出到一個(gè)具體的路徑中,基于Properties作為常量數(shù)據(jù) * @param prop 基于Properties的常量數(shù)據(jù)模型 * @param template 模板路徑 * @param outPath 輸出路徑 * @param objs 對(duì)象列表 * @param clz 對(duì)象的類型 * @param isClasspath 模板是否在classPath路徑下 */ public void exportObj2ExcelByTemplate(Properties prop,String template,String outPath,List objs,Class clz,boolean isClasspath) { ExcelTemplate et = handlerObj2Excel(template, objs, clz, isClasspath); et.replaceFinalData(prop); et.writeToFile(outPath); } private Workbook handleObj2Excel(List objs, Class clz) { Workbook wb = new HSSFWorkbook(); try { Sheet sheet = wb.createSheet(); Row r = sheet.createRow(0); List<ExcelHeader> headers = getHeaderList(clz); Collections.sort(headers); //寫標(biāo)題 for(int i=0;i<headers.size();i++) { r.createCell(i).setCellValue(headers.get(i).getTitle()); } //寫數(shù)據(jù) Object obj = null; for(int i=0;i<objs.size();i++) { r = sheet.createRow(i+1); obj = objs.get(i); for(int j=0;j<headers.size();j++) { r.createCell(j).setCellValue(BeanUtils.getProperty(obj, getMethodName(headers.get(j)))); } } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return wb; } /** * 導(dǎo)出對(duì)象到Excel,不是基于模板的,直接新建一個(gè)Excel完成導(dǎo)出,基于路徑的導(dǎo)出 * @param outPath 導(dǎo)出路徑 * @param objs 對(duì)象列表 * @param clz 對(duì)象類型 */ public void exportObj2Excel(String outPath,List objs,Class clz) { Workbook wb = handleObj2Excel(objs, clz); FileOutputStream fos = null; try { fos = new FileOutputStream(outPath); wb.write(fos); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if(fos!=null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 導(dǎo)出對(duì)象到Excel,不是基于模板的,直接新建一個(gè)Excel完成導(dǎo)出,基于流 * @param os 輸出流 * @param objs 對(duì)象列表 * @param clz 對(duì)象類型 */ public void exportObj2Excel(OutputStream os,List objs,Class clz) { try { Workbook wb = handleObj2Excel(objs, clz); wb.write(os); } catch (IOException e) { e.printStackTrace(); } } /** * 從類路徑讀取相應(yīng)的Excel文件到對(duì)象列表 * @param path 類路徑下的path * @param clz 對(duì)象類型 * @param readLine 開(kāi)始行,注意是標(biāo)題所在行 * @param tailLine 底部有多少行,在讀入對(duì)象時(shí),會(huì)減去這些行 * @return */ public List<Object> readExcel2ObjsByClasspath(String path,Class clz,int readLine,int tailLine) { Workbook wb = null; try { wb = new HSSFWorkbook(TemplateFileUtil.getTemplates(path)); return handlerExcel2Objs(wb, clz, readLine,tailLine); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 從文件路徑讀取相應(yīng)的Excel文件到對(duì)象列表 * @param path 文件路徑下的path * @param clz 對(duì)象類型 * @param readLine 開(kāi)始行,注意是標(biāo)題所在行 * @param tailLine 底部有多少行,在讀入對(duì)象時(shí),會(huì)減去這些行 * @return */ public List<Object> readExcel2ObjsByPath(String path,Class clz,int readLine,int tailLine) { Workbook wb = null; try { wb = new HSSFWorkbook(TemplateFileUtil.getTemplates(path)); return handlerExcel2Objs(wb, clz, readLine,tailLine); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 從類路徑讀取相應(yīng)的Excel文件到對(duì)象列表,標(biāo)題行為0,沒(méi)有尾行 * @param path 路徑 * @param clz 類型 * @return 對(duì)象列表 */ public List<Object> readExcel2ObjsByClasspath(String path,Class clz) { return this.readExcel2ObjsByClasspath(path, clz, 0,0); } /** * 從文件路徑讀取相應(yīng)的Excel文件到對(duì)象列表,標(biāo)題行為0,沒(méi)有尾行 * @param path 路徑 * @param clz 類型 * @return 對(duì)象列表 */ public List<Object> readExcel2ObjsByPath(String path,Class clz) { return this.readExcel2ObjsByPath(path, clz,0,0); } private String getCellValue(Cell c) { String o = null; switch (c.getCellType()) { case Cell.CELL_TYPE_BLANK: o = ""; break; case Cell.CELL_TYPE_BOOLEAN: o = String.valueOf(c.getBooleanCellValue()); break; case Cell.CELL_TYPE_FORMULA: o = String.valueOf(c.getCellFormula()); break; case Cell.CELL_TYPE_NUMERIC: o = String.valueOf(c.getNumericCellValue()); break; case Cell.CELL_TYPE_STRING: o = c.getStringCellValue(); break; default: o = null; break; } return o; } private List<Object> handlerExcel2Objs(Workbook wb,Class clz,int readLine,int tailLine) { Sheet sheet = wb.getSheetAt(0); List<Object> objs = null; try { Row row = sheet.getRow(readLine); objs = new ArrayList<Object>(); Map<Integer,String> maps = getHeaderMap(row, clz); if(maps==null||maps.size()<=0) throw new RuntimeException("要讀取的Excel的格式不正確,檢查是否設(shè)定了合適的行"); for(int i=readLine+1;i<=sheet.getLastRowNum()-tailLine;i++) { row = sheet.getRow(i); Object obj = clz.newInstance(); for(Cell c:row) { int ci = c.getColumnIndex(); String mn = maps.get(ci).substring(3); mn = mn.substring(0,1).toLowerCase()+mn.substring(1); BeanUtils.copyProperty(obj,mn, this.getCellValue(c)); } objs.add(obj); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return objs; } private List<ExcelHeader> getHeaderList(Class clz) { List<ExcelHeader> headers = new ArrayList<ExcelHeader>(); Method[] ms = clz.getDeclaredMethods(); for(Method m:ms) { String mn = m.getName(); if(mn.startsWith("get")) { if(m.isAnnotationPresent(ExcelResources.class)) { ExcelResources er = m.getAnnotation(ExcelResources.class); headers.add(new ExcelHeader(er.title(),er.order(),mn)); } } } return headers; } private Map<Integer,String> getHeaderMap(Row titleRow,Class clz) { List<ExcelHeader> headers = getHeaderList(clz); Map<Integer,String> maps = new HashMap<Integer, String>(); for(Cell c:titleRow) { String title = c.getStringCellValue(); for(ExcelHeader eh:headers) { if(eh.getTitle().equals(title.trim())) { maps.put(c.getColumnIndex(), eh.getMethodName().replace("get","set")); break; } } } return maps; } }
Excel模板文件
創(chuàng)建一個(gè)模板文件,如下圖:
POI導(dǎo)出Excel的模板文件
測(cè)試類
@SpringBootTest @RunWith(SpringRunner.class) public class ExportExcelTest { @Test public void test() throws Exception { List<WebDto> list = new ArrayList<WebDto>(); list.add(new WebDto("知識(shí)林", "http://www.zslin.com", "admin", "111111", 555)); list.add(new WebDto("權(quán)限系統(tǒng)", "http://basic.zslin.com", "admin", "111111", 111)); list.add(new WebDto("校園網(wǎng)", "http://school.zslin.com", "admin", "222222", 333)); Map<String, String> map = new HashMap<String, String>(); map.put("title", "網(wǎng)站信息表"); map.put("total", list.size()+" 條"); map.put("date", getDate()); ExcelUtil.getInstance().exportObj2ExcelByTemplate(map, "web-info-template.xls", new FileOutputStream("D:/temp/out.xls"), list, WebDto.class, true); } private String getDate() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); return sdf.format(new Date()); } }
執(zhí)行測(cè)試方法后,查看D:/temp/out.xls文件后可以看到如下圖的內(nèi)容:
POI導(dǎo)出Excel結(jié)果圖
下載地址:Springboot_jb51.rar
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
VSCode中開(kāi)發(fā)JavaWeb項(xiàng)目的詳細(xì)過(guò)程(Maven+Tomcat+熱部署)
這篇文章主要介紹了VSCode中開(kāi)發(fā)JavaWeb項(xiàng)目(Maven+Tomcat+熱部署),本文分步驟通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09JAVA實(shí)現(xiàn)FTP斷點(diǎn)上傳的方法
這篇文章主要介紹了JAVA實(shí)現(xiàn)FTP斷點(diǎn)上傳的方法,涉及java使用FTP實(shí)現(xiàn)文件傳輸?shù)南嚓P(guān)技巧,需要的朋友可以參考下2015-06-06JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
這篇文章主要為大家詳細(xì)介紹了JavaWeb實(shí)現(xiàn)郵件發(fā)送功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12idea2020.3測(cè)試評(píng)價(jià)及感受
idea2020.3版本這次變化最大的也就是 UI了完全拋棄了之前一直使用的模板更改成了新的樣式,感興趣的朋友快來(lái)下載體驗(yàn)下吧2020-10-10Java ThreadPoolExecutor的參數(shù)深入理解
這篇文章主要介紹了Java ThreadPoolExecutor的參數(shù)深入理解的相關(guān)資料,需要的朋友可以參考下2017-03-03詳解Spring Boot最核心的27個(gè)注解,你了解多少?
這篇文章主要介紹了詳解Spring Boot最核心的27個(gè)注解,你了解多少?文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08