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字节和图片位置以及商品文本信息
}

 

posted @ 2019-05-05 10:23  cjean  阅读(1200)  评论(0编辑  收藏  举报