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
posted on 2021-04-28 20:58 wenbin_ouyang 阅读(220) 评论(0) 编辑 收藏 举报