在最近的项目开发中,遇到这样一个需求,用户导入带图片的excel,excel批量导入功能已做过很多了,带图片的是第一次尝试,大概的要求有以下几点:

所有excel中的图片不能超出单元格,即必须在单元格内
所有图片单个大小必须在1M以内
其中一列的单元格放入的图片不能多于5张
其中一列的单元格为无限数量的图片与不多于2000的字符

核心思路:获取所有的图片放入Map

  /*** 获取Excel2003图片** @param sheet 当前sheet对象* @param workbook 工作簿对象* @return Map key:图片左上角-右下角单元格索引+uuid(leftRow,leftCol_rightRow,rightCol_uuid)String,value:图片流PictureData*/private Map<String, PictureData> getSheetPictrues03(HSSFSheet sheet, HSSFWorkbook workbook) {Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();// 获取excel上所有的图片List<HSSFPictureData> pictures = workbook.getAllPictures();if (pictures.size() != 0) {HSSFPatriarch hp = sheet.getDrawingPatriarch();List<HSSFShape> shapeList = hp.getChildren();for (HSSFShape shape : shapeList) {HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();if (shape instanceof HSSFPicture) {HSSFPicture pic = (HSSFPicture) shape;int pictureIndex = pic.getPictureIndex() - 1;HSSFPictureData picData = pictures.get(pictureIndex);String picIndex = String.valueOf(anchor.getRow1()) + "," + String.valueOf(anchor.getCol1()) + "_"+ anchor.getRow2() + "," + String.valueOf(anchor.getCol2()) + "_"+ UUID.randomUUID();// Map key:图片左上角-右下角单元格索引+uuid(1,2_3,4_uuid),左上右下定位一张图片// leftRow,leftCol_rightRow,rightCol_uuid ,放入返回的Map时,拼接uuid标示唯一的图片sheetIndexPicMap.put(picIndex, picData);}}}return sheetIndexPicMap;}

验证关键代码

// 声明的存放同一单元的图片,方便后面判断同一单元格图片是否超过5张Map<String, String> numTempMap = new HashMap<String, String>();Object key[] = sheetIndexPicMap.keySet().toArray();for (int i = 0; i < sheetIndexPicMap.size(); i++) {String keyTemp = key[i].toString();// 图片左上角所在的行列String leftTop = keyTemp.substring(0, keyTemp.indexOf("_"));// 图片右下角所在的行列String rightBottom = keyTemp.substring(keyTemp.indexOf("_") + 1, keyTemp.lastIndexOf("_"));int leftRow = Integer.parseInt(leftTop.substring(0, leftTop.indexOf(",")));int leftCol = Integer.parseInt(leftTop.substring(leftTop.indexOf(",") + 1));int rightRow = Integer.parseInt(rightBottom.substring(0, rightBottom.indexOf(",")));int rightCol = Integer.parseInt(rightBottom.substring(rightBottom.indexOf(",") + 1));int currentCol = leftCol;int currentRow = leftRow;// 左上角行与右下角行不相同 或 左上角列与右下角列不相同,即为图片超出单元格if (leftRow != rightRow || leftCol != rightCol) {throw bizExceptions.create(CatalogError.ERROR_10001610, "图片超出单元格!");}// 为使逻辑更清晰,分开两种写超出单元格的判断,图片不在4、5列的也为超出单元格// 这里我的实际需求是,只有第4、5列才能上传图片if (!(leftCol == 4 || leftCol == 5)) {throw bizExceptions.create(CatalogError.ERROR_10001610, "图片超出单元格!");}PictureData pic = sheetIndexPicMap.get(key[i]);byte[] data = pic.getData();if (data.length / 1024.0 / 1024.0 > 3) {throw bizExceptions.create(CatalogError.ERROR_10001608, "推荐描述图片大小超过3M!");}// 这里循环所有的图片,同一单元的图片放入同一key的Map中,后续根据判断单元格的数量if (!numTempMap.containsKey(currentRow + "")) {for (int k = 0; k < sheetIndexPicMap.size(); k++) {String keyTempk = key[k].toString();String leftTopk = keyTempk.substring(0, keyTempk.indexOf("_"));int currentRowk = Integer.parseInt(leftTopk.substring(0, leftTopk.indexOf(",")));int currentColk = Integer.parseInt(leftTopk.substring(leftTopk.indexOf(",") + 1));if (currentRow == currentRowk && currentColk == startCellNum) {String productImgNumStr = numTempMap.get(currentRow + "");int productImgNum = 0;if (null != productImgNumStr) {productImgNum = Integer.parseInt(productImgNumStr) + 1;}numTempMap.put(currentRow + "", productImgNum + "");}}}}}Object keyNum[] = numTempMap.keySet().toArray();for (int i = 0; i < numTempMap.size(); i++) {String productImgs = numTempMap.get(keyNum[i]);if (null != productImgs && Integer.parseInt(productImgs) >= 5) {throw bizExceptions.create(CatalogError.ERROR_10001609, "产品图片数量超过5张!");}}

这种方式,个人觉得还是有点太消耗性能,本来就是批量导入,一次性将所有图片放入Map中,然后循环key,实际处理中应该是很慢的,笔者供职外包,无法查看线上实际情况。

POI java 处理excel上传图片相关推荐

  1. dwr框架java解析excel_dwr poi java 将excel 导出到客户端

    1.前端js代码: ExcelService.createExcel({ callback:function(rtnData){ dwr.engine.openInDownload(rtnData); ...

  2. POI java导出Excel设置自适应行高

    本文章参考于:https://www.cnblogs.com/dtts/p/4741575.html 需求:根据单元格的内容自动设置行高 代码: /*** 设置自适应行高的方法*/public int ...

  3. java excel api 下载文件_Java-Excel Java操作Excel POI(Jakarta POI API) - 下载 - 搜珍网

    Java操作Excel/Jakarta POI API/data/Jakarta POI API.doc Java操作Excel/Jakarta POI API/jar/poi-3.0.2-FINAL ...

  4. 利用Java反射机制和poi插件操作excel

    最近在公司写一个利用poi插件读取excel的东西,,不想每一个都写一遍解析代码.就想利用Java的反射机制,写对应的实体类,获取对应excel中的值,下面是解析的代码,仅供参考.不足之处,望指出/* ...

  5. java Export Excel POI 转

    最终选择用POI成功导出excel.总之很有用. http://www.cnblogs.com/xwdreamer/archive/2011/07/20/2296975.html http://poi ...

  6. java excel读取操作,Java 操作 Excel (读取Excel2003 2007,Poi兑现)

    Java 操作 Excel (读取Excel2003 2007,Poi实现) 一. Apache POI 简介( http://poi.apache.org/) 使用Java程序读写Microsoft ...

  7. Java POI Excel( pio:纯java操作excel的api )

    2010-03-17 21:35 POI官方网址:http://poi.apache.org/ POI的功能实在很强大,而且是apache的子项目,它下面又包含一些Component,比如处理Exce ...

  8. java导出excel设置行高列宽_使用POI生成Excel文件,可以自动调整excel列宽

    //autoSizeColumn()方法自动调整excel列宽 importjava.io.FileOutputStream; importorg.apache.poi.hssf.usermodel. ...

  9. Java实现excel的读与写(Apache POI)

    本文将讨论利用Apache POI提供的类实现Excel文件的读与写操作. 整个项目的目录结构基于前面的一篇文章:<java读取pdf内容> 1.pom.xml <dependenc ...

最新文章

  1. 虚拟化部署之Hyper-V简介
  2. 关于tcp、http可能你想知道的那些事
  3. Highchart插件下载与安装
  4. startprocessinstancebykey()里面填写的参数_3种方法,快速学会在Word文档里面如何插入表格...
  5. python在财务上的应用-财会人必看:这个工具,30分钟可以把人家一天的工作都给干完!...
  6. ST_Curve --- 一个专业的曲线绘制控件
  7. NFS服务器的安装与配置
  8. 通过JS和CSS,实现网页加载中的动画效果
  9. OpenCV彩色目标跟踪
  10. 零基础在Linux环境安装Cadence系列软件
  11. windows ping 端口
  12. 这7位年轻人正在通过科技让世界颤抖,预见中囯未来!
  13. 计算机课ppt插入图片,ppt2010官方基础教程:插入照片-powerpoint技巧-电脑技巧收藏家...
  14. LOL盗号PHP源码,说说技术那些事之LOL盗号网站
  15. 前端传入数字,后端用枚举接收统一处理
  16. 解读《Superhuman AI for multiplayer poker》
  17. 大连大学计算机科学与技术研究生毕业工资,大学研究生毕业的你,现在一个月的月薪多少?现实让人想哭!...
  18. 榕树说技术支持(Rong Zhiyun technical support)
  19. 手机通讯录 Python
  20. mysql取rownum_MySQL中的ROWNUM的实现

热门文章

  1. kux格式怎么转换mp4,这里有妙招
  2. dell服务器报错信息,DELL 服务器LED屏报错信息 2012版
  3. 金融科技B端市场群雄争霸 PATH四家各出奇招
  4. Linux命令行窗口无法输入密码
  5. 什么是Teardrop攻击?我们要如何防御Teardrop攻击?
  6. 我们看到的太阳是8分钟前的太阳
  7. 竟可打通了Python和Excel,还能自动生成代码,这个插件绝了
  8. 高等组合学笔记(三): 间隔排列,投票问题,圈集排列组合与生成函数简介
  9. 笔杆网试用---感官体验篇一
  10. python裁剪图片边缘模糊_用cv2模糊部分图像后的锐利边缘