POI: calculated end index (4361) is out of allowable range (4339..4358)

  问题描述:

  1)使用同步的方式没有问题;

  2)使用多线程的方式报错;

  出现问题的代码(使用的POI 版本3.17)

package com.oy.controller;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

public class PoifsWriter {
    private FileOutputStream outputFile;
    private int rowCount;

    public PoifsWriter(String filename, int rowCount) throws FileNotFoundException {
        this.outputFile = new FileOutputStream(filename);
        this.rowCount = rowCount;
    }

    public void writeOutData() throws Exception {
        try {
            Workbook wb = new HSSFWorkbook();
            int threadNum = 2;
            CountDownLatch latch = new CountDownLatch(threadNum);

            for (int i = 0; i < threadNum; i++) {
          // Sheet sheet = wb.createSheet("test-sheet" + System.currentTimeMillis() + new Random().nextInt(1000)); // sheet创建在父线程 ExecutorService es
= Executors.newCachedThreadPool(); es.execute(() -> { Sheet sheet = wb.createSheet("test-sheet" + System.currentTimeMillis() + new Random().nextInt(1000)); for (int r = 0; r < rowCount; r++) { Row row = sheet.createRow((short) r); row.createCell(0).setCellValue(1.03 * (r + 7)); row.createCell(1).setCellValue(new Date()); row.createCell(2).setCellValue(Calendar.getInstance()); row.createCell(3).setCellValue(String.format("row:%d/col:%d", r, 3)); row.createCell(4).setCellValue(true); row.createCell(5).setCellType(Cell.CELL_TYPE_ERROR); } latch.countDown(); }); } latch.await(); wb.write(outputFile); } finally { outputFile.close(); } } public static void main(String[] args) throws Exception { String version = HSSFWorkbook.class.getPackage().getImplementationVersion(); System.out.println("POI Version: " + version); String filename = "e:/a.xls"; int rowCount = 10; PoifsWriter writer = new PoifsWriter(filename, rowCount); writer.writeOutData(); } }

  分析:

  1)在子线程中创建sheet产生并发。

  2)把参数int threadNum = 2;改为10,结果如下

Exception in thread "pool-8-thread-1" Exception in thread "pool-5-thread-1" Exception in thread "pool-7-thread-1" Exception in thread "pool-4-thread-1" java.lang.RuntimeException: Sheet number out of bounds!
    at org.apache.poi.hssf.model.InternalWorkbook.checkSheets(InternalWorkbook.java:765)
    at org.apache.poi.hssf.model.InternalWorkbook.setSheetName(InternalWorkbook.java:599)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.createSheet(HSSFWorkbook.java:954)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.createSheet(HSSFWorkbook.java:131)
    at com.oy.controller.PoifsWriter.lambda$0(PoifsWriter.java:37)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
java.lang.RuntimeException: Sheet number out of bounds!
    at org.apache.poi.hssf.model.InternalWorkbook.checkSheets(InternalWorkbook.java:765)
    at org.apache.poi.hssf.model.InternalWorkbook.setSheetName(InternalWorkbook.java:599)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.createSheet(HSSFWorkbook.java:954)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.createSheet(HSSFWorkbook.java:131)
    at com.oy.controller.PoifsWriter.lambda$0(PoifsWriter.java:37)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
java.lang.ArrayIndexOutOfBoundsException: 3
    at java.util.ArrayList.add(ArrayList.java:463)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.createSheet(HSSFWorkbook.java:955)

  3)修改为:在父线程创建sheet

原文地址:https://www.cnblogs.com/xy-ouyang/p/14715778.html