需求背景:用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);