解析excel表到数据库

最近项目有一个需求,需要批量上传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)//获取工作表 范围是 0~(sheetSize-1)
String sheetName = sheet.getSheetName();

获取第1行

1
2
int rowSize = sheet.getPhysicalNumberOfRows();//获取有记录的行数
Row firstRow = sheet.getRow(i);//获取每列 范围是 0~(rowSize-1)

获取列的大小

1
int columnSize = firstRow.getPhysicalNumberOfCells();//获取有记录的列数

到现在为止,已经可以精确定位到哪一行的那一列上了,就可以唯一确定一个单元格,即一个cell

1
2
3
Cell cell = firstRow.getCell(i);//获取第i行的每个cell
String value = cell.getStringCellValue()//获取cell的值,还有其他形式的
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
//getPictures1
List<HSSFShape> list = sheet.getDrawingPatriarch().getChildren();
for (HSSFShape shape : list) {
if (shape instanceof HSSFPicture) {
HSSFPicture picture = (HSSFPicture) shape;
PictureData pdata = picture.getPictureData();//获取图片数据
//获取图片在sheet中的位置信息
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
//getPictures2
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();//获取此形状的图片数据
//获取图片在sheet中的位置信息
XSSFClientAnchor anchor = picture.getPreferredSize();//计算这张图片的首选尺寸。
CTMarker marker = anchor.getFrom();//返回起始锚点
String key = String.valueOf(marker.getRow());
}
}
}

参考POI API文档以及网上相关资料


解析excel表到数据库
https://vickkkyz.fun/2022/03/24/Problems/excel/
作者
Vickkkyz
发布于
2022年3月24日
许可协议