java导出excel浏览器下载,单线程VS多线程
package com.mengyang.transactional.other.excelxssf;
import com.mengyang.transactional.other.myselfExcel.ExcelUtils;
import com.mengyang.transactional.pojo.ZhongXinDTO;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
public class ExportExcelUtil {
Class<T> clazz;
public ExportExcelUtil(Class<T> clazz) {
this.clazz = clazz;
}
//单线程
public void exportExcel(HttpServletResponse response, String excelHeaer, int sheetNum, List<T> dataList) {
SXSSFWorkbook workbook = new SXSSFWorkbook(-1);
String fileName = "中信报表导出" + ".xlsx";
try {
//使用workbook对象创建样式对象
CellStyle cellStyle = workbook.createCellStyle();
//创建字体对象
Font font = workbook.createFont();
//处理表格头部信息
String[] head = excelHeaer.split(",");
// 得到目标目标类的所有的字段列表
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
}
Sheet sheet = workbook.createSheet("XXX");
ExcelUtils.setCellStyle(sheet, cellStyle, font);
//遍历集合中的数据
Iterator<T> iterator = dataList.iterator();
int currentRow = 0;
//写入头信息
Row row = sheet.createRow(currentRow);
for (int i = 0; i < head.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(head[i]);
cell.setCellStyle(cellStyle);
}
currentRow++;
//写入业务数据
while (iterator.hasNext()) {
T t = iterator.next();
row = sheet.createRow(currentRow);
for (int i = 0; i < fields.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(String.valueOf(fields[i].get(t)));
cell.setCellStyle(cellStyle);
}
currentRow++;
}
//下载
response.reset();
response.setContentType("application/octet-stream; charset=utf-8");//以流的形式对文件进行下载
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));//对文件名编码,防止文件名乱码
workbook.write(response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
} finally {
//删除之前保存的临时文件
workbook.dispose();
}
}
public void exportExcelAndMoreThread(HttpServletResponse response, String excelHeaer, int sheetNum, List<T> dataList) {
SXSSFWorkbook workbook = new SXSSFWorkbook(-1);
String fileName = "中信报表导出" + ".xlsx";
try {
//使用workbook对象创建样式对象
CellStyle cellStyle = workbook.createCellStyle();
//创建字体对象
Font font = workbook.createFont();
//处理表格头部信息
String[] head = excelHeaer.split(",");
CountDownLatch countDownLatch = new CountDownLatch(sheetNum);//倒计时开关
// 得到目标目标类的所有的字段列表
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
}
//遍历集合中的数据
//Iterator<T> iterator = dataList.iterator();
int currentRow = 0;
if (Objects.equals(0, sheetNum)) {//单线程处理
Sheet sheet = workbook.createSheet("XXX");
ExcelUtils.setCellStyle(sheet, cellStyle, font);
//遍历集合中的数据
Iterator<T> iterator = dataList.iterator();
//写入头信息
Row row = sheet.createRow(currentRow);
for (int i = 0; i < head.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(head[i]);
cell.setCellStyle(cellStyle);
}
currentRow++;
//写入业务数据
while (iterator.hasNext()) {
T t = iterator.next();
row = sheet.createRow(currentRow);
for (int i = 0; i < fields.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(String.valueOf(fields[i].get(t)));
cell.setCellStyle(cellStyle);
}
currentRow++;
}
} else {
int dataCount = dataList.size();//数据的长度//如何把list集合分成对应的份数,开几条线程就相当于把数据分成几份
int avgNum = (int) Math.floor(dataCount / sheetNum);//获得平均值
int remainder = dataCount % sheetNum;//最后有余数 102%4 =2
int fromIndex = 0;
int toIndex = 0;
for (int i = 0; i < sheetNum; i++) {
fromIndex = i * avgNum;
if (i == sheetNum - 1) {
//最后一个线程被开启
toIndex = (i + 1) * avgNum - 1 + remainder;
} else {
toIndex = (i + 1) * avgNum - 1;
}
//分解数据
List<T> data = dataList.subList(fromIndex, toIndex + 1);
Sheet sheet1 = workbook.createSheet("项目数据" + i);
ExcelUtils.setCellStyle(sheet1, cellStyle, font);
new Thread(() -> {
Iterator<T> iterator = data.iterator();
int startIndex = 0;
Row row = sheet1.createRow(startIndex);
for (int j = 0; j < head.length; j++) {
Cell cell = row.createCell(j);
cell.setCellValue(head[j]);
cell.setCellStyle(cellStyle);
}
startIndex++;
while (iterator.hasNext()) {
T t = iterator.next();
row = sheet1.createRow(startIndex);
for (int k = 0; k < fields.length; k++) {
Cell cell = row.createCell(k);
try {
cell.setCellValue(String.valueOf(fields[k].get(t)));
cell.setCellStyle(cellStyle);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
startIndex++;
}
countDownLatch.countDown();
}, "线程" + i).start();
}
//告诉主线程,要等所有的线程运行完再进行Excel的导出
countDownLatch.await();
}
//下载
response.reset();
response.setContentType("application/octet-stream; charset=utf-8");//以流的形式对文件进行下载
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));//对文件名编码,防止文件名乱码
workbook.write(response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
} finally {
//删除之前保存的临时文件
workbook.dispose();
}
}
}