最近项目有一个需求,需要批量上传excel表中的数据到数据库中,excel表的标题和数据库中相应表的字段不同,需要获取到excel中的数据后对应着数据库中的字段添加。excel表中还可能包含图片,所以也需要将图片解析。
首先需要导入解析excel需要的jar包,如果使用maven,则导入相关依赖
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency>
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.17</version> </dependency>
|
然后先读取整个excel表,得到一个Workbook对象wb
1 2 3 4 5 6 7 8
| Workbook wb =null; String filename = excel.getOriginalFilename(); InputStream is is = excel.getInputStream(); if (filename.endsWith(".xls")) { wb = new HSSFWorkbook(is); } else if (filename.endsWith(".xlsx")) { wb = new XSSFWorkbook(is); }
|
这里有两种格式的excel表,一个是以.xls结尾,另一个是以.xlsx结尾
1、xls是复合文档类型的结构,xlsx是基于XML的压缩方式;2、xls是2003及以前版本的文件格式,xlsx是2007及以后版本的文件格式
HSSFWorkbook、XSSFWorkbook都实现了WorkBook接口
如果wb对象不空,就可以获取里面的sheet(工作表)
1 2 3
| int sheetSize = wb.getNumberOfSheets(); Sheet sheet = wb.getSheetAt(i) String sheetName = sheet.getSheetName();
|
获取第1行
1 2
| int rowSize = sheet.getPhysicalNumberOfRows(); Row firstRow = sheet.getRow(i);
|
获取列的大小
1
| int columnSize = firstRow.getPhysicalNumberOfCells();
|
到现在为止,已经可以精确定位到哪一行的那一列上了,就可以唯一确定一个单元格,即一个cell
1 2 3
| Cell cell = firstRow.getCell(i); String value = cell.getStringCellValue() int cellType= cell.getCellType();
|
上面部分只能获取非图片数据,那么图片数据应该如何获取呢?
获取工作表每行的图片数据
1 2 3 4 5 6
| Map<String, PictureData> pictureMap; if(excel.getOriginalFilename().endsWith(".xls")){ pictureMap = getPictures1((HSSFSheet) sheet); }else{ pictureMap = getPictures2((XSSFSheet) sheet); }
|
1 2 3 4 5 6 7 8 9 10 11
| List<HSSFShape> list = sheet.getDrawingPatriarch().getChildren(); for (HSSFShape shape : list) { if (shape instanceof HSSFPicture) { HSSFPicture picture = (HSSFPicture) shape; PictureData pdata = picture.getPictureData(); HSSFClientAnchor cAnchor = (HSSFClientAnchor) picture.getAnchor(); String key = String.valueOf(cAnchor.getRow1()); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| List<POIXMLDocumentPart> list = sheet.getRelations(); for (POIXMLDocumentPart part : list) { if (part instanceof XSSFDrawing) { XSSFDrawing drawing = (XSSFDrawing) part; List<XSSFShape> shapes = drawing.getShapes(); for (XSSFShape shape : shapes) { XSSFPicture picture = (XSSFPicture) shape; PictureData pdata = picture.getPictureData(); XSSFClientAnchor anchor = picture.getPreferredSize(); CTMarker marker = anchor.getFrom(); String key = String.valueOf(marker.getRow()); } } }
|
参考POI API文档以及网上相关资料