easypoi导出excel模板,使用poi导出大量数据到excel遇到的问题

 2023-09-26 阅读 18 评论 0

摘要:最近在工作遇到利用poi导出大量数据到excel并提供下载的运用场景,并遇到了一个问题,当数据量过大时(几十万),后台在进行数据写入excel中的过程会非常耗时,导致迟迟没有响应前台,结果数据还没导完,前台页面就已经崩掉了。 解决思路&

最近在工作遇到利用poi导出大量数据到excel并提供下载的运用场景,并遇到了一个问题,当数据量过大时(几十万),后台在进行数据写入excel中的过程会非常耗时,导致迟迟没有响应前台,结果数据还没导完,前台页面就已经崩掉了。


解决思路:接收到前台导出excel请求之后,开一个线程,在线程里进行数据的写入和将写入完成的excel保存到服务器中等耗时操作,前台定时发送ajax请求检测是否已经导出完成,如果完成则提供一个下载链接到前台供用户下载。


想到解决思路之后,自己写了一个小demo,顺便学习下利用poi导出excel,同时还在定时检测的时候加了一个百分比进度到前台显示已经导出了多少数据。

easypoi导出excel模板?

后台ExcelServlet:

package com.myj.servlet;import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;import com.myj.user.User;public class ExcelServlet extends HttpServlet{//用户并发访问时,使用map保存相应数据//存放写入完成标志private static Map<String, Boolean> flagMap = new HashMap<String, Boolean>();//存放线程private static Map<Long, MyThread> excelHelperMap = new HashMap<Long, MyThread>();;@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTf-8");response.setHeader("Cache-Control","no-cache");  //HTTP 1.1response.setHeader("Pragma","no-cache");         //HTTP 1.0response.setDateHeader ("Expires", 0); String action = request.getParameter("action");//flagMap.put(ip, false);if("outExcel".equals(action)){String fileName = String.valueOf(new Date().getTime())+".xls";System.out.println("fileName:"+fileName);flagMap.put(fileName, false);System.out.println(flagMap.get(fileName));//ServletOutputStream sos = response.getOutputStream();String filePath = request.getServletContext().getRealPath("/") + fileName;System.out.println(request.getSession().getServletContext().getRealPath("/"));System.out.println("filePath:"+filePath);//开启线程进行写入操作long threadId = beginProcess(request, filePath, response, fileName);//将必要的参数写回前台,并在定时检测时提交回来response.getWriter().write(fileName+","+threadId);//定时检测是否写入完成	}else if("checkFin".equals(action)){String fileName = request.getParameter("fileName");long threadId = Long.valueOf(request.getParameter("threadId"));if(flagMap.get(fileName)==null?false:flagMap.get(fileName)){response.reset();response.getWriter().write(String.valueOf(flagMap.get(fileName)));flagMap.put(fileName, false);}else{//将进度写回前台显示response.getWriter().write(procBar(threadId));}System.out.println(procBar(threadId));//response.getWriter().write("");//下载excel}else if("downloadExcel".equals(action)){String fileName = request.getParameter("fileName");response.reset();response.setContentType("APPLICATION/OCTET-STREAM");   response.setHeader("Content-Disposition", "attachment;filename="+"report.xls");   String filePath = request.getServletContext().getRealPath("/")+fileName;System.out.println(filePath);FileInputStream fis = new FileInputStream(filePath);PrintWriter out = response.getWriter();int i = 0;System.out.println("开始下载excel...");while((i=fis.read())!=-1){out.write(i);}System.out.println("下载完毕.");fis.close();out.flush();out.close();}}//获取测试数据public static List<User> getUserList(){List<User> userList = new ArrayList<User>();for(int i=0;i<1000000;i++){User user = new User();user.setName("user"+i);user.setAge(20);userList.add(user);}return userList;}//接收请求之后开启一个线程进行将数据写入excel和保存服务器操作public long beginProcess(HttpServletRequest request, String filePath, HttpServletResponse response, String fileName) {//test caseMyThread excelHelper = new MyThread(request, filePath, response, fileName);excelHelper.start();long threadId = excelHelper.getId();excelHelperMap.put(threadId, excelHelper);return threadId;}public int getRowIndex(long threadId) {MyThread excelHelper = excelHelperMap.get(threadId);if ((excelHelper.getRowIndex()-2)<excelHelper.getCount()) {return excelHelper.getRowIndex();}else {return -1;}}//获取百分比进度public String procBar(long threadId){MyThread excelHelper = excelHelperMap.get(threadId);//减去两行才是数据行double pro = (double)(excelHelper.getRowIndex()-2)/(double)excelHelper.getCount();NumberFormat nf = NumberFormat.getPercentInstance();nf.setMinimumFractionDigits(2);return nf.format(pro);}/*** 进行将数据写入excel和将写入完成的excel* 保存到服务器等耗时的操作**/public class MyThread extends Thread{private HttpServletRequest request;private String filePath;private HttpServletResponse response;private String fileName;private int rownum = 0;private int count;public MyThread(HttpServletRequest request, String filePath, HttpServletResponse response, String fileName){this.request = request;this.filePath = filePath;this.response = response;this.fileName = fileName;this.count = getUserList().size();}public int getRowIndex() {return rownum;}public int getCount() {return count;}@Overridepublic void run() {Sheet sheet = null;Row row = null;Workbook workbook = new SXSSFWorkbook(2000);sheet = workbook.createSheet();row = sheet.createRow(0);row.createCell(5).setCellValue("测试表");row = sheet.createRow(1);row.createCell(0).setCellValue("姓名");row.createCell(1).setCellValue("年龄");rownum = 2;System.out.println("开始将数据写入excel...");for(User u : getUserList()){row = sheet.createRow(rownum);row.createCell(0).setCellValue(u.getName());row.createCell(1).setCellValue(u.getAge());rownum++;}System.out.println("写入完毕,开始保存到服务器硬盘...");BufferedOutputStream bos = null;try {bos = new BufferedOutputStream(new FileOutputStream(filePath));workbook.write(bos);System.out.println("保存完毕。");bos.flush();//				workbook = null;
//				workbook = new SXSSFWorkbook(2000);System.out.println("线程里的fileName:"+fileName);flagMap.put(fileName, true);System.out.println("线程里的flag:"+flagMap.get(fileName));} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}finally{try {bos.close();} catch (IOException e) {e.printStackTrace();}}}}}

前台testExcel.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title><script type="text/javascript">var fileName = "";var threadId = "";function out(){var xmlhttp;if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safarixmlhttp=new XMLHttpRequest();}else{// code for IE6, IE5xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}xmlhttp.onreadystatechange=function(){if (xmlhttp.readyState==4 && xmlhttp.status==200){data = xmlhttp.responseText;dataArr = data.split(",");fileName = dataArr[0];threadId = dataArr[1];checkFin();}}xmlhttp.open("POST","excelServlet",true);xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");xmlhttp.send("action=outExcel");}function checkFin(){loadXMLDoc();t = setTimeout("checkFin()", 500);}function stop(){clearTimeout(t);}//定时发送ajax请求,检测后台时候都出完毕function loadXMLDoc(){var xmlhttp;if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safarixmlhttp=new XMLHttpRequest();}else{// code for IE6, IE5xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}xmlhttp.onreadystatechange=function(){if (xmlhttp.readyState==4 && xmlhttp.status==200){var flag = xmlhttp.responseText;if(flag == "true"){	//导出完毕,提供连接进行下载clearTimeout(t);var a = document.createElement("a");a.setAttribute("href","excelServlet?action=downloadExcel&fileName="+fileName);a.innerText = "下载excel";document.getElementById("d1").appendChild(a);}else{	//还没导完,显示导了多少数据document.getElementById("proc").innerText = flag;}}}xmlhttp.open("POST","excelServlet?action=checkFin&fileName="+fileName+"&threadId="+threadId,true);xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");xmlhttp.send(); //window.location.href = "excelServlet?action=checkFin";}
</script></head>
<body><form action="excelServlet"><input type="button" name="submit1" value="输出excel" οnclick="out();"/><input type="hidden" name="action" value="outExcel"/></form><div id="d1"></div><h3 id="proc"></h3>
</body>
</html>


poi数据怎么获取。根据自己写的demo,修改了原来项目导出excel的代码后,问题解决。



版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/97329.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息