起初头儿让我作一个excel的导出功能,由于以前作过,因此代码比较简单,可是因为数据量庞大,致使导出的时间很长,因此只能改为异步的方式。前端
话很少说,下面贴代码吧。java
@RestController public class ExportExcelHelper { @Value("#{personConfig.defaultOrgTree}") private Integer defaultTreeId; @Autowired private CustomQueryService customQueryService; public static String RUNNING_STATUS = "该任务仍在运行中"; public static String STOP_STATUS = "该任务已经被手动中止"; public static String FINISH_STATUS = "该任务已经完成"; private volatile int runFlag = 0; //0无任务 1任务进行中 -1任务被手动中止 private Result<Progress> exportResult; XSSFWorkbook wb; String processid; /** * 用于将查询出的数据写入到excel的数据流中 * * @param queryTable 查询出的数据 * @param totaltitle 第一行的总标题 * @return XSSFWorkbook excel数据流 * @author yuanyu * @since 2019.12.02 */ public static XSSFWorkbook exportExcel(QueryTable queryTable, String totaltitle) throws Exception { // 新建一个Excel文件 XSSFWorkbook wb = new XSSFWorkbook(); // Excel中的sheet XSSFSheet sheet = wb.createSheet(); //设置第一行也就是总标题的格式 XSSFCellStyle firstrowcellStyle = wb.createCellStyle(); firstrowcellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); Font totalTtileFont = wb.createFont(); totalTtileFont.setFontName("宋体"); totalTtileFont.setFontHeightInPoints((short) 18);//设置字体大小 totalTtileFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显示 firstrowcellStyle.setFont(totalTtileFont); // 建立第一行 总标题行 XSSFRow firstrow = sheet.createRow(0); XSSFCell cell_00 = firstrow.createCell(0); cell_00.setCellValue(totaltitle); cell_00.setCellStyle(firstrowcellStyle); //建立第二行 属性标题行 XSSFRow secondrow = sheet.createRow(1); XSSFCellStyle secondrowStyle = wb.createCellStyle(); secondrowStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); Font subtitleFont = wb.createFont(); //设置第二行属性标题行的格式 subtitleFont.setFontName("宋体"); subtitleFont.setFontHeightInPoints((short) 12);//设置字体大小 subtitleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显示 secondrowStyle.setFont(subtitleFont); // 从参数queryTable中解析出打印的每列标题,放入title中 List<String> title = Lists.newArrayList(); for (QueryField p : queryTable.getHeader()) { title.add(p.getName()); } XSSFCell secondrowcell; // 给第一行赋值,值为咱们从参数中解析出的标题,所以须要咱们在传参的时候须要严格按照约定 for (int i = 0; i < title.size(); i++) { secondrowcell = secondrow.createCell(i); secondrowcell.setCellValue(title.get(i)); secondrowcell.setCellStyle(secondrowStyle); sheet.setColumnWidth(i, title.get(i).getBytes("UTF-8").length * 2 * 256); } //二重循环 将行和列的数据填充进去 XSSFCellStyle datarowStyle = wb.createCellStyle(); datarowStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); XSSFRow contextrow; XSSFCell datarowcell; for (int i = 1; i < queryTable.getRows().size(); i++) { contextrow = sheet.createRow(i + 1); for (int p = 0; p < queryTable.getHeader().size(); p++) { datarowcell = contextrow.createCell(p); datarowcell.setCellValue(queryTable.getRows().get(i).getString(queryTable.getHeader().get(p).getKey())); datarowcell.setCellStyle(datarowStyle); } } //将第一行标题进行合并 CellRangeAddress region = new CellRangeAddress(0, 0, 0, title.size() - 1); sheet.addMergedRegion(region); return wb; } private class Progress { private String start = DateUtils.parseDateToString(new Date()); private String end; private String status = RUNNING_STATUS; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getStart() { return start; } public void setStart(String start) { this.start = start; } public String getEnd() { return end; } public void setEnd(String end) { this.end = end; } } private class Export extends Thread { CustomQueryVo query; Export(CustomQueryVo query) { this.query = query; } @Override public void run() { exportResult = Result.create(new Progress()); while (runFlag == 1) { //说明任务仍在进行中 query.setCatalogid(defaultTreeId); try { wb = excelExport(query).getResult(); break; } catch (Exception e) { if (e instanceof IErrorCode) { Result.create((IErrorCode) e); break; } else { Result.create(CommonError.internal_error); break; } } } if (exportResult.successful()) { exportResult.getResult().setEnd(DateUtils.parseDateToString(new Date())); if (runFlag == -1) { exportResult.getResult().setStatus(STOP_STATUS); } else { exportResult.getResult().setStatus(FINISH_STATUS); } } runFlag = 0; } } @PostMapping("/exportasyn") @ApiOperation("excel导出") @Api(value = "excel导出", permit = ApiPermit.LOGIN) public Result<Void> excelExportAsyn(@RequestBody CustomQueryVo query) throws Exception { query.setCatalogid(defaultTreeId); String namespace = query.getModel(); Integer catalogid = query.getCatalogid(); Integer nodeid = query.getNodeid(); if (catalogid == null || nodeid == null) { throw new MicroException(CommonError.illegal_args, "未设置查询的组织目录"); } List<QueryField> fields = query.getFields(); if (fields == null || fields.size() == 0) { throw new MicroException(CommonError.illegal_args, "未设置查询的字段"); } if (!CustomQueryHelper.MODEL_USER.equals(query.getModel()) && !CustomQueryHelper.MODEL_ORG.equals(query.getModel())) { throw new MicroException(CommonError.illegal_args, "不支持" + namespace + "查询"); } if (runFlag == 0) { runFlag = 1; Export export = new Export(query); export.start(); processid = UUIDUtils.generate(); System.out.println("线程id是"+processid); return Result.create(); } else { return Result.create(CommonError.illegal_operation, "excel正在导出请勿重复造做"); } } @GetMapping("/export/{id}") @ApiOperation("获取进度") @Api(value = "获取进度", permit = ApiPermit.LOGIN) public Result<Progress> progress(@PathVariable("id") String id ) { if (!id.equals(processid) || StringUtils.isEmpty(id)){ return Result.create(CommonError.notfound, "没法找到该任务"); } if (exportResult == null) { return Result.create(CommonError.notfound, "暂无进度信息"); } return exportResult; } @GetMapping("/export/download") @ApiOperation("下载excel文件") @Api(value = "下载excel文件", permit = ApiPermit.LOGIN) public Result<Void> download(HttpServletResponse response) throws Exception { if (runFlag == 0) { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String excelfilename = sdf.format(date) + ".xlsx"; response.setContentType("application/vnd.ms-excel;charset=UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + excelfilename); response.flushBuffer(); wb.write(response.getOutputStream()); wb.close(); return Result.create(); } else { return Result.create(CommonError.notfound, "没法获取数据"); } } @GetMapping("/export/stop") @ApiOperation("中止excel导出") @Api(value = "中止excel导出", permit = ApiPermit.LOGIN) public Result<Void> stop() { if (runFlag == 0) { return Result.create(CommonError.illegal_operation, "没有任务"); } else { runFlag = -1; return Result.create(); } } /** * 根据条件查询数据而且整理数据 * * @param query 前端传来的查询条件 * @return XSSFWorkbook excel数据流 * @author yuanyu * @since 2019/12/02 */ public Result<XSSFWorkbook> excelExport(CustomQueryVo query) throws Exception { String title = query.getTitle(); QueryTable queryTable = new QueryTable(); List<Data> dataList = new ArrayList<>(); query.setNeedtotal(false); int pagenumber = 1; query.setPagenum(pagenumber); query.setPagesize(2000); Result<QueryTable> queryTableResult; try { queryTableResult = customQueryService.query(query); } catch (Exception e) { if (e instanceof IErrorCode) { return Result.create((IErrorCode) e); } else { return Result.create(CommonError.internal_error); } } int maxheadernum = queryTableResult.getResult().getHeader().size(); long totalDataNumber = 0; Map<Integer, List<QueryField>> headermap = new HashMap<>(); while (queryTableResult.successful()) { totalDataNumber += queryTableResult.getResult().getRows().size(); if (totalDataNumber > 500000) { break; } System.out.println("查询数据总数" + totalDataNumber); dataList.addAll(queryTableResult.getResult().getRows()); //获取最大的属性数 并将最大数与其对应的属性集合放到map里面 if (maxheadernum < queryTableResult.getResult().getHeader().size()) { maxheadernum = queryTableResult.getResult().getHeader().size(); } headermap.put(maxheadernum, queryTableResult.getResult().getHeader()); pagenumber++; query.setPagenum(pagenumber); try { queryTableResult = customQueryService.query(query); } catch (Exception e) { if (e instanceof IErrorCode) { return Result.create((IErrorCode) e); } else { return Result.create(CommonError.internal_error); } } } queryTable.setRows(dataList); queryTable.setHeader(headermap.get(maxheadernum)); XSSFWorkbook wb = ExportExcelHelper.exportExcel(queryTable, title); return Result.create(wb); } }