POI读取带有图片(图片有的是合并单元格的)的商品列表Excel
首先明确的是:(案例是在2003基础上的,2007版的相同)
暂时还是不清楚poi读取Excel的顺序问题!!!!
但是,POI在读取Excel文件中的文字是的顺序,首先是sheet名称,其次是按照列进行读取文字、文本(无论文本是不是合并过单元格)
###如果遇到图片是不能按照其默认的CELL_TYPE_FORMULA(公式型-2)、CELL_TYPE_STRING(字符串型-1)、CELL_TYPE_NUMERIC(数值型-0)、CELL_TYPE_BOOLEAN(布尔型-4)、CELL_TYPE_BLANK(空值-3)这5种类型去读取;对图片需进行单独的读取(读取还需分清图片是否合并单元格,合并单元格的位置等问题);
1.对纯文字的商品列表或者如下图的商品列表的Excel文件
2.带有合并单元格的Excel
这两种格式的Excel都可以使用下面的方法共有;由于不清楚合并单元格的位置在哪,所以采取位置范围的方式进行图片覆盖(细节留言)
//获取单元格的值 默认是文本 public String getCellValue(Cell cell){ if(cell == null){ return ""; } return cell.getStringCellValue(); } /** * 获取 合并单元格 范围(这很重要) 当知道合并单元格的范围后,就可以知道这个图片在哪,那些列文字是和他一样的图片,在插入数据库时,由于在这个范围内的图片只有1个, 所以可以使用这个范围进行数据库表更改,将这个范围的空的图片全部update一下就可以了,实现每列文字都有图片的形式 * @return */ public List<CellRangeAddress> gethbdygfw(org.apache.poi.ss.usermodel.Sheet sheet){ List<CellRangeAddress> list = new ArrayList<>(); // 获取 sheet中合并单元格的数量 int sheetmergerCount = sheet.getNumMergedRegions(); // 便利所有 的单元格 for(int i=0;i<sheetmergerCount;i++){ // 获取合并单元格 保存 到list中 CellRangeAddress ca = sheet.getMergedRegion(i); list.add(ca); } return list; } // 获取 合并单元格的 起始 和 中终止 的 行 和列 public Map<String,List> getColRowFK(List<CellRangeAddress> cellRangeAddresslist){ Map<String, List> posiMap = new HashMap<>(); int firCol = 0; int lasCol = 0; int firRow = 0; int lasRow = 0; //循环所有的 合并单元格 for(int i=0;i<cellRangeAddresslist.size();i++){ //分别获取 单元格 的地址 CellRangeAddress ca = cellRangeAddresslist.get(i); firCol = ca.getFirstColumn(); lasCol = ca.getLastColumn(); firRow = ca.getFirstRow(); lasRow = ca.getLastRow(); //将每个单元格地址封禁 儒 list中待取出使用 List<String> posiList = new ArrayList<>(); posiList.add(firCol+""); posiList.add(lasCol+""); posiList.add(firRow+""); posiList.add(lasRow+""); // 将 读取到的 每个合并单元格 编号 并 将每个编号的 单元格进行位置赋值 posiMap.put("merg"+i, posiList); } return posiMap; } /** * * 读取商品价格参数导入功能 excel 的方法 * 输入参数 文件,sheet页序号,0开始;必填的列个数 * 读取 office 2003 excel * @throws IOException * @throws FileNotFoundException */ public Map<String, Object> read2003FKExcel(File file,int sheetn,int startrow) throws IOException{ Map<String, Object> dataMap = new HashMap<>(); HSSFWorkbook hwb = new HSSFWorkbook(new FileInputStream(file)); BASE64Encoder encoder = new BASE64Encoder(); BASE64Decoder decoder = new BASE64Decoder(); Object value = null; HSSFRow row = null; HSSFCell cell = null; List<List<String>> list = new LinkedList<List<String>>(); String encodedPdataText = null;//base64转码后的图片文本内容 String picPosition = null;//Excel中图片的位置 1-2 一行2列 8-4 8行4列 HSSFSheet sheet = hwb.getSheetAt(sheetn); // 获取合并单元格 的位置 范围 将范围集合传回处理逻辑进行待使用(比如数据库操作) List<CellRangeAddress> fwList = gethbdygfw(sheet); Map<String,List> posiMap = getColRowFK(fwList); // System.out.println("**************++++++++++++++++"); // System.out.println(posiMap); // System.out.println("**************++++++++++++++++"); dataMap.put("posiMap", posiMap); //获取图片的位置以及图片资源 用来定位图片 Map<String, String> hssfPictureDataMap = new HashMap<String, String>(); List<HSSFShape> hssfShapList = sheet.getDrawingPatriarch().getChildren(); for(HSSFShape shap:hssfShapList){ if(shap instanceof HSSFPicture){ HSSFPicture picture = (HSSFPicture) shap; HSSFClientAnchor cAnchor = picture.getClientAnchor(); HSSFPictureData pdataAdress = picture.getPictureData(); byte[] pdata = pdataAdress.getData(); encodedPdataText = encoder.encode(pdata); // System.out.println("encodedPdataText/////----"+encodedPdataText); String pictureKey = cAnchor.getRow1()+"-"+cAnchor.getCol1(); // System.out.println("pictureKey----"+pictureKey); hssfPictureDataMap.put(pictureKey, encodedPdataText); } } // System.out.println(hssfPictureDataMap.size()); for(int i = startrow;i<= sheet.getLastRowNum();i++){ row = sheet.getRow(i); if (row == null) { continue; } List<String> linked = new LinkedList<String>(); for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { cell = row.getCell(j); if (cell == null) { linked.add(""); continue; } cell.setCellType(1); value = cell.toString(); picPosition = i+"-"+j; if(hssfPictureDataMap.containsKey(picPosition)){//当图片的位置和读的行列号一致时将图片进行base64处理并插入进商品信息集合 String pic64Str = hssfPictureDataMap.get(picPosition); value = pic64Str; hssfPictureDataMap.remove(picPosition); } linked.add(value.toString()); } list.add(linked); } //System.out.println(list.toString()); dataMap.put("list", list); return dataMap;// 此集合中是图片的base字节和图片位置以及商品文本信息 }