測試結果:
數據庫表截圖:
導出cvs文件:
頁面,導出按鈕,導出js
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <body> <h2>Hello World!</h2> <%-- 引入jQuery --%> <script src="js/jquery-1.10.2.min.js"></script> <script type="text/javascript"> $(function () { $('#exportCsv').bind("click", function(){ var formElement=$("<form>"); // 定義一個form表單 formElement.attr("style","display:none"); formElement.attr("target",""); formElement.attr("method","post"); var contextPath = "${pageContext.request.contextPath}"; formElement.attr("action", contextPath + "/item/export"); /*var filterRules = $("#purchaseDetail_datagrid").datagrid("options").filterRules; //把過濾條件傳入 var inputElement=$("<input>"); inputElement.attr("type","hidden"); inputElement.attr("name","filterRules"); inputElement.attr("value",JSON.stringify(filterRules)); formElement.append(inputElement);*/ $("body").append(formElement); // 將表單放置在web中 /*inputElement=$("<input>"); inputElement.attr("type","hidden"); inputElement.attr("name","deptId"); inputElement.attr("value",deptId); formElement.append(inputElement);*/ formElement.submit();//表單提交 return false; }); }) </script> </body> <a id="exportCsv" href="javascript:void(0)">導出CSV</a> </html>
頁面點擊“導出cvs”按鈕后,會在頁面body中追加一個表單
controller
@RequestMapping(value = "/export") @ResponseBody public void export(@RequestParam Map<String, Object> params, Model model, HttpServletRequest request, HttpServletResponse resp) { itemService.export(params, request, resp); }
service
package com.alphajuns.ssm.service.impl; import com.alphajuns.ssm.mybatis.ItemMapper; import com.alphajuns.ssm.pojo.Item; import com.alphajuns.ssm.service.ItemService; import com.alphajuns.ssm.util.AbstractCsvHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; @Service public class ItemServiceImpl extends AbstractCsvHelper implements ItemService { @Autowired private ItemMapper itemMapper; @Override public void export(Map<String, Object> params, HttpServletRequest request, HttpServletResponse resp) { exportCvs(params, request, resp); } @Override protected Map<String, String> getCsvHeader() { Map<String, String> header = new LinkedHashMap<String, String>(); header.put("id", "類目ID"); header.put("parent_id", "父類目ID"); header.put("title", "分類名稱"); header.put("status", "狀態"); header.put("sort_order", "排列序號"); header.put("is_parent", "是否為父類目"); header.put("created", "創建時間"); header.put("updated", "更新時間"); return header; } @Override protected String getFilename() { Date date = new Date(); DateFormat df=new SimpleDateFormat("yyyy-MM-dd"); String time=df.format(date); return "分類詳情_" + time + ".csv"; } @Override protected List<Map<String, ?>> getCsvRecords(Map<String, Object> params) { List<Map<String, ?>> itemContentCategoryMapList = itemMapper.queryItemContentCategory(params); for(Map itemContentCategoryMap : itemContentCategoryMapList){ // 狀態 String status = String.valueOf(itemContentCategoryMap.get("status")); String statusVal = ""; if ("1".equals(status)) { statusVal = "正常"; } else if("2".equals(status)) { statusVal = "刪除"; } itemContentCategoryMap.put("status", statusVal); // 狀態 String isParent = String.valueOf(itemContentCategoryMap.get("is_parent")) ; String isParentVal = ""; if ("1".equals(isParent)) { isParentVal = "true"; } else if("2".equals(isParent)) { isParentVal = "false"; } itemContentCategoryMap.put("is_parent", statusVal); } return itemContentCategoryMapList; } @Override protected void prepareParams(Map<String, Object> params) { } }
其中需要cvs的jar包,maven坐標
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-csv</artifactId> <version>1.4</version> </dependency>
模板方法模式中,導出步驟位於抽象類的一個方法中,該方法中調用了抽象類中的抽象方法,該抽象方法的實現類位於子類中,這樣根據導出可以根據需要,自定義表頭,導出的數據
導出cvs模板類AbstractCsvHelper
package com.alphajuns.ssm.util; import java.io.IOException; import java.io.PrintWriter; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import org.apache.log4j.Logger; /** * 導出csv的幫助類 * @author warrenxia * */ public abstract class AbstractCsvHelper { /** * logger */ private static Logger logger = Logger.getLogger(AbstractCsvHelper.class); /** * 導出csv * @param params * @param request * @param resp */ public void exportCvs(Map<String, Object> params, HttpServletRequest request, HttpServletResponse resp) { resp.setContentType("application/octet-stream"); resp.setCharacterEncoding("GBK"); int rows = 500; CSVFormat csvFormat = CSVFormat.DEFAULT; CSVPrinter csvPrinter = null; PrintWriter printWriter = null; try { String agent = (String)request.getHeader("USER-AGENT"); if(agent != null && agent.toLowerCase().indexOf("firefox") > 0) { resp.setHeader("Content-Disposition","attachment; filename=" + new String(getFilename().getBytes("GB2312"),"ISO-8859-1")); } else { resp.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(getFilename(), "UTF-8")); } printWriter = resp.getWriter(); csvPrinter = new CSVPrinter(printWriter, csvFormat); Map<String, String> header = getCsvHeader(); insertHeader(header, csvPrinter); prepareParams(params); params.put("rows", rows); params.put("page", 1); //查詢導出的數據 List<Map<String,?>> mapList = getCsvRecords(params); int totalCount = 0; if(mapList!=null&&!mapList.isEmpty()){ if (mapList.get(0).containsKey("TOTALCOUNT")) { Number nTotalCount = (Number) mapList.get(0).get("TOTALCOUNT"); totalCount = nTotalCount.intValue(); } else { totalCount = mapList.size(); } } // 設置最大導出數量 String reportMaxRow = "20000"; int intReportMaxRow = 5000; if(reportMaxRow!=null && !reportMaxRow.trim().equals("")){ intReportMaxRow = Integer.parseInt(reportMaxRow.trim()); } if(totalCount>intReportMaxRow){ String errMsg = "不能導出大於"+intReportMaxRow+"條的數據,請縮小選擇范圍!"; List<String> record = new ArrayList<String>(); record.add(errMsg); csvPrinter.printRecord(record); throw new ReportBusinessException(errMsg); } insertRecords(mapList, header, csvPrinter); int totalPage = (int) Math.ceil((double)totalCount / rows); for (int i = 1; i < totalPage; i++) { params.put("page", i + 1); mapList = getCsvRecords(params); insertRecords(mapList, header, csvPrinter); } } catch (IOException e) { e.printStackTrace(); } catch(ReportBusinessException e){ logger.error("報表導出異常",e); throw e; } catch (Exception e) { e.printStackTrace(); } finally { try { csvPrinter.flush(); printWriter.flush(); csvPrinter.close(); printWriter.close(); } catch (Exception e) { e.printStackTrace(); } } } protected abstract Map<String, String> getCsvHeader(); protected abstract String getFilename(); protected abstract List<Map<String,?>> getCsvRecords(Map<String, Object> params); protected abstract void prepareParams(Map<String, Object> params); private void insertHeader(Map<String, String> header, CSVPrinter csvPrinter) throws IOException { csvPrinter.printRecord(header.values()); } private void insertRecords(List<Map<String,?>> mapList, Map<String, String> header, CSVPrinter csvPrinter) throws IOException { for (Map<String, ?> map : mapList) { List<String> record = new ArrayList<String>(); for (Entry<String, String> entry : header.entrySet()) { Object object = map.get(entry.getKey()); if (object == null) { record.add(""); } else { record.add(String.valueOf(object)); } } csvPrinter.printRecord(record); } } }
報表導出異常類
package com.alphajuns.ssm.util; public class ReportBusinessException extends RuntimeException{ /** * serialVersionUID */ private static final long serialVersionUID = 1L; /** * */ private String errorCode; /** * */ private String message; /** * BusinessException * @param message message */ public ReportBusinessException(String message) { this.message = message; } /** * BusinessException * @param errorCode errorCode * @param message message */ public ReportBusinessException(String errorCode, String message) { this.message = message; this.errorCode = errorCode; } /** * BusinessException * @param message message * @param cause cause */ public ReportBusinessException(String message, Throwable cause) { super(cause); this.message = message; } /** * BusinessException * @param errorCode errorCode, * @param message message * @param cause cause */ public ReportBusinessException(String errorCode, String message, Throwable cause) { super(errorCode, cause); this.errorCode = errorCode; this.message = message; } public String getErrorCode() { return this.errorCode; } public void setErrorCode(String errorCode) { this.errorCode = errorCode; } @Override public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } }
mapper接口
List<Map<String,?>> queryItemContentCategory(Map<String, Object> params);
mapper.xml
<select id="queryItemContentCategory" resultType="map"> select * from tb_content_category </select>