Java download Excel table (ajax processing stream file)

Java download Excel table (ajax processing stream file)

Problems encountered:
① Export Excel to process a large amount of data.
② The back-end uses the SXSSFWorkbook export function in Apache POI, and does not use the xlsx.core.min.js front-end export. Considering that the front-end export efficiency will be relatively low, more processing is required One-step data
③ Ajax processes the file stream. This should be used not only to export excel files, but also to process other files.
Technology: HTML, CSS, JavaScript, SpringBoot

  • Front end ajax part of the code logic:
/**
 * 	handlePrefix,handleNext这两个参数是函数,用来做额外的处理,前一个是下载前处理函数,下载完成之后处理函数
 */
function export(handlePrefix,handleNext){
    
    
	//准备下载时处理
	if(handlePrefix){
    
    
		handlePrefix();
	}
	let param = {
    
    };
	for (let key in searchArgs) {
    
    
	    param[key] = searchArgs[key];
	};
	let p = "";
	for (let i in param) {
    
    
	    if (param[i] != undefined && param[i] != null && param[i] != "") {
    
    
	        p = p + i + "=" + param[i] + "&";
	    }
	}
	p = p.substring(0, p.length - 1);
	//以上是进行参数的处理,可进行自定义参数处理
	let url = "hpmont/exportHistoryFault.mvc?" + p;
	//定义下载文件名
	let fileName = "xxx.xlsx";
	//使用原生创建请求
	let xhr = new XMLHttpRequest();
	xhr.open('GET', url, true);
	// 定义请求完成的处理函数,请求前也可以增加加载框/禁用下载按钮逻辑
	xhr.responseType = "blob";
	xhr.onload = function () {
    
    
	    // 请求完成,进行处理
	    if (this.status === 200) {
    
    
	        // 返回200
	        let blob = this.response;
	        let reader = new FileReader();
	        reader.readAsDataURL(blob);  // 转换为base64,可以直接放入标签href
	        reader.onload = function (e) {
    
    
	            // 转换完成,创建一个a标签用于下载,处理思路相当于点击a连接进行完成下载。
	            let a = document.createElement('a');
	            //下载文件名
	            a.download = fileName;
	            a.href = e.target.result;
	            $("body").append(a);  // 修复firefox中无法触发click
	            a.click();
	            $(a).remove();
	        }
	    };
	    //下载完成处理
	    if(handleNext){
    
    
			handleNext();
		}
	};
	// 发送ajax请求
	xhr.send()
}
  • The back-end uses SXSSFWorkbook for export operations:
    Excel has been exported here as an example, first of all, you have to import it in maven pom.xml:
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.0.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.0.0</version>
</dependency>
/**
 * 导出excel记录
 * @param request
 * @param response
 */
@RequestMapping(value = "/exportHistoryFault",method= RequestMethod.GET)
public void exportHistoryFault(HttpServletRequest request, HttpServletResponse response)  {
    
    
    Map<String,Object> param = new HashMap<>();
    Enumeration enu=request.getParameterNames();
    while(enu.hasMoreElements()){
    
    
        String paraName=(String)enu.nextElement();
        param.put(paraName,request.getParameter(paraName));
    }
    try {
    
    
        if (param.get("id")==null|| StringUtils.isEmpty(param.get("id").toString())){
    
    
            param.put("id",getUserId());
        }
        //查询需要导出的记录结果
        Map<String, Object> res=historyInquiryService.findHistoryList(param);
        ExportExcel.exportHistoryFault(response,(List<Map<String, Object>>) res.get("rows"));
    } catch (Exception e) {
    
    
        logger.error("导出电梯信息excel出错",e);
        e.printStackTrace();
    }
}

public class ExportExcel {
    
    
    private static final Logger logger = LoggerFactory.getLogger(ExportExcel.class);
    
    public static void exportHistoryFault(HttpServletResponse response, List<Map<String, Object>> list) throws IOException {
    
    
        long begin = System.currentTimeMillis();
        logger.info("开始导出故障记录");
        OutputStream output = null;
        try {
    
    
            //在内存中保存1000行,超出刷新,使用SXSSFWorkbook导出的效率很高,具我的数据而言,40万条数据五分钟左右
            SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(1000);
            //excel表格的底部Sheet名称
            SXSSFSheet sxssfSheet = sxssfWorkbook.createSheet("故障记录");
            //设置单元格样式们这里不起作用
            CellStyle cellStyle = sxssfWorkbook.createCellStyle();
            //设置单元格居中,这里不起作用,不知道为什么
            cellStyle.setAlignment(CellStyle.ALIGN_CENTER);
            //设置指定列的列宽,256 * 50这种写法是因为width参数单位是单个字符的256分之一
            sxssfSheet.setColumnWidth(0, 256 * 20);
            sxssfSheet.setColumnWidth(4, 256 * 20);
            //创建第一行数据,相当于头标题
            SXSSFRow headRow = sxssfSheet.createRow(0);
            headRow.createCell(0).setCellValue("工号");
            headRow.createCell(1).setCellValue("故障代码");
            headRow.createCell(2).setCellValue("检修状态");
            headRow.createCell(3).setCellValue("故障楼层");
            headRow.createCell(4).setCellValue("上报时间");
            //设置单元格数据
            if (list != null && list.size() > 0) {
    
    
                for (int i = 0; i < list.size(); i++) {
    
    
                    SXSSFRow bodyRow = sxssfSheet.createRow(i + 1);
                    bodyRow.createCell(0).setCellValue(list.get(i).get("elevatorNum") == null ? "" : list.get(i).get("elevatorNum").toString());
                    bodyRow.createCell(1).setCellValue(list.get(i).get("errorCode") == null ? "" : list.get(i).get("errorCode").toString());
                    if (list.get(i).get("insSts") != null) {
    
    
                        int insSts = Integer.parseInt(list.get(i).get("insSts").toString());
                        if (insSts == 1) {
    
    
                            bodyRow.createCell(2).setCellValue("检修");
                        } else if (insSts == 2) {
    
    
                            bodyRow.createCell(2).setCellValue("正常");
                        } else if (insSts == 0) {
    
    
                            bodyRow.createCell(2).setCellValue("故障");
                        } else {
    
    
                            bodyRow.createCell(2).setCellValue("-");
                        }
                    }else{
    
    
                        bodyRow.createCell(2).setCellValue("-");
                    }
                    bodyRow.createCell(3).setCellValue(list.get(i).get("floor") == null ? "" : list.get(i).get("floor").toString());
                    bodyRow.createCell(4).setCellValue(list.get(i).get("reportTime") == null ? "" : list.get(i).get("reportTime").toString());
                }
            }
            //重置响应,将响应设置为流文件传递到前端
            output = response.getOutputStream();
            response.reset();
            response.setContentType("application/octet-stream");
            sxssfWorkbook.write(output);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            if (output != null) {
    
    
                output.close();
            }
        }
        long end = System.currentTimeMillis();
        logger.info("完成导出故障记录,耗时:{}{}", end - begin, "毫秒");
    }
}
  

Please study the official website for details on word, excel and other related office operations .

Guess you like

Origin blog.csdn.net/qq_30385099/article/details/114917350