要实现动态效果,就不能依赖实体类,否则一个新的Excel表导入时还要添加实体类,应直接对数据库进行操作,所以不推荐使用SpringBoot JPA ,推荐使用原生的JDBC或JDBC Template,返回的是Map,List的集合 ,除此之外,还可以用字符串拼接的方式控制SQL语句,而不是返回所有字段数据
1.在pom.xml中添加依赖,主要利用POI
org.apache.poi
poi
3.11
org.apache.poi
poi-ooxml
3.9
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.4
2.数据访问层
@Repository
public class ExcelImportRepository {
@Autowired
private JdbcTemplate jdbctemplate;
/**
* @param tableName 要插入的表
* @param keys 指定插入的字段值
* @param values 指定插入的数据值
*/
//添加数据
public void addInfo(String tableName,String keys,String values) {
StringBuilder sql = new StringBuilder();
sql.append("insert into ").append(tableName).append("(").append(keys).append(")").append(" values (").append(values).append(")");
jdbctemplate.update(sql.toString());
}
}
3.Service层
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
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.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.cgs.cqwf.store.fileDownload.SystemConfig;
@Service
@Transactional
public class ExcelImportService {
//注入数据访问层
@Autowired
private ExcelImportRepository excelimportrepository;
//获取配置文件中对应属性值
private String getProperties;
toStringUtil tsu = new toStringUtil();
/**
*
* @param tableName 指定Excel文件导入到哪个表
* @param file Excel文件
* @param start 指定Excel文件导入数据的起始值,全部导入则为1
* @return
* @throws Exception
*/
@Transactional(rollbackFor=Exception.class)
public boolean ExcelImport(String tableName, MultipartFile file, int start) throws Exception {
boolean notNull=false; //判断Excel文件是否有内容
String filename=file.getOriginalFilename();
if (!filename.matches("^.+\\.(?i)(xls)$") && !filename.matches("^.+\\.(?i)(xlsx)$")) {
throw new Exception("上传文件格式不正确");
}
//判断Excel文件的版本
boolean isExcel2003=true;
if (filename.matches("^.+\\.(?i)(xlsx)$")) {
isExcel2003 = false;
}
InputStream is=file.getInputStream();
Workbook wb=null;
if (isExcel2003) {
wb = new HSSFWorkbook(is);
} else {
wb = new XSSFWorkbook(is);
}
//获取要导入的表的字段值,因为我的属性文件里表名前都加了cqwf2
getProperties=SystemConfig.getProperty("cqwf2."+tableName);
String[] info=getProperties.split(",");
//获取Excel文件的第一页sheet,判断是否有信息
Sheet sheet=wb.getSheetAt(0);
if(sheet!=null){
notNull=true;
}
//创建两个List集合,一个保存属性文件中的字段值,一个保存Excel文件中每一行的单元格的值
List keysList=new ArrayList();
List valuesList=new ArrayList();
//获取英文字段值
for(int i=0;i
SystemConfig:是我在别的包下面写的工具类,用来读取属性文件,根距属性名获取对应的属性信息
属性文件里的格式:cqwf2.表名=id(数据库中表的字段名):主键(Excel文件中的表头名),name:姓名
导入的时候注意的问题:空单元格导入时,单元格类型为空和内容为空是不一样的,这里提供了三个静态常量
Row.MissingCellPolicy RETURN_NULL_AND_BLANK
/** Missing cells are returned as null, Blank cells are returned as normal */
public static final MissingCellPolicy RETURN_NULL_AND_BLANK = new MissingCellPolicy();
缺失的单元格作为null返回,空白单元格作为正常返回
Row.MissingCellPolicy RETURN_BLANK_AS_NULL
/** Missing cells are returned as null, as are blank cells */
public static final MissingCellPolicy RETURN_BLANK_AS_NULL = new MissingCellPolicy();
缺失的单元格将作为null返回,空白单元格也是如此
Row.MissingCellPolicy CREATE_NULL_AS_BLANK
/** A new, blank cell is created for missing cells. Blank cells are returned as normal */
public static final MissingCellPolicy CREATE_NULL_AS_BLANK = new MissingCellPolicy();
为丢失的单元格创建一个新的空白单元格。空白单元恢复正常。
判断内容为空时,直接调用StringUtils.isBlank(Str) 方法即可,无论有几个空字符串
getPhysicalNumberOfCells和getLastCellNum的区别:
getPhysicalNumberOfCells 是获取不为空的列个数。
getLastCellNum 是获取最后一个不为空的列是第几个。
因此,若是excel数据中存在空行或空列,必须用getLastRow的办法才干完全读取数据。
4. Controller层
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequestMapping("excelImport")
public class ExcelImportController {
@Autowired
private ExcelImportService excelImportService;
/**
* @param tableName Excel文件要导入的表名
* @param file Excel文件
* @param start Excel文件导入内容的起始点。全导入则为1
* @return
*/
@PostMapping("import")
public boolean addStore_Test(String tableName, @RequestParam("file") MultipartFile file,int start){
boolean a=false;
try {
a=excelImportService.ExcelImport(tableName,file,start);
} catch (Exception e) {
e.printStackTrace();
}
return a;
}
}
5. 工具类
public class toStringUtil {
/*
* 把List集合转化成指定格式的String类型
*/
public String ListToString(List list){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i));
sb.append(",");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
/*
* 判断字符串是否为数字
*/
public static boolean isNumber(String str){
for (int i = 0; i < str.length(); i++) {
if(!Character.isDigit(str.charAt(i))){
return false;
}
}
return true;
}
}