前言:前段时间在写表格导出的时候,需要导出的数据集合需要循环处理,但是速度太慢,所以看了一下如何使用多线程加快导出速度,如有不足之处,请多批评指正。
注意:对象类实现Cloneable接口,不然导出会发现数据混乱。
@Data
public class EmployeeException extends BaseObject implements Cloneable {
private String employeeId;
private Date exceptionDate;
private Integer exceptionType;
private String name;
private String startTime;
private String endTime;
private String departmentId;
private String projectId;
private String signInTime;
private String signLocation;
private String signOutTime;
private String signOutLocation;
private String projectName;
private String startTimeForCut;
private String endTimeForCut;
private Integer status;
@Override
public EmployeeException clone() throws CloneNotSupportedException {
return (EmployeeException)super.clone();
}
}
1、Controller层方法
public void exportEmployeeException(employeeException) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
InputStream inStream = null;
OutputStream outputStream = null;
String isExport = "succ";
HttpSession session = this.getServletRequest().getSession();
try {
employeeExceptionService.exportEmployeeException2(employeeException, os);
String fileName = URLEncoder.encode(dateFormat.format(new Date()) + "列表");
os.flush();
byte[] buf = os.toByteArray();
log.info("生成excel长度:" + buf.length + "字节");
inStream = new ByteArrayInputStream(buf);
this.getServletResponse().reset();
this.getServletResponse().setContentType("application/vnd.ms-excel");
this.getServletResponse().setCharacterEncoding("UTF-8");
this.getServletResponse().addHeader("Content-Disposition",
"attachment; filename=\"" + fileName + ".xlsx\"");
byte[] b = new byte[1024];
int len;
outputStream = this.getServletResponse().getOutputStream();
while ((len = inStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
} catch (Exception e) {
log.error("{}", e);
isExport = "fail";
} finally {
try {
if (os != null) {
os.close();
}
if (inStream != null) {
inStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (Exception e) {
logger.error("os close exception!!", e);
}
session.setAttribute("isExport", isExport);
}
}
2、service层方法
注:handleList(employeeException, employeeExceptionList, 5)方法用到了多线程的知识。
public void exportEmployeeException2(EmployeeException employeeException, ByteArrayOutputStream os) throws InterruptedException {
List<EmployeeException> employeeExceptionList = employeeExceptionMapper.selectAllEmployeeExceptionList(employeeException);
handleList(employeeException, employeeExceptionList, 5);
ArrayList<Map<String, String>> data = new ArrayList<>();
for (EmployeeExceptionExport employeeExceptionExport : employeeExceptionExportList) {
Map<St