excel遇到 PartAlreadyExistsException: A part with the name ‘/xl/media/image1120.jpeg‘ already exists

在使用 poi 插入图片的时候,遇到一个报错

org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException: A part with the name '/xl/media/image1120.jpeg' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]

大概意思是 Excel 新生成Part的Name 和 已经存在于Excel的一个 Part的Name 相同,没有办法解决所以报错了。

我的代码是这么写的,目的是往Excel里插入一张图片:

try {
	  Cell cell10 = row.createCell(10);
	  int pictureIndex = workbook.addPicture(model.getPicture(), Workbook.PICTURE_TYPE_JPEG);
	  CreationHelper helper = workbook.getCreationHelper();
	  Drawing drawing = sheet.createDrawingPatriarch();
	  ClientAnchor anchor = helper.createClientAnchor();
	
	  // 图片插入坐标
	  anchor.setCol1(10);
	  anchor.setRow1(row.getRowNum());
	  // 插入图片
	  Picture pict = drawing.createPicture(anchor, pictureIndex);
	  sheet.autoSizeColumn(10);
	  // 指定我想要的长宽
	  pict.resize(4, 1);

} catch(Exception exception) {
	  log.warn("fail to process picture of user {} brandgoodid {}", model.getUserId(), model.getBrandGoodId(), exception);
}

代码出问题的地方在这一行,问题是没检查 model.getPicture() 这个 byte[] 数组为不为 null。加上检查,就没有报错了。

int pictureIndex = workbook.addPicture(model.getPicture(), Workbook.PICTURE_TYPE_JPEG);

如果顺着源码,打断点看的话,问题出在了两个地方
第一个地方在 org.apache.poi.ooxml.POIXMLDocumentPart#createRelationship(org.apache.poi.ooxml.POIXMLRelation, org.apache.poi.ooxml.POIXMLFactory, int, boolean):

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

这边 ppName 和 null byte[] 对应的ppName 重复了。
因为这个ppName生成函数的入参 index 是根据 Excel 里所有图片的数量确定的。

第二处代码就是写入 null byte[] 的位置了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值