使用POI将excel里的图片进行保存并将图片路径设置到单元格中

需求背景:用excel导入批量数据的时候,需要将头像图片同时导入上传,因为代码用的工具类就是poi,而且用的Workbook接收不分后缀,网上找了半天没有发现使用统一的一个类来处理excel的图片,所以具体实现还是要分HSSF和XSSF。

PS:如果有更好的方法欢迎指正

//为了提高代码效率,先做是否有图片的判断
//判断是否有图片
List<? extends PictureData> allPictures = workbook.getAllPictures();
if(allPictures.size() != 0){
	ExcelPicture.dealPicture(workbook);
}
/**
 * 读取excel里的图片
 */
public class ExcelPicture {

	/**
	 * 将excel里的图片转为上传路径
	 * @return
	 */
	public static void dealPicture(Workbook workbook) throws IOException {
		//判断类型
		if(workbook instanceof HSSFWorkbook){
			HSSFWorkbook hssfWorkbook = (HSSFWorkbook)workbook;
			//循环获取shape 判断是否有图片
			HSSFSheet sheet = hssfWorkbook.getSheetAt(0);
			Iterator<HSSFShape> iterator = sheet.createDrawingPatriarch().getChildren().iterator();
			while (iterator.hasNext()){
				HSSFShape shape = (HSSFShape)iterator.next();
				//如果为图片
				if(shape instanceof HSSFPicture){
					HSSFPicture picture = (HSSFPicture) shape;
					HSSFClientAnchor clientAnchor = picture.getClientAnchor();
					PictureData pictureData = picture.getPictureData();

					//获取图片格式
					String ext = pictureData.suggestFileExtension();
					//上传图片
					String picUrl = uploadPicture(pictureData.getData(),ext);

					//将图片单元格替换为上传路径
					workbook.getSheetAt(0).getRow(clientAnchor.getRow1()).createCell(clientAnchor.getCol1()).setCellValue(picUrl);
				}
			}
		}else{
			XSSFWorkbook xssfWorkbook = (XSSFWorkbook)workbook;
			XSSFSheet sheet = xssfWorkbook.getSheetAt(0);
			List<XSSFShape> shapes = sheet.createDrawingPatriarch().getShapes();
			for (XSSFShape shape : shapes) {
				if(shape instanceof XSSFPicture){
					XSSFPicture picture = (XSSFPicture)shape;
					XSSFClientAnchor clientAnchor = picture.getClientAnchor();
					XSSFPictureData pictureData = picture.getPictureData();

					//获取图片格式
					String ext = pictureData.suggestFileExtension();
					//上传图片
					String picUrl = uploadPicture(pictureData.getData(),ext);

					//将图片单元格替换为上传路径
					workbook.getSheetAt(0).getRow(clientAnchor.getRow1()).createCell(clientAnchor.getCol1()).setCellValue(picUrl);
				}
			}

		}
	}

	/**
	 * 将图片上传,返回图片存储路径
	 * @param pictureData
	 * @param ext
	 * @return
	 * @throws IOException
	 */
	public static String uploadPicture(byte[] pictureData,String ext)  throws IOException{
		String saveFileName = UUID.randomUUID().toString() + "." + ext;
		String saveFilePath = BusinessUtil.getUploadFileDir() + "/" + saveFileName;

		InputStream inputStream = new ByteArrayInputStream(pictureData);
		File file = new File(saveFilePath);
		OutputStream outputStream = new FileOutputStream(file);
		IOUtils.copy(inputStream, outputStream);
		inputStream.close();
		outputStream.close();

		return "/" + Const.UPLOAD_DIR.replaceFirst("^/", "") + "/" + saveFileName;
	}
}

几个点:

1)Workbook可以进行类型判断是因为翻了源码,在用工厂类创建的时候本身就进行了类型判断

 2)一开始想的是获取图片所在的cell的坐标,通过get获取然后直接set,结果报的空指针异常,debug了一下,图片所在的坐标没有值的话workbook里是没有的,所以需要创建一个

不过这里的row应该也不能直接get,应该加个判断才对,当时业务关系这里不可能为空,所以就先这样吧 ┑( ̄Д  ̄)┍

//空指针异常
workbook.getSheetAt(0).getRow(clientAnchor.getRow1()).getCell(clientAnchor.getCol1()).setCellValue(picUrl);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值