使用多线程导出excel时可能的问题

导入apachepoi依赖

 <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.16</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.16</version>
        </dependency>

 此时以thread举例,代码如下:

public class PoiDemo02 {
    public static void main(String[] args) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet01 = workbook.createSheet();
        XSSFSheet sheet02 = workbook.createSheet();
       Thread thread01= new Thread(()->{
            write(sheet01);
        });
       thread01.start();
        Thread thread02= new Thread(()->{
            write(sheet02);
        });
        thread02.start();
        try {
            thread01.join();---------------01
            thread02.join();---------------02
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //通过文件输出流将内存中的excel写入到文件中
        FileOutputStream fileOutputStream = new FileOutputStream("G:\\code" + File.separator + "POITest.xlsx");
        workbook.write(fileOutputStream);
        workbook.close();
    }

    public static void write(XSSFSheet sheet){
        XSSFRow xssfRow = sheet.createRow(0);
        XSSFCell cell01 = xssfRow.createCell(0);
        cell01.setCellValue("成绩");
        XSSFCell cell02 = xssfRow.createCell(1);
        cell02.setCellValue("姓名");
        String[] surname={"李","张","赵","孙","王","欧阳","皇甫","曹"};
        String[] name={"阳","春","白","雪","曲","高","和","寡","大","富","大","贵"};
        for (int i = 1; i < 10; i++) {
          int surnamei=  new Random().nextInt(7);
          int namei=  new Random().nextInt(11);
          String studentName= surname[surnamei]+name[namei];
            writeRandom(sheet,i,studentName);
        }
    }
    public static void writeRandom(XSSFSheet sheet,int rowNum,String name){
        XSSFRow xssfRow = sheet.createRow(rowNum);
        XSSFCell cell01 = xssfRow.createCell(0);
        cell01.setCellValue(new Random().nextInt(100));
        XSSFCell cell02 = xssfRow.createCell(1);
        cell02.setCellValue(name);
    }
}

执行后导出excel内容为

如果将01和02行注释掉,代码为:

public class PoiDemo02 {
    public static void main(String[] args) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet01 = workbook.createSheet();
        XSSFSheet sheet02 = workbook.createSheet();
       Thread thread01= new Thread(()->{
            write(sheet01);
        });
       thread01.start();
        Thread thread02= new Thread(()->{
            write(sheet02);
        });
        thread02.start();
//        try {
//            thread01.join();
//            thread02.join();
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
        //通过文件输出流将内存中的excel写入到文件中
        FileOutputStream fileOutputStream = new FileOutputStream("G:\\code" + File.separator + "POITest.xlsx");
        workbook.write(fileOutputStream);
        workbook.close();
    }

    public static void write(XSSFSheet sheet){
        XSSFRow xssfRow = sheet.createRow(0);
        XSSFCell cell01 = xssfRow.createCell(0);
        cell01.setCellValue("成绩");
        XSSFCell cell02 = xssfRow.createCell(1);
        cell02.setCellValue("姓名");
        String[] surname={"李","张","赵","孙","王","欧阳","皇甫","曹"};
        String[] name={"阳","春","白","雪","曲","高","和","寡","大","富","大","贵"};
        for (int i = 1; i < 10; i++) {
          int surnamei=  new Random().nextInt(7);
          int namei=  new Random().nextInt(11);
          String studentName= surname[surnamei]+name[namei];
            writeRandom(sheet,i,studentName);
        }
    }
    public static void writeRandom(XSSFSheet sheet,int rowNum,String name){
        XSSFRow xssfRow = sheet.createRow(rowNum);
        XSSFCell cell01 = xssfRow.createCell(0);
        cell01.setCellValue(new Random().nextInt(100));
        XSSFCell cell02 = xssfRow.createCell(1);
        cell02.setCellValue(name);
    }
}

 执行代码后得到的excel内容入下

此时发现数据是不完整的,这是为什么呢?

在代码中插入03,04,05,06行代码,运行:

public class PoiDemo02 {
    public static void main(String[] args) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet01 = workbook.createSheet();
        XSSFSheet sheet02 = workbook.createSheet();
       Thread thread01= new Thread(()->{
           System.out.println(Thread.currentThread().getName()+"开始---"+System.currentTimeMillis());--------03
            write(sheet01);
           System.out.println(Thread.currentThread().getName()+"结束---"+System.currentTimeMillis());-------04
        });
       thread01.start();
        Thread thread02= new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"开始---"+System.currentTimeMillis());-----------05
            write(sheet02);
            System.out.println(Thread.currentThread().getName()+"结束---"+System.currentTimeMillis());----------06
        });
        thread02.start();
        try {
            thread01.join();
            thread02.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //通过文件输出流将内存中的excel写入到文件中
        FileOutputStream fileOutputStream = new FileOutputStream("G:\\code" + File.separator + "POITest.xlsx");
        System.out.println(Thread.currentThread().getName()+"-----"+System.currentTimeMillis());-------------07
        workbook.write(fileOutputStream);
        System.out.println(Thread.currentThread().getName()+"-----"+System.currentTimeMillis());-------------08
        workbook.close();

    }

    public static void write(XSSFSheet sheet){
        XSSFRow xssfRow = sheet.createRow(0);
        XSSFCell cell01 = xssfRow.createCell(0);
        cell01.setCellValue("成绩");
        XSSFCell cell02 = xssfRow.createCell(1);
        cell02.setCellValue("姓名");
        String[] surname={"李","张","赵","孙","王","欧阳","皇甫","曹"};
        String[] name={"阳","春","白","雪","曲","高","和","寡","大","富","大","贵"};
        for (int i = 1; i < 10; i++) {
          int surnamei=  new Random().nextInt(7);
          int namei=  new Random().nextInt(11);
          String studentName= surname[surnamei]+name[namei];
            writeRandom(sheet,i,studentName);
        }
    }
    public static void writeRandom(XSSFSheet sheet,int rowNum,String name){
        XSSFRow xssfRow = sheet.createRow(rowNum);
        XSSFCell cell01 = xssfRow.createCell(0);
        cell01.setCellValue(new Random().nextInt(100));
        XSSFCell cell02 = xssfRow.createCell(1);
        cell02.setCellValue(name);
    }

 代码运行后输出结果为

Thread-0开始---1749737101859
Thread-1开始---1749737101860
main-----1749737101861
Thread-1结束---1749737101915
Thread-0结束---1749737101916
main-----1749737102034

导出excel为:

此时把01,02行代码放开,代码如下:

public class PoiDemo02 {
    public static void main(String[] args) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet01 = workbook.createSheet();
        XSSFSheet sheet02 = workbook.createSheet();
       Thread thread01= new Thread(()->{
           System.out.println(Thread.currentThread().getName()+"开始---"+System.currentTimeMillis());
            write(sheet01);
           System.out.println(Thread.currentThread().getName()+"结束---"+System.currentTimeMillis());
        });
       thread01.start();
        Thread thread02= new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"开始---"+System.currentTimeMillis());
            write(sheet02);
            System.out.println(Thread.currentThread().getName()+"结束---"+System.currentTimeMillis());
        });
        thread02.start();
        try {
            thread01.join();
            thread02.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //通过文件输出流将内存中的excel写入到文件中
        FileOutputStream fileOutputStream = new FileOutputStream("G:\\code" + File.separator + "POITest.xlsx");
        System.out.println(Thread.currentThread().getName()+"-----"+System.currentTimeMillis());
        workbook.write(fileOutputStream);
        System.out.println(Thread.currentThread().getName()+"-----"+System.currentTimeMillis());
        workbook.close();

    }

    public static void write(XSSFSheet sheet){
        XSSFRow xssfRow = sheet.createRow(0);
        XSSFCell cell01 = xssfRow.createCell(0);
        cell01.setCellValue("成绩");
        XSSFCell cell02 = xssfRow.createCell(1);
        cell02.setCellValue("姓名");
        String[] surname={"李","张","赵","孙","王","欧阳","皇甫","曹"};
        String[] name={"阳","春","白","雪","曲","高","和","寡","大","富","大","贵"};
        for (int i = 1; i < 10; i++) {
          int surnamei=  new Random().nextInt(7);
          int namei=  new Random().nextInt(11);
          String studentName= surname[surnamei]+name[namei];
            writeRandom(sheet,i,studentName);
        }
    }
    public static void writeRandom(XSSFSheet sheet,int rowNum,String name){
        XSSFRow xssfRow = sheet.createRow(rowNum);
        XSSFCell cell01 = xssfRow.createCell(0);
        cell01.setCellValue(new Random().nextInt(100));
        XSSFCell cell02 = xssfRow.createCell(1);
        cell02.setCellValue(name);
    }
}

 运行代码后输出为:

Thread-0开始---1749737292754
Thread-1开始---1749737292755
Thread-0结束---1749737292819
Thread-1结束---1749737292820
main-----1749737292821
main-----1749737292961

导出excel为:

这里涉及到了子线程和主线程的执行顺序,有兴趣的可以csdn查找下,顺便说下,在多线程下开启spring事务时也要考虑到主线程和子线程的顺序问题,一般开发中不会这样new线程多是使用线程池来开启多线程,例中只是为了方便理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值