1. 程式人生 > >poi 解析 excel

poi 解析 excel

Apache POI 是用 Java 編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程式對 Microsoft Office 格式檔案讀和寫的功能。

本文使用 springboot + mybatis + poi ,來介紹如何解析 excel 、並將 excel 內的資料新增到資料庫

一、編寫程式碼

 1、新增依賴

因為 excel 分 2003 以前版本和 2007 以上版本,所以需要引入兩個 poi 依賴jar包,以對它們分別解析

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.dmeo</groupId>
	<artifactId>springbootpoi</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springbootpoi</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-freemarker</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!--poi對excel2007以上版本的支援-->  
		<dependency>
		        <groupId>org.apache.poi</groupId>
		        <artifactId>poi-ooxml</artifactId>
		        <version>3.17</version>
	        </dependency>
	        <!--poi對excel2003以下版本的支援-->  
               <dependency>
                         <groupId>org.apache.poi</groupId>
                         <artifactId>poi</artifactId>
                         <version>3.17</version>
              </dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2、配置mybatis

由於本文重點是 poi 解析 excel ,這裡就不詳細談如何配置 mybatis,如果讀者不會這部分內容,可以參看博主的另一篇文章,springboot 整合 mybatis

mybatis 配置成功後、yml檔案如下

server:
  port:  9001
  
spring:
  datasource:
    url:  jdbc:mysql://10.42.12.67:3306/orcl?useUnicode=true&characterEncoding=utf-8&useSSL=false
    driver-class-name:  com.mysql.jdbc.Driver  
    username:  root
    password:  123456 
    
mybatis:
  mapper-locations:  classpath:mapper/*Mapper.xml
  config-location:  classpath:mapper/config/sqlMapConfig.xml     

3、資料庫建表

建表sql如下

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `user_id` double DEFAULT NULL,
  `user_name` varchar(64) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `user_addr` varchar(64) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

表格建立後如下

4、建立實體類

package com.demo.bean;

public class User {
	
	private double userId;
	
	private String userName;
	
	private Integer age;
	
	private String userAddr;

	public double getUserId() {
		return userId;
	}

	public void setUserId(double userId) {
		this.userId = userId;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getUserAddr() {
		return userAddr;
	}

	public void setUserAddr(String userAddr) {
		this.userAddr = userAddr;
	}

	@Override
	public String toString() {
		return "User [userId=" + userId + ", userName=" + userName + ", age=" + age + ", userAddr=" + userAddr + "]";
	}
}

5、建立mapper介面層

package com.demo.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.demo.bean.User;

@Mapper
public interface UserMapper {
	
	//批量將資料新增到資料庫
	int insertForeach(List<User> list);

}

6、建立 mapper.xml 檔案

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.demo.mapper.UserMapper">

	<insert id="insertForeach" parameterType="java.util.List" useGeneratedKeys="false">
    	insert into user ( user_id, user_name, age, user_addr) values
    	<foreach collection="list" item="item" index="index" separator=",">
    	 	(#{item.userId}, #{item.userName}, #{item.age}, #{item.userAddr})
        </foreach>		
    </insert>    
</mapper>

7、編寫上傳 excel 頁面

此處使用 freemarker 模板引擎

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>excel上傳解析</title>
</head>
<body>
		<form action="/importExcel" method="post" enctype="multipart/form-data">
			<input type="file" name="file" />
			<input type="submit" value="EXCEL上傳" />
		</form>
</body>
</html>

8、建立 excel 值處理類

package com.demo.util;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;

public class ExcelUtils {
	
	/**
	 * excel值處理
	 * @param hssfCell
	 * @return
	 */
	public static Object getXSSFValue(XSSFCell hssfCell) {
	    if(hssfCell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {
	    	return hssfCell.getNumericCellValue();    //數字
	    }else if(hssfCell.getCellType() == XSSFCell.CELL_TYPE_BOOLEAN) {
	    	return hssfCell.getBooleanCellValue();    //boolean
	    }else if(hssfCell.getCellType() == XSSFCell.CELL_TYPE_ERROR){
	    	return hssfCell.getErrorCellValue();      //故障
	    }else if(hssfCell.getCellType() == XSSFCell.CELL_TYPE_FORMULA){
	    	return hssfCell.getCellFormula();         //公式
	    }else if(hssfCell.getCellType() == XSSFCell.CELL_TYPE_BLANK) {
	    	return "";                                //空值
	    }else {
	    	return hssfCell.getStringCellValue();     //字串
	    }
		
	}
	
	/**
	 * excel值處理
	 * @param hssfCell
	 * @return
	 */
	public static Object getValue(Cell hssfCell) {
	    if(hssfCell.getCellType()==XSSFCell.CELL_TYPE_NUMERIC) {
	    	return hssfCell.getNumericCellValue();   //數字 
	    }else if(hssfCell.getCellType()==XSSFCell.CELL_TYPE_BOOLEAN) {
	    	return hssfCell.getBooleanCellValue();   //boolean
	    }else if(hssfCell.getCellType()==XSSFCell.CELL_TYPE_ERROR){
	    	return hssfCell.getErrorCellValue();     //故障
	    }else if(hssfCell.getCellType()==XSSFCell.CELL_TYPE_FORMULA){
	    	return hssfCell.getCellFormula();        //公式
	    }else if(hssfCell.getCellType() == XSSFCell.CELL_TYPE_BLANK) {
	    	return ""; 	                             //空值
	    }else {
	    	return hssfCell.getStringCellValue();    //字串
	    }
	}

}

9、建立controller 及解析 excel 主要程式碼

具體註釋已經寫到程式碼中、相信讀者能夠看懂

package com.demo.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.demo.bean.User;
import com.demo.mapper.UserMapper;
import com.demo.util.ExcelUtils;

@Controller
public class ExcelController {
	
	private static Logger logger = LoggerFactory.getLogger(ExcelController.class);
	
	@Autowired
	private UserMapper userMapper;
	
	@RequestMapping("/")
	public ModelAndView index() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("index");
		return mav;
	}
	
	@RequestMapping("/importExcel")
	public ModelAndView importExcel(MultipartFile file) throws IOException {
		
		String fileName = file.getOriginalFilename();  //獲得上傳的excel檔名
		String fileSuffix = fileName.substring(fileName.lastIndexOf(".")+1);  //獲取上傳的excel檔名字尾
		
		List<User> list = null;
		
		if("xlsx".equals(fileSuffix)) {
			logger.info("excel2007及以上版本");
			
			XSSFWorkbook xwb = new XSSFWorkbook(file.getInputStream()); //獲取excel工作簿
			
			XSSFSheet xssfSheet = xwb.getSheetAt(0); //獲取excel的sheet
			
			if(xssfSheet == null) {
				return null;
			}
			
			list = new ArrayList<User>();
			
			//迴圈獲取excel每一行  
			for(int rowNum = 1; rowNum < xssfSheet.getLastRowNum()+1; rowNum++) {
				XSSFRow xssfRow = xssfSheet.getRow(rowNum);
				if(xssfRow == null) {
					continue;
				}
				
				User user = new User();
				
				//迴圈獲取excel每一行的每一列  
				for(int cellNum = 0; cellNum < xssfRow.getLastCellNum(); cellNum++) {
					XSSFCell xssCell = xssfRow.getCell(cellNum);
					if(xssCell == null) {
						continue;
					}
					
			        if(cellNum == 0) {
						  user.setUserId((Double)ExcelUtils.getXSSFValue(xssCell));
		    		  }else if(cellNum == 1) {
		    			  user.setUserName((String)ExcelUtils.getXSSFValue(xssCell));
		    		  }else if(cellNum == 2) {
		    			  //Integer型別需要自行處理
		    			  String res = String.valueOf((Double)ExcelUtils.getXSSFValue(xssCell));
						  Integer.parseInt(res.substring(0, res.length()-2));
						  user.setAge(Integer.parseInt(res.substring(0, res.length()-2))); 	 
		    		  }else if(cellNum == 3) {
		    			  user.setUserAddr((String)ExcelUtils.getXSSFValue(xssCell));
		    		  }
					
					 System.out.print(" "+ExcelUtils.getXSSFValue(xssCell));
					
				}
				list.add(user);  //將excel每一行的資料封裝到user物件,並將user物件新增到list 
				System.out.println("");
			}
	}else if("xls".equals(fileSuffix)) {
		   logger.info("excel2003版本");
		  
	           Workbook wb=new HSSFWorkbook(file.getInputStream()); //獲取excel工作簿
	       
	           Sheet sheet=wb.getSheetAt(0);  //獲取excel的sheet
			   
			   if(sheet==null) {
					return null;
				}
			   
			   list = new ArrayList<User>();
			   
			//迴圈獲取excel每一行   
			for(int rowNum=1;rowNum<sheet.getLastRowNum()+1;rowNum++) {
					Row row=sheet.getRow(rowNum);
					if(row==null) {
						continue;
					  }
					
				User user = new User();	
				
				//迴圈獲取excel每一行的每一列  
				for(int cellNum=0;cellNum<row.getLastCellNum();cellNum++) {
						Cell cell=row.getCell(cellNum);
						if(cell==null) {
							continue;
						}
					
					if(cellNum==0) {
							 user.setUserId((Double)ExcelUtils.getValue(cell));
			    		  }else if(cellNum==1) {
			    			  user.setUserName((String)ExcelUtils.getValue(cell));
			    		  }else if(cellNum==2) {
			    			  //Integer型別需要自行處理
			    			  String res = String.valueOf((Double)ExcelUtils.getValue(cell));
							  Integer.parseInt(res.substring(0, res.length()-2));
							  user.setAge(Integer.parseInt(res.substring(0, res.length()-2))); 	
			    		  }else if(cellNum==3) {
			    			  user.setUserAddr((String)ExcelUtils.getValue(cell));
			    		  }
						
						 System.out.print(" "+ExcelUtils.getValue(cell));
			   }
				 list.add(user);    //將excel每一行的資料封裝到user物件,並將user物件新增到list 
				 System.out.println("");
		}
		
	}
		//將list批量新增到資料庫
		int count = userMapper.insertForeach(list);
		System.out.println(count);
		return null;
		
	}

}

10、總結

經過以上9個步驟、專案結構如下

二、測試

excel xlsxxls 檔案分別如下

先上傳 紅樓夢人物.xls  檔案 ,效果如下

再上傳 西遊記.xlsx  檔案 ,效果如下