文件下載需要五步:
1.設置文件ContentType類型
// 設置文件ContentType類型,這樣設置,會自動判斷下載文件類型 response.setContentType("multipart/form-data");
2.設置文件頭
// 設置文件頭:最后一個參數是設置下載文件名 response.addHeader("Content-Disposition", "attachment;filename=" + new String(title.getBytes(),"ISO8859-1") + ".xls");
3.獲取輸出流(out)
// 獲取輸出流 out = res.getOutputStream();
4.寫到輸出流(out)中
5.關閉資源
--------華麗的分割線-------web項目導出Excel文檔
POM :
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.15-beta1</version> </dependency>
Class : RestController
package com.xindatai.ibs.device.act; import java.io.IOException; import java.io.OutputStream; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.xindatai.common.web.BaseAct; import com.xindatai.common.web.resp.ModelMapWriter; import com.xindatai.common.web.resp.PageRespWriter; import com.xindatai.ibs.device.act.bean.PerfReqParam; import com.xindatai.ibs.device.act.validate.PerfActValidate; import com.xindatai.ibs.device.bean.PerfPM25; import com.xindatai.ibs.device.service.PerfService; import com.xindatai.ibs.util.ExportExcel; @RestController public class PerfAct extends BaseAct{ @Resource private PerfService service; @Resource private PerfActValidate validate; @Resource private ExportExcel<PerfPM25> exportExcel; @RequestMapping(value = "/perf" , method = RequestMethod.GET) public String perf(HttpServletRequest req,HttpServletResponse res , PerfReqParam param){ res.setHeader("Access-Control-Allow-Origin", "*"); ModelMapWriter writer = new ModelMapWriter(); validate.perf(param); if(param.hasErrors()){ writer = ModelMapWriter.createErrWriter(param); }else{ if(param.getExport()){ OutputStream out = null; try { String title = "來福士PM2.5濃度監測值統計報表"; List<PerfPM25> list = service.getPerfsExport(param); String[] headers = {"監測點","統計時間","PM2.5濃度平均值","溫度平均值","濕度平均值"}; String[] headersName = {"name","perfTime","pm25","temp","humi"}; // 設置文件ContentType類型,這樣設置,會自動判斷下載文件類型 res.setContentType("multipart/form-data"); // 設置文件頭:最后一個參數是設置下載文件名 res.addHeader("Content-Disposition", "attachment;filename=" + new String(title.getBytes(),"ISO8859-1") + ".xls"); // 獲取輸出流 out = res.getOutputStream(); exportExcel.exportExcel(title, headers, headersName, list, out); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(null != null){ out.close(); } } catch (IOException e) { e.printStackTrace(); } } }else{ PageRespWriter<PerfPM25> query = service.getPerfs(param); return toJsonFormatDate(query); } } return toJsonFormatDate(writer); } }
Class : @Service
package com.xindatai.ibs.util; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFComment; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFPatriarch; import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; import org.springframework.stereotype.Service; @Service public class ExportExcel<T> { public void exportExcel(String title, String[] headers,String[] headersName,Collection<T> dataset, OutputStream out) { exportExcel(title, headers, headersName, dataset, out, "yyyy-MM-dd HH:mm:ss"); } /* * 這是一個通用的方法,利用JAVA的反射機制,可以將放置在JAVA集合中並且符合一定條件的數據以EXCEL的形式輸出到指定IO設備上 * @param title 表格標題名 * @param headers 表格屬性列名數組 * @Param headersName 字段數組,用來獲取反射方法。 * @param dataset 需要顯示的數據集合,集合中一定要放置符合javabean風格的類的對象。此方法支持的javabean屬性的數據類型有基本數據類型及String,Date,byte[](圖片數據) * @param out 與輸出設備關聯的流對象,可以將EXCEL文檔導出到本地文件或者網絡中。 * @param pattern 如果有時間數據,設定輸出格式。默認為“yyyy-MM-dd” */ public void exportExcel(String title,String[] headers,String[] headersName, Collection<T> dataset,OutputStream out,String pattern){ // 聲明一個工作簿 HSSFWorkbook workbook = new HSSFWorkbook(); // 聲明一個表格 HSSFSheet sheet = workbook.createSheet(title); // 設置表格默認列寬度為15個字節 sheet.setDefaultColumnWidth((short)15); // 生成一個單元格樣式:表頭單元格樣式 HSSFCellStyle styleCaptaion = workbook.createCellStyle(); // 設置表頭單元格樣式:設置單元格背景色 // styleCaptaion.setFillBackgroundColor(HSSFColor.SKY_BLUE.index); // 設置表頭單元格樣式:指定單元格的填充信息模式和純色填充單元。 // styleCaptaion.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); // 設置表頭單元格樣式:設置邊框的類型為單元格的右邊界 styleCaptaion.setBorderBottom(HSSFCellStyle.BORDER_THIN); styleCaptaion.setBorderTop(HSSFCellStyle.BORDER_THIN); styleCaptaion.setBorderLeft(HSSFCellStyle.BORDER_THIN); styleCaptaion.setBorderRight(HSSFCellStyle.BORDER_THIN); // 設置表頭單元格樣式:設置單元格為水平對齊的類型 styleCaptaion.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 生成一個字體:表頭字體 HSSFFont fontCaptaion = workbook.createFont(); // 生成一個字體:設置字體顏色 fontCaptaion.setColor(HSSFColor.VIOLET.index); // 生成一個字體:設置字體大小 fontCaptaion.setFontHeightInPoints((short)12); // 生成一個字體:字體加粗 fontCaptaion.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 把字體應用到當前單元格樣式中 styleCaptaion.setFont(fontCaptaion); // 生成內容單元格樣式 HSSFCellStyle styleContent = workbook.createCellStyle(); styleContent.setFillBackgroundColor(HSSFColor.LIGHT_YELLOW.index); styleContent.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); styleContent.setBorderBottom(HSSFCellStyle.BORDER_THIN); styleContent.setBorderTop(HSSFCellStyle.BORDER_THIN); styleContent.setBorderLeft(HSSFCellStyle.BORDER_THIN); styleContent.setBorderRight(HSSFCellStyle.BORDER_THIN); styleContent.setAlignment(HSSFCellStyle.ALIGN_CENTER); styleContent.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 生成內容字體 HSSFFont fontContent = workbook.createFont(); fontContent.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); // 把字體應用到內容單元格樣式中 styleContent.setFont(fontContent); // 聲明一個畫圖的頂級管理器 HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); // 定義注釋的大小和位置 HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short)4, 2, (short)6, 5)); // 設置注釋內容 comment.setString(new HSSFRichTextString("可以在POI中添加注釋")); // 設置注釋作者,當鼠標移動到單元格上時可以在狀態欄中看到該內容 comment.setAuthor("lime"); // 產生表格標題行 HSSFRow row = sheet.createRow(0); for(short i = 0;i < headers.length;i++){ HSSFCell cell = row.createCell(i); cell.setCellStyle(styleCaptaion); HSSFRichTextString text = new HSSFRichTextString(headers[i]); cell.setCellValue(text); } // 遍歷集合數據,產生數據行 Iterator<T> it = dataset.iterator(); int index = 0; while(it.hasNext()){ row = sheet.createRow(++index); T t = (T)it.next(); Class<? extends Object> tCls = t.getClass(); for(short i = 0;i < headers.length;i++){ HSSFCell cell = row.createCell(i); String getterName = "get" + headersName[i].substring(0, 1).toUpperCase() + headersName[i].substring(1); Method method = null; Object value = null; try { method = tCls.getDeclaredMethod(getterName); value = method.invoke(t); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } verify(value, cell, row, pattern, sheet, index, patriarch, workbook, i); } } try { workbook.write(out); } catch (IOException e) { e.printStackTrace(); }finally{ if(null != out){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } public void verify(Object value,HSSFCell cell,HSSFRow row, String pattern, HSSFSheet sheet, int index, HSSFPatriarch patriarch, HSSFWorkbook workbook, int i){ // 判斷值的類型后進行強制類型轉換 String textValue = null; if(value instanceof Integer){ int intValue = (Integer)value; cell.setCellValue(intValue); }else if(value instanceof Float){ float fValue = (Float)value; cell.setCellValue(fValue); }else if(value instanceof Double){ double dValue = (Double)value; cell.setCellValue(dValue); }else if(value instanceof Long){ long longValue = (Long)value; cell.setCellValue(longValue); }else if(value instanceof Boolean){ boolean bValue = (Boolean)value; textValue ="男"; if(!bValue){ textValue = "女"; } cell.setCellValue(textValue); }else if(value instanceof Date){ Date date = (Date)value; SimpleDateFormat sdf = new SimpleDateFormat(pattern); textValue = sdf.format(date); cell.setCellValue(textValue); }else if(value instanceof byte[]){ // 有圖片時,設置行高為60px; row.setHeightInPoints(60); // 設置圖片所在列寬度為80px,注意這里單位的一個換算 sheet.setColumnWidth(i,(short)35.7*80); // sheet.autoSizeColumn(i); byte[] bsValue = (byte[])value; HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short)6,index,(short)6,index); // anchor.setAnchorType(2); patriarch.createPicture(anchor, workbook.addPicture(bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG)); }else{ // 其他數據類型都當作字符串簡單處理 if(null == value){ value = "未知區域"; } textValue = value.toString(); } // 如果不是圖片數據,就利用正則表達式判斷textValue是否全部有數字組成 if(textValue != null){ Pattern p = Pattern.compile("^//d+(//.//d+)?$"); Matcher matcher = p.matcher(textValue); if(matcher.matches()){ // 是數字當double處理 cell.setCellValue(Double.parseDouble(textValue)); }else{ HSSFRichTextString richString = new HSSFRichTextString(textValue); HSSFFont font3 = workbook.createFont(); font3.setColor(HSSFColor.BLUE.index); richString.applyFont(font3); cell.setCellValue(richString); } } } }
啦啦啦
啦啦啦
啦啦啦
啦啦啦