java导出excel浏览器下载,单线程VS多线程

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();
    }
}

}

相关推荐
程序员是干活的几秒前
私家车开车回家过节会发生什么事情
java·开发语言·软件构建·1024程序员节
煸橙干儿~~11 分钟前
分析JS Crash(进程崩溃)
java·前端·javascript
2401_8543910812 分钟前
Spring Boot大学生就业招聘系统的开发与部署
java·spring boot·后端
Amor风信子13 分钟前
华为OD机试真题---跳房子II
java·数据结构·算法
我是陈泽16 分钟前
一行 Python 代码能实现什么丧心病狂的功能?圣诞树源代码
开发语言·python·程序员·编程·python教程·python学习·python教学
优雅的小武先生26 分钟前
QT中的按钮控件和comboBox控件和spinBox控件无法点击的bug
开发语言·qt·bug
虽千万人 吾往矣33 分钟前
golang gorm
开发语言·数据库·后端·tcp/ip·golang
创作小达人35 分钟前
家政服务|基于springBoot的家政服务平台设计与实现(附项目源码+论文+数据库)
开发语言·python
郭二哈38 分钟前
C++——list
开发语言·c++·list
杨荧39 分钟前
【JAVA开源】基于Vue和SpringBoot的洗衣店订单管理系统
java·开发语言·vue.js·spring boot·spring cloud·开源