Excel文档的生成与下载
2018-11-28 16:41 看月亮爬上来 阅读(108) 评论(0) 编辑 收藏 举报最近在做项目的时候,需要对于数据库获取到的数据生成相应的Excel表格并且可供下载。
在项目的DAO层使用的事hibernate框架。hibernate的transforms转换的三种结果:
- Transformers.ALIAS_TO_ENTITY_MAP //把输出结果转换成map
- Transformers.TO_LIST //把结果按顺序排进List
- Transformers.aliasToBean(target) //把结果通过setter方法注入到指定的对象属性中
所以在获取数据返回的时候,可以返回是一个map,KEY:与DB中名称一致(大小写一致)
1 return super.getPageDataBySql(helper, pager, Transformers.ALIAS_TO_ENTITY_MAP);
对于返回的值为map类型的,在生成Excel方法里面的获取也应该通过map方式进行获取,在controller里面的代码可以如下:
1 @RequestMapping(params = "method=exportExcel") 2 public ModelAndView exportExcel(HttpServletRequest request, HttpServletResponse response, WhiteList searchBean, String startTime, String endTime, String suppName) throws ParseException { 3 try { 4 // 封装要传递给业务层的Map 5 Map<String, Object> excelMap = new HashMap<String, Object>(); 6 String[] columnNameArray = new String[] { 7 "创建日期", 8 "用户号", 9 "用户姓名", 10 "手机号", 11 "创建人名称", 12 "创家人ID", 13 "状态" 14 }; 15 16 // 数据对应的数组List 17 List<Object[]> dataArrayList = new ArrayList<Object[]>(); 18 // Step1 19 // 封装标题(key 只能为title) 20 excelMap.put("title", "白名单用户信息统计列表"); 21 // Step2 封装列名(key 只能为columnNameArray) 22 excelMap.put("columnNameArray", columnNameArray); 23 24 Paginater paginater = IWhiteListServer.findSplitPage(RequestManager.getPager(request),searchBean, 25 startTime,endTime);// 遍历封装的对象,获取对应的数据填入Excel表格 26 for (Object object : paginater.getData()) { 27 Map<String, Object> map = (Map<String, Object>) object; 28 // 数据解析 29 String status = ""; 30 if (map.get("STATUS") != null) { 31 if (map.get("STATUS").equals("0")) { 32 status = "失效"; 33 } else if (map.get("STATUS").equals("1")) { 34 status = "正常"; 35 } 36 } 37 38 39 Object[] dataArray = new Object[] { 40 map.get("CREATE_TIME"), // 创建时间 41 map.get("USERCODE"), // 用户号 42 map.get("USERNAME"), // 用户姓名 43 map.get("MOBILE"), // 手机号 44 map.get("CREATOR_NAME"), // 创建人名称 45 map.get("CREATOR_ID"), // 创建人ID 46 status // 状态 47 48 }; 49 // 封装数组元素 50 dataArrayList.add(dataArray); 51 } 52 // 封装内容(key 只能为dataArrayList) 53 excelMap.put("dataArrayList", dataArrayList); 54 // 下载分页处理 55 56 // Step4 57 // 调用公共的下载方法 58 this.downExcel(excelMap, response); 59 } catch (Exception e) { 60 e.printStackTrace(); 61 LogUtil.MSG.error("下载失败了", e); 62 } 63 return null; 64 }
这里的调用公共下载方法“downExcel”方法如下:
1 public void downExcel(Map<String, Object> excelMap, HttpServletResponse response) { 2 try { 3 String fileName = new String(excelMap.get("title").toString().getBytes("gb2312"), "ISO8859-1"); 4 OutputStream os = response.getOutputStream(); 5 response.reset(); // 清空输出流 6 // response.setHeader("charset","gb2312"); 7 response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xls"); 8 response.setContentType("application/msexcel"); 9 10 // 将excelMap中的数据写入到Excel文件中 11 FileDownloadUtil.writeExcel(excelMap, os, response); 12 13 } catch (Exception e) { 14 LogUtil.MSG.error(excelMap.get("title") + "页面 调用downExcel()方法时出现异常"); 15 } 16 17 }
上面这个方法调用了封装类FileDownloadUtil里面的方法,此封装类如下:
1 package com.eptok.util; 2 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.OutputStream; 6 import java.io.UnsupportedEncodingException; 7 import java.math.BigDecimal; 8 import java.sql.Timestamp; 9 import java.util.ArrayList; 10 import java.util.Date; 11 import java.util.HashMap; 12 import java.util.List; 13 import java.util.Map; 14 15 import javax.servlet.http.Cookie; 16 import javax.servlet.http.HttpServletResponse; 17 18 import org.apache.commons.lang.StringUtils; 19 import org.slf4j.Logger; 20 import org.slf4j.LoggerFactory; 21 22 import hikefa.core.exception.BizException; 23 import jxl.Workbook; 24 import jxl.write.DateFormat; 25 import jxl.write.DateTime; 26 import jxl.write.Label; 27 import jxl.write.Number; 28 import jxl.write.NumberFormat; 29 import jxl.write.WritableCellFormat; 30 import jxl.write.WritableFont; 31 import jxl.write.WritableSheet; 32 import jxl.write.WritableWorkbook; 33 import jxl.write.WriteException; 34 import jxl.write.biff.RowsExceededException; 35 36 37 public class FileDownloadUtil { 38 39 40 protected final static Logger logger = LoggerFactory.getLogger(FileDownloadUtil.class); 41 42 // 单元格数据类型:文本 43 protected static final int DATA_TYPE_STRING = 0; 44 // 单元格数据类型:金额 45 protected static final int DATA_TYPE_CURRENCY = 1; 46 // 单元格数据类型:日期 47 protected static final int DATA_TYPE_DATE = 2; 48 // 单元格数据间隙 49 protected static final int CELL_WIDTH_SPACE = 2; 50 /** 51 * 最大下载行数 52 */ 53 public static final int MAX_LINES = 60000; 54 /** 55 * 56 * @author 57 * @Title: writeExcel 58 * @Description: 生成Excel文件的公用方法 59 * @param response 60 * @throws 61 * @return void 62 */ 63 @SuppressWarnings("unchecked") 64 public static void writeExcel(Map<String,Object> excelMap,OutputStream os, HttpServletResponse response) throws IOException, WriteException{ 65 66 //生成一个可以写操作的工作薄 67 WritableWorkbook workbook = Workbook.createWorkbook(os); 68 69 try{ 70 List<Object[]> dataList = (List<Object[]>) excelMap.get("dataArrayList"); 71 int mod = dataList.size() % MAX_LINES; 72 int size = dataList.size() / MAX_LINES; 73 if(mod != 0) { 74 size += 1; 75 } 76 for(int i = 1; i <= size; i++) { 77 //写入到第一个sheet0中 78 WritableSheet sheet = workbook.createSheet(excelMap.get("title").toString() + "-" + i, i - 1); 79 80 String[] columnNameArray = (String[])excelMap.get("columnNameArray"); 81 //columnName样式 82 jxl.write.WritableFont wfont = new jxl.write.WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false,jxl.format.UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.BLUE); 83 WritableCellFormat wc1 = new WritableCellFormat(wfont); 84 wc1.setAlignment(jxl.format.Alignment.CENTRE); 85 86 87 //写入data数据到Excel文件中 88 int startRow = 1; 89 int row = 2; 90 91 if(excelMap.get("noTitle") == null || !"false".equals(excelMap.get("noTitle"))) { 92 //合并标题单元格 93 sheet.mergeCells(0, 0,columnNameArray.length-1, 0); 94 95 //title样式 96 jxl.write.WritableFont wfontTitle = new jxl.write.WritableFont(WritableFont.ARIAL, 20, WritableFont.NO_BOLD, false,jxl.format.UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.RED); 97 WritableCellFormat wc1Title = new WritableCellFormat(wfontTitle); 98 wc1Title.setAlignment(jxl.format.Alignment.CENTRE); 99 100 //写入Title内容 101 Label labelhead = new Label(0, 0,excelMap.get("title").toString(), wc1Title); 102 sheet.addCell(labelhead); 103 }else { 104 startRow = 0; 105 row = 1; 106 } 107 108 109 //写入标题名字 110 int offset = 0; 111 // 每列最大字符数 112 List<Integer> cwl = new ArrayList<Integer>(); 113 for(String columnName:columnNameArray){ 114 Label label_filed1 = new Label(offset, startRow,columnName, wc1); 115 sheet.addCell(label_filed1); 116 cwl.add(string_length(columnName)); 117 ++offset; 118 } 119 120 // 设置单元格格式对象Map 121 Map<String, WritableCellFormat> wcfMap = setWritableCellFormatsMap(); 122 123 int curPosition = i * MAX_LINES; 124 if(curPosition > dataList.size()) { 125 curPosition = dataList.size(); 126 } 127 for (Object[] strArray : ((List<Object[]>) excelMap 128 .get("dataArrayList")).subList((i - 1) * MAX_LINES, curPosition)) { 129 addDataIntoExcel(row, strArray, excelMap.get("title") 130 .toString(), sheet, cwl, wcfMap); 131 ++row; 132 } 133 // 统一设置列宽 134 setColumnFormat(workbook, cwl); 135 // 136 writeCookie(response); 137 } 138 //写入数据到工作薄中 139 workbook.write(); 140 }catch(Exception e){ 141 LogUtil.ERROR.error(excelMap.get("title")+"页面 调用writeExcel()方法时出现异常"); 142 throw new BizException(excelMap.get("title")+"页面 调用writeExcel()方法时出现异常" + e.getMessage(), e); 143 }finally{ 144 workbook.close(); 145 os.close(); 146 } 147 } 148 149 public static void main(String[] args) throws Exception { 150 FileOutputStream out= new FileOutputStream("D:/home/goodsManager/jdGoodsPool/京东商品(20180104164000).xls"); 151 Map<String, Object> excelMap = new HashMap<String, Object>(); 152 String[] columnNameArray = new String[] { "id","一级品类"}; 153 //封装表头 154 excelMap.put("columnNameArray", columnNameArray); 155 String fileName = "京东商品(20180104164001).xls"; 156 excelMap.put("fileName",fileName); 157 158 excelMap.put("title","京东商品"); 159 //封装下载路径 160 excelMap.put("filePath", "D:/home/goodsManager/jdGoodsPool/"); 161 List<Object[]> dataList = new ArrayList<>(); 162 Object[] temp1 = new Object[] {"实物商品","1"}; 163 Object[] temp2 = new Object[] {"实物商品","2"}; 164 Object[] temp3 = new Object[] {"实物商品","3"}; 165 Object[] temp4 = new Object[] {"实物商品","4"}; 166 Object[] temp5 = new Object[] {"实物商品","5"}; 167 Object[] temp6 = new Object[] {"实物商品","6"}; 168 Object[] temp7 = new Object[] {"实物商品","7"}; 169 Object[] temp8 = new Object[] {"实物商品","8"}; 170 dataList.add(temp1); 171 dataList.add(temp2); 172 dataList.add(temp3); 173 dataList.add(temp4); 174 dataList.add(temp5); 175 dataList.add(temp6); 176 dataList.add(temp7); 177 dataList.add(temp8); 178 excelMap.put("dataArrayList", dataList); 179 // 将excelMap中的数据写入到Excel文件中 180 FileDownloadUtil.writeExcel(excelMap, out, null); 181 182 } 183 184 private static void writeCookie(HttpServletResponse response) { 185 Cookie cookie = new Cookie("isDownSuccess",String.valueOf(System.currentTimeMillis())); 186 response.addCookie(cookie); 187 } 188 189 // 设置单元格格式对象Map 190 private static Map<String, WritableCellFormat> setWritableCellFormatsMap() { 191 Map<String, WritableCellFormat> wcfMap = new HashMap<String, WritableCellFormat>(); 192 wcfMap.put("numberWCF", new WritableCellFormat(new NumberFormat("###,###0.00"))); 193 wcfMap.put("dateWCF", new WritableCellFormat(new DateFormat("yyyy-MM-dd HH:mm:ss"))); 194 return wcfMap; 195 } 196 197 /** 198 * 199 * @author 200 * @Title: addDataIntoExcel 201 * @Description: 写入List<String[])中的数据到Excel文件中 202 * @param cwl 203 * @param wcfMap 204 * @param dataFmtCol 205 * @throws 206 * @return void 207 */ 208 public static void addDataIntoExcel(int row, Object[] strArray, 209 String title, WritableSheet sheet, List<Integer> cwl, Map<String, WritableCellFormat> wcfMap) { 210 try { 211 // 写入String[]中的数据到Excel文件中 212 int size = strArray.length; 213 int column = 0; 214 for (int i = 0; i < size; i++) { 215 if (null == strArray[i] || "null".equals(strArray[i]) || "null(null)".equals(strArray[i]) 216 || "".equals(strArray[i])) { 217 addCellHandler(column, row, "", sheet, wcfMap); 218 }else { 219 addCellHandler(column, row, strArray[i], sheet, wcfMap); 220 // 设置最大列宽 221 setMaxColWidth(i, string_length(strArray[i]), cwl); 222 } 223 // 列进行累加 224 column++; 225 } 226 227 } catch (Exception e) { 228 LogUtil.ERROR.error(title + "页面 调用addDataIntoExcel()方法时出现异常" + e.getMessage()); 229 } 230 } 231 232 // 设置最大列宽 233 private static void setMaxColWidth(int pos, int curLen, List<Integer> cwl) { 234 int tmp = cwl.get(pos); 235 cwl.set(pos, tmp < curLen ? curLen : tmp); 236 } 237 238 // 列数据格式化信息设置 239 private static void addCellHandler(int column, int row, Object o, 240 WritableSheet sheet, Map<String, WritableCellFormat> wcfMap) throws RowsExceededException, WriteException { 241 switch (getDataType(o)) { 242 case DATA_TYPE_CURRENCY: 243 sheet.addCell(getNumberFormat(column, row, o, wcfMap)); 244 break; 245 case DATA_TYPE_DATE: 246 sheet.addCell(getDateFormat(column, row, o, wcfMap)); 247 break; 248 default: 249 sheet.addCell(getTxtFormat(column, row, o)); 250 break; 251 } 252 } 253 254 // 获取数据类型编码 255 private static int getDataType(Object o) { 256 int tc = DATA_TYPE_STRING; 257 if (o instanceof BigDecimal || o instanceof Double) { 258 tc = DATA_TYPE_CURRENCY; 259 } else if(o instanceof Date) { 260 tc = DATA_TYPE_DATE; 261 } 262 return tc; 263 } 264 265 // 获取金额格单元格格式化对象 266 private static Number getNumberFormat(int column, int row, Object val, Map<String, WritableCellFormat> wcfMap) { 267 return new Number(column, row, Double.valueOf(String.valueOf(val)), wcfMap.get("numberWCF")); 268 } 269 270 // 获取日期单元格格式化对象 271 private static DateTime getDateFormat(int column, int row, Object val, Map<String, WritableCellFormat> wcfMap) { 272 return new DateTime(column, row, timestamp2Date((Timestamp)val), wcfMap.get("dateWCF")); 273 } 274 275 // 获取文本单元格格式化对象 276 private static Label getTxtFormat(int column, int row, Object val) { 277 return new Label(column, row, String.valueOf(val)); 278 } 279 280 // 设置列格式 281 private static void setColumnFormat(WritableWorkbook workbook, 282 List<Integer> cwl) { 283 WritableSheet ws = workbook.getSheet(0); 284 int len = cwl.size(); 285 for (int i = 0; i < len; i++) { 286 int cw = cwl.get(i); 287 ws.setColumnView(i,cw > 50 ? 50 : cw); 288 } 289 } 290 291 // 字符长度计算 292 private static int string_length(Object d) { 293 int valueLength = 0; 294 if(null != d) { 295 if(d instanceof Date) { 296 String dateRule = "yyyy-MM-dd HH:mm:ss"; 297 valueLength = dateRule.length(); 298 } else { 299 String value = StringUtils.EMPTY; 300 try { 301 value = new String(String.valueOf(d).getBytes("GBK"), "ISO8859_1"); 302 } catch (UnsupportedEncodingException e) { 303 LogUtil.ERROR.error("error in string_length method:".concat(e.getMessage())); 304 // 长度计算异常时处理 305 valueLength = stringLengthHandler(d); 306 } 307 valueLength = value.length(); 308 } 309 } 310 return valueLength + CELL_WIDTH_SPACE; 311 } 312 313 // 长度计算异常时处理 314 private static int stringLengthHandler(Object d) { 315 int len = 0; 316 String value = String.valueOf(d); 317 String chinese = "[\u4e00-\u9fa5]"; 318 for (int i = 0; i < value.length(); i++) { 319 String temp = value.substring(i, i + 1); 320 if (temp.matches(chinese)) { 321 len += 2; 322 } else { 323 len += 1; 324 } 325 } 326 return len; 327 } 328 329 // 日期转换 330 private static Date timestamp2Date(Timestamp tt) { 331 return new Date(tt.getTime()); 332 } 333 334 public static void downExcel(Map<String, Object> excelMap, HttpServletResponse response) { 335 try { 336 String fileName = new String(excelMap.get("title").toString().getBytes("gbk"), "ISO8859-1"); 337 OutputStream os = response.getOutputStream(); 338 response.reset(); // 清空输出流 339 response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xls"); 340 response.setContentType("application/msexcel"); 341 // 将excelMap中的数据写入到Excel文件中 342 writeExcel(excelMap, os, response); 343 } catch (Exception e) { 344 LogUtil.ERROR.error(excelMap.get("title") + "页面调用downExcel()方法时出现异常"); 345 } 346 } 347 }
另一种返回的则是类对象的数据结果:
1 return super.getPageDataBySql(helper, pager, Transformers.aliasToBean(OrdersExtend.class));
在controller里面的代码可以如下:
@RequestMapping(params = "method=exportExcelFlowCard") public ModelAndView exportExcelFlowCard(HttpServletRequest request, HttpServletResponse response, Orders searchBean, String startTime, String endTime, String activeTime, String trackOutTime) throws ParseException { try { // 封装要传递给业务层的Map Map<String, Object> excelMap = new HashMap<String, Object>(); String[] columnNameArray = new String[] { "序号", "订单号/订单批次号", "商户号", "商户名称", "订单总金额(元)", "订单总笔数", "流量卡数量", "激活状态", "出库状态", "出库时间", }; // 数据对应的数组List List<Object[]> dataArrayList = new ArrayList<Object[]>(); // Step1 // 封装标题(key 只能为title) excelMap.put("title", "流量卡批充信息表"); // Step2 封装列名(key 只能为columnNameArray) excelMap.put("columnNameArray", columnNameArray); // Pager pager = new Pager(0,10000); // Pager pager = RequestManager.getPager(request); Paginater paginater = ordersServer.findSplitPage3(searchBean, new Pager(1, FileDownloadUtil.MAX_LINES), startTime, endTime, activeTime, trackOutTime); // 遍历封装的对象,获取对应的数据填入Excel表格 int i = 1; for (Object object : paginater.getData()) { OrdersExtend o2 = (OrdersExtend) object; DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // String activationTime = ""; String trackTime = ""; if (o2.getTrackTime() != null) { trackTime = format.format(o2.getTrackTime()); } String trackStatus = ""; if ("0".equals(o2.getTrackStatus())) { trackStatus = "未出库"; } if ("1".equals(o2.getTrackStatus())) { trackStatus = "已出库"; } String activationStatus = ""; if ("0".equals(o2.getActivationStatus())) { activationStatus = "未激活"; } if ("1".equals(o2.getActivationStatus())) { activationStatus = "已激活"; } if ("2".equals(o2.getActivationStatus())) { activationStatus = "申请中"; } if ("3".equals(o2.getActivationStatus())) { activationStatus = "部分激活"; } Object[] dataArray = new Object[] { i, o2.getOrdersCode() + "/" + o2.getOrdersBatchNo(), // 订单批次号 o2.getCreateUser(), // 订单创建人 o2.getEnterName(), // 商户名称 o2.getOrderTotalPrice(), // 订单支付总金额 o2.getOrderCount(), // 订单笔数 o2.getCardCount(), activationStatus, trackStatus, trackTime /* * o2.getCreateName(),//创建人名称 //o2.getCusid(), * o2.getPayRoutCode(),//路由编号 */ }; i++; // 封装数组元素 dataArrayList.add(dataArray); } // 封装内容(key 只能为dataArrayList) excelMap.put("dataArrayList", dataArrayList); // 下载分页处理 // Step4 // 调用公共的下载方法 this.downExcel(excelMap, response); } catch (Exception e) { LogUtil.MSG.error("下载失败了", e); } return null; }
同样,调用公共下载方法“downExcel”方法。
这就是用到的两种可能,其他的情况以后遇到再添加。
@RequestMapping(params = "method=exportExcelFlowCard")public ModelAndView exportExcelFlowCard(HttpServletRequest request, HttpServletResponse response, Orders searchBean, String startTime, String endTime, String activeTime,String trackOutTime) throws ParseException {try {// 封装要传递给业务层的MapMap<String, Object> excelMap = new HashMap<String, Object>();String[] columnNameArray = new String[] { "序号", "订单号/订单批次号", "商户号", "商户名称", "订单总金额(元)", "订单总笔数", "流量卡数量", "激活状态", "出库状态", "出库时间",
};
// 数据对应的数组ListList<Object[]> dataArrayList = new ArrayList<Object[]>();// Step1// 封装标题(key 只能为title)excelMap.put("title", "流量卡批充信息表");// Step2 封装列名(key 只能为columnNameArray)excelMap.put("columnNameArray", columnNameArray);
// Pager pager = new Pager(0,10000);// Pager pager = RequestManager.getPager(request);Paginater paginater = ordersServer.findSplitPage3(searchBean, new Pager(1, FileDownloadUtil.MAX_LINES), startTime, endTime, activeTime, trackOutTime);// 遍历封装的对象,获取对应的数据填入Excel表格int i = 1;for (Object object : paginater.getData()) {OrdersExtend o2 = (OrdersExtend) object;DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// String activationTime = "";String trackTime = "";if (o2.getTrackTime() != null) {trackTime = format.format(o2.getTrackTime());}
String trackStatus = "";if ("0".equals(o2.getTrackStatus())) {trackStatus = "未出库";}if ("1".equals(o2.getTrackStatus())) {trackStatus = "已出库";}String activationStatus = "";if ("0".equals(o2.getActivationStatus())) {activationStatus = "未激活";}if ("1".equals(o2.getActivationStatus())) {activationStatus = "已激活";}if ("2".equals(o2.getActivationStatus())) {activationStatus = "申请中";}if ("3".equals(o2.getActivationStatus())) {activationStatus = "部分激活";}
Object[] dataArray = new Object[] { i, o2.getOrdersCode() + "/" + o2.getOrdersBatchNo(), // 订单批次号o2.getCreateUser(), // 订单创建人o2.getEnterName(), // 商户名称o2.getOrderTotalPrice(), // 订单支付总金额o2.getOrderCount(), // 订单笔数o2.getCardCount(), activationStatus, trackStatus, trackTime/* * o2.getCreateName(),//创建人名称 //o2.getCusid(), * o2.getPayRoutCode(),//路由编号 */};i++;// 封装数组元素dataArrayList.add(dataArray);}// 封装内容(key 只能为dataArrayList)excelMap.put("dataArrayList", dataArrayList);// 下载分页处理// Step4// 调用公共的下载方法this.downExcel(excelMap, response);} catch (Exception e) {LogUtil.MSG.error("下载失败了", e);}return null;
}