多线程读POI

在做POI的时候,为了提高性能,我们一般会用多线程来分批读取大量数据。

1.自己写一个类实现Runable接口专为poi实现多线程的线程类

public class POIThread implements Runnable{

    //从哪一行开始读
    private Integer startRows;
    //读取到哪一行
    private Integer endRows;
    //读取哪一个对象

    //POI线程的构造方法
    public POIThread(Integer startRows, Integer endRows, XSSFSheet sheet) {
        super();
        this.startRows = startRows;
        this.endRows = endRows;
        this.sheet = sheet;
    }

    public void run() {
        System.out.println("我是"+Thread.currentThread().getName());
        //读取规定的内容
        for (int i = startRows; i <= endRows; i++) {
            System.out.println(sheet.getRow(i).getCell(0)+"\t"+sheet.getRow(i).getCell(1)+"\t"+sheet.getRow(i).getCell(2));
        }
    }

    //set、get方法
    public Integer getStartRows() {
        return startRows;
    }

    public void setStartRows(Integer startRows) {
        this.startRows = startRows;
    }

    public Integer getEndRows() {
        return endRows;
    }

    public void setEndRows(Integer endRows) {
        this.endRows = endRows;
    }

    public XSSFSheet getSheet() {
        return sheet;
    }

    public void setSheet(XSSFSheet sheet) {
        this.sheet = sheet;
    }
}

2.以springmvc为例,controller层

@Controller
@RequestMapping("/poi")
public class POIController throws Exception{
    @RequestMapping("test")
    public String test(MultipartFile excelFile) {
        System.out.println("姓名"+"\t"+"年龄"+"\t"+"性别");
        InputStream inputStream = excelFile.getInputStream();
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            for(int i=0;i//当前页不为空
                if (excel.getSheetAt(i)!=null) {
                    //获取当前页的所有行
                    int sumRows = excel.getSheetAt(i).getLastRowNum();
                    //开启的线程数(每两个开启一个线程)
                    int threadNum;  
                    if (sumRows%2==0) {
                            threadNum = sumRows/2;
                    }else{
                            threadNum = sumRows/2+1;
                    }
                    //因为刚开始和中间还有结束三种情况不一样
                    //比如0~1、1~2、最后一个
                    for(int currentTreadNum=0;currentTreadNumif (currentTreadNum == 0) {
                            POIThread poiThread = new POIThread(currentTreadNum, currentTreadNum+1, excel.getSheetAt(i));
                        new Thread(poiThread).strat();
                        }else if (currentTreadNum == threadNum-1) {
                            POIThread poiThread = new POIThread(currentTreadNum*2, sumRows-1, excel.getSheetAt(i));
                        new Thread(poiThread).strat();
                        }else {
                            POIThread poiThread = new POIThread(currentTreadNum*2, currentTreadNum*2+1, excel.getSheetAt(i));
                        new Thread(poiThread).strat();
                        }
                }else{
                    countine;
                }
            }
    }
}

3.excel文件

姓名 年龄 性别
张三 1
李四 2
王五 3

重点:这里多线程读出来的是乱序的。

你可能感兴趣的:(多线程读POI)