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

}

相关推荐
Source.Liu7 分钟前
【用Rust写CAD】第二章 第四节 函数
开发语言·rust
monkey_meng8 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马11 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng14 分钟前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
七星静香15 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员16 分钟前
java导出word文件(手绘)
java·开发语言·word
ZHOUPUYU17 分钟前
IntelliJ IDEA超详细下载安装教程(附安装包)
java·ide·intellij-idea
q24985969318 分钟前
前端预览word、excel、ppt
前端·word·excel
stewie620 分钟前
在IDEA中使用Git
java·git
小白学大数据23 分钟前
正则表达式在Kotlin中的应用:提取图片链接
开发语言·python·selenium·正则表达式·kotlin