参考多篇网上的代码做了一些修改,做了一个自用的工具类,先贴代码在稍作说明
exportData(String sheetName, Map<String, Object> titles, List<Map<String, Object>> listData参数sheetName:工作表的名称,titles 是Excel表的标题比如学号,姓名,性别,listData封装Map 每个Map表示数据库的一条数据,其他注释已经都写了
package com.smart.common.utils; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.HorizontalAlignment; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.util.List; import java.util.Map; /** * Created by liujin on 2018/7/4. */ public class ExportExcel { /** * 数据导入Excel * @param sheetName * @param titles * @param listData */ public static HSSFWorkbook exportData(String sheetName, Map<String, Object> titles, List<Map<String, Object>> listData) throws IOException { // ====创建工作簿==== HSSFWorkbook wb = new HSSFWorkbook(); // ====创建工作表==== HSSFSheet sheet = wb.createSheet(sheetName); // ====合并单元格==== // sheet.addMergedRegion(new CellRangeAddress(0, 0, 0 , 8)); // ====创建单元格样式和单元格==== HSSFCellStyle cellStyle = wb.createCellStyle(); // ====设置内容居中==== cellStyle.setAlignment(HorizontalAlignment.CENTER); int rowNum = 0; //行序号,从第0行开始 int colNum = 0; //列序号,从第0行开始 // ====创建工作表的行==== HSSFRow row = sheet.createRow(rowNum); // ====创建单元格==== HSSFCell cell = null; // ====给第一行的单元格设置titles的值==== for (String key : titles.keySet()) { // ====创建一个单元格==== cell = row.createCell(colNum); // ====给单元格赋值==== cell.setCellValue(titles.get(key).toString()); // ====设置单元格风格==== cell.setCellStyle(cellStyle); // ====设置行高==== row.setHeightInPoints(20); // ====换到下一个单元格(同一行的下一列)==== colNum++; } // ====换行==== rowNum++; // ====列重置为0==== colNum = 0; // ====写数据,从标题的下一行开始==== for (int i = 0; i < listData.size(); i++) { Map<String, Object> data = listData.get(i); row = sheet.createRow(rowNum); for (String key : titles.keySet()) { cell = row.createCell(colNum); Object value = data.get(key); if (value != null) { cell.setCellValue(value.toString()); } else { cell.setCellValue(""); } // sheet.setColumnWidth(colNum, value.toString().length() * 516); sheet.autoSizeColumn(colNum, true); cell.setCellStyle(cellStyle); row.setHeightInPoints(20); colNum++; } rowNum++; colNum = 0; } return wb; // ====生成文件==== // String fileName = "C:\\Myself\\" + fileNm + ".xlsx"; // OutputStream out = new FileOutputStream(fileName); // wb.write(out); // out.close(); } /** * 下载Excel * @param response * @param fileName */ public static void down(HttpServletResponse response, String fileName, HSSFWorkbook wb) throws IOException { // ===将生成的Excel以流输出==== BufferedInputStream bis = null; BufferedOutputStream bos = null; // ====将Excel的数据写入字节流中==== ByteArrayOutputStream os = new ByteArrayOutputStream(); wb.write(os); byte[] content = os.toByteArray(); // ====读取流信息==== InputStream is = new ByteArrayInputStream(content); // ====设置response参数,可以打开下载页面==== response.reset(); //清空response response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xls","utf-8")); // ====从response中获得字节输出流==== ServletOutputStream out = response.getOutputStream(); // wb.write(response.getOutputStream()); bis = new BufferedInputStream(is); bos = new BufferedOutputStream(out); // ====创建数组长度为2048的字节数组,作为缓冲区==== byte[] buff = new byte[2048]; int bytesRead; // ====read方法:从bis输入流中将buff.length个字节数据读入buff数组中,返回读入缓冲区的字节总数,到末尾返回-1==== while ((-1 != (bytesRead = bis.read(buff, 0, buff.length)))) { bos.write(buff, 0, bytesRead); } bis.close(); bos.close(); } }
--------------下面是业务层代码------------------
titles用LinkHashMap的形式这样数据会按顺序写入,不然最后生成的数据格式不是预期的,
由于数据库取得的每条数据都要放入map中,而且每次for循环中无法生成不同变量名的map,所以导致如果在for循环里直接new一个map第二次循环时的数据会替换掉第一次的map里面的值,所以我再用一个Map(maps)来存放这些数据的map,确保maps里每个key取得的map都是数据库的一条数据,然后在加入listData中
/** * poi导出数据 * @param response * @return */ public void withdrawToExcel(HttpServletResponse response) { Map<String, Object> titles = new LinkedHashMap<>(); titles.put("index", "序号"); titles.put("orderNo", "提现单号"); titles.put("person", "提现人"); titles.put("amount", "提现金额"); titles.put("bankOpen", "开户行"); titles.put("bankCard", "银行卡号"); titles.put("phone", "联系电话"); titles.put("status", "提现状态"); titles.put("date", "提现时间"); List<Map<String, Object>> listData = new ArrayList<>(); Map<String, Map<String, Object>> maps = new HashMap<>(); List<Withdraw> list = super.findList(null); for (int i = 0; i < list.size(); i++) { Withdraw po = list.get(i); Map<String, Object> map = new HashMap<>(); map.put("index", i + 1); map.put("orderNo", po.getNo()); map.put("amount", po.getAmount()); if ("0".equals(po.getUserType())) { //用户 MobileUser mo = mobileUserService.load(po.getUserId()); if (mo != null) { map.put("person", mo.getName()); map.put("bankOpen", mo.getBankOpen()); map.put("bankCard", mo.getBankCard()); map.put("phone", mo.getPhone()); } else { map.put("person", ""); map.put("bankOpen", ""); map.put("bankCard", ""); map.put("phone", ""); } } else { //代理商 Agents at = agentsService.load(po.getUserId()); if (at != null) { map.put("person", at.getRealName()); map.put("bankOpen", at.getAccountBank()); map.put("bankCard", at.getAccount()); map.put("phone", at.getPhone()); } else { map.put("person", ""); map.put("bankOpen", ""); map.put("bankCard", ""); map.put("phone", ""); } } // ====提现状态==== map.put("status", DictUtils.getDictValue("withdraw_status", po.getStatus(), null)); map.put("date", DateUtils.pageformat(po.getCreateDate())); maps.put("map" + i, map); } for (String key : maps.keySet()) { listData.add(maps.get(key)); } String sheetName = "提现流水"; String fileName = "提现流水表"; try { // ====将数据导入Excel==== HSSFWorkbook wb = ExportExcel.exportData(sheetName, titles, listData); // ====下载Excel==== ExportExcel.down(response, fileName, wb); } catch (IOException e) { e.printStackTrace(); } }