一. 异常报告

java.util.concurrent.ExecutionException: org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException:
A part with the name '/xl/worksheets/sheet1.xml' already exists : Packages shall not
contain equivalent part names and package implementers shall neither create nor recognize
packages with equivalent part names. [M1.12]at java.util.concurrent.FutureTask.report(FutureTask.java:122)at java.util.concurrent.FutureTask.get(FutureTask.java:192)at com.xlcloud.business.vip.util.parallel.ParallelQueryExecutor.execute(ParallelQueryExecutor.java:62)at com.xlcloud.business.vip.service.orders.NewExportGoodsOldOrderService.newExportGoodsOrderList(NewExportGoodsOldOrderService.java:54)at com.xlcloud.business.vip.service.orders.NewExportGoodsOldOrderService$$FastClassBySpringCGLIB$$cf8ecc61.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)at org.springframework.aop.interceptor.AsyncExecutionInterceptor$$Lambda$714/372457144.call(Unknown Source)at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)at java.util.concurrent.FutureTask.run(FutureTask.java)at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException: A part with the name '/xl/worksheets/sheet1.xml' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]at org.apache.poi.openxml4j.opc.OPCPackage.createPart(OPCPackage.java:889)at org.apache.poi.openxml4j.opc.OPCPackage.createPart(OPCPackage.java:853)at org.apache.poi.POIXMLDocumentPart.createRelationship(POIXMLDocumentPart.java:558)at org.apache.poi.xssf.usermodel.XSSFWorkbook.createSheet(XSSFWorkbook.java:858)at org.apache.poi.xssf.streaming.SXSSFWorkbook.createSheet(SXSSFWorkbook.java:677)at com.xlcloud.business.vip.service.orders.PayOrderNewOldTask.orderAreaExcel(PayOrderNewOldTask.java:52)at com.xlcloud.business.vip.service.orders.PayOrderNewOldTask.results(PayOrderNewOldTask.java:41)at com.xlcloud.business.vip.util.parallel.ParallelTask.call(ParallelTask.java:20)at com.xlcloud.business.vip.util.parallel.ParallelTask.call(ParallelTask.java:10)at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)at java.util.concurrent.FutureTask.run(FutureTask.java)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)... 1 common frames omitted

二. 产生背景和解决方案

   问题背景: 使用多线程绘制excel表格,每个线程创建一个sheet,测试服偶现上面的异常信息,且频率较高。看源码也没发现什么问题,传入的sheet名称确定是完全不同的。一时间没有定位问题。
   在后来,觉得是多线程绘制表格产生的问题。再次看源码,发现问题:

1)报错位置

PackagePart createPart(PackagePartName partName, String contentType,boolean loadRelationships) {throwExceptionIfReadOnly();if (partName == null) {throw new IllegalArgumentException("partName");}if (contentType == null || contentType.equals("")) {throw new IllegalArgumentException("contentType");}// Check if the specified part name already existsif (partList.containsKey(partName)&& !partList.get(partName).isDeleted()) {throw new PartAlreadyExistsException("A part with the name '" + partName.getName() + "'" +" already exists : Packages shall not contain equivalent part names and package" +" implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");}.......
}

2)向上查找

   由报错位置可知partName重复了,继续往上找

 protected final RelationPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){try {PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));PackageRelationship rel = null;PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());......}}

   由上可知 partName 是由 descriptor 中根据idx获取的,idx可能在多线程中传入的是相同的

 public XSSFSheet createSheet(String sheetname) {......int sheetNumber = 1;outerloop:while(true) {for(XSSFSheet sh : sheets) {sheetNumber = (int)Math.max(sh.sheet.getSheetId() + 1, sheetNumber);}// Bug 57165: We also need to check that the resulting file name is not already taken// this can happen when moving/cloning sheetsString sheetName = XSSFRelation.WORKSHEET.getFileName(sheetNumber);for(POIXMLDocumentPart relation : getRelations()) {if(relation.getPackagePart() != null && sheetName.equals(relation.getPackagePart().getPartName().getName())) {// name is taken => try next onesheetNumber++;continue outerloop;}}// no duplicate found => use this onebreak;}RelationPart rp = createRelationship(XSSFRelation.WORKSHEET, XSSFFactory.getInstance(), sheetNumber, false);......}

  可以看出,当前方法线程不安全,多线程下同一个Workbook对象可能产生相同的sheetNumber,从而导致文中最上面产生的问题。

三. 解决方法

   在创建sheet时,加同步锁

SXSSFSheet sheet;
synchronized (ExportOrder.class){sheet=wb.createSheet(goodsOrderRequestDto.getSheetName());
}

A part with the name ‘/xl/worksheets/sheet1.xml‘ already exists : Packages shall not contain equival相关推荐

  1. EASYPOI导入报错The part /xl/drawings/drawing1.xml failed to be saved

    EASYPOI导入报错The part /xl/drawings/drawing1.xml failed to be saved Caused by: org.apache.poi.openxml4j ...

  2. java代码使用http请求解压zip包并解析xml_Javascript 是如何解析 Excel 文件的?

    最近要做一个导入导出 Excel 的功能,上一次做这个功能的时候,还是用的 Java Apache POI,这是一个用 Java 编写的免费开源的跨平台的 Java API,能够对 Microsoft ...

  3. Excel 2007 Open XML文件结构(2)

    Excel 2007 Open XML文件结构(2) 在以上文件中,根据<sheet>元素中r:id属性的值可得到工作表数据的XML文件.例如,在workbook.xml文件中名为工作表1 ...

  4. android 读取xlsx文件,android怎么解析表格.xlsx文件

    在網上搜了一下,現在用的是jxl.jar2.6.12解析xlsx文件,但只能解析到51行,后面的獲取不到了,這是什么問題? 用的是網上的這段代碼 http://www.open-open.com/ho ...

  5. OpenXml开发-向Excel2007文档中添加数据

    public static void Run()         {              // 打开Excel2007模板文档             using (PackageHelper ...

  6. java使用poi(XSSFWorkbook)读取excel(.xlsx)文件

    其中最主要的区别在于jxl不支持.xlsx,而poi支持.xlsx 这里介绍的使用poi方式(XSSFWorkbook),实际上poi提供了HSSFWorkbook和XSSFWorkbook两个实现类 ...

  7. Android开发笔记(三十四)Excel文件的读写

    Android中操作Excel文件的场合较少见,主要是一些专业领域导入导出报表时使用,所以处理Excel读写的开源代码也很稀缺.目前读写Excel主要采用开源库jxl,这个是韩国人写的excel操作工 ...

  8. 单sheet页的多个EXCEL文档合并为一个多sheet页的EXCEL文档

    文章目录 前言 一.生成多个excel文档 二.合并excel文档 1. excel文档的实质 2.修改文件拓展名为.zip,并解压 3.处理XML文件 4.压缩文件夹组,并修改.zip为.xlsx ...

  9. 微信小程序生成Excel

    微信小程序生成Excel 一.问题描述 最近一直在查找在微信小程序中生成Excel的办法.需求就是根据一个json数据或者对象数组,生成一个Excel文件,或者打开Excel文件.网上找了很久,没找到 ...

最新文章

  1. python ctime源码_Python3基础 getatime getctime getmtime 文件的最近访问 + 属性修改 + 内容修改时间...
  2. PMP考试的过与只是
  3. MySQL DDL操作--------外键最佳实战
  4. VC++屏幕抓词的技术实现
  5. java继承总结_java继承总结(二)
  6. json文件示例_Spark SQL - JSON数据集
  7. uvalive4836(枚举)
  8. 在MySQL数据库建立多对多的数据表关系
  9. (35) css企业命名规范
  10. python调用另一个.py文件中的类和函数
  11. Android学习之布局管理器嵌套
  12. 《高性能MySQL》之选择优化的数据类型
  13. 极大似然估计法的理解
  14. Qt QPushButton水晶按钮样式例子
  15. python 头条新闻机器人_荐GitHub:今日头条机器人
  16. 无线网技术——知识点
  17. AVFoundation
  18. qt android图片自适应大小,Qt on Android:怎样适应不同的屏幕尺寸
  19. 基于指标选择的多目标搜索(IBEA)
  20. 《天外世界》游戏体验报告

热门文章

  1. docker安装portainer详细步骤
  2. Gateway的限流重试机制
  3. 【多重背包】二进制转换/ 其实有区别的--不全懂,会不放心的
  4. 为什么C语言是最适合单片机编程的高级语言
  5. iOS - 外加字体(只需三步-教你轻松实现)
  6. kali爆破wifi密码测试
  7. Oracle数据迁移 EXP/IMP
  8. [转载]用JBuilder9 开发Struts实例
  9. 魔兽多版本转换器中文绿色版 仅15M大小
  10. linux 安装 php7.3.0