一、思路是这样的:
1.先做好一个Excel模板供用户下载,例如下图
2.用户使用模板填好数据,上传Excel文件到web后台,后台接收文件。
3.把用户上传的文件进行校验文件格式、字段是否符合要求,符合要求则解析数据,保存到数据库中,不符合要求则提示;
二、代码实现
1.要导入的数据JAVA对象如下:
public class Rfid extends BaseEntity{
//名称
private String name;
//藏品类别
private String rfidTypeId;
//藏品类别名称
private String rfidTypeName;
//藏品分类
private String typeName;
//藏品年代
private String age;
//设计师
private String stylist;
//品牌
private String brand;
//国家地区
private String contriesRegions;
//材质
private String texture;
//工艺
private String technology ;
//尺寸
private String measure;
//颜色
private String colour;
//入藏时间
private Date enterTime;
//包含藏品数量
private Integer rfidCout;
//藏品来源
private String source;
//馆藏状态
private Integer rfidState=0;
//关键词
private String keyword;
//曾被引用
private String quote;
//关联藏品
@Transient
private String relevance;
//保险
private String insurance;
//藏品编号
private String typeNumber;
//出入库状态
private Integer status=0;
//仓库位置信息
private String locationInformation;
//描述
private String description;
//省略get、set方法
}
2.Excel表格导入后,处理代码如下
/**
* 读取出filePath中的所有数据信息
* @param filePath filePath excel文件的绝对路径
* @param cellNameList 要读取的对应表头名
* @return
*/
public static List<String[]> getDataFromExcel(String filePath,List<String> cellNameList )throws Exception{
List<String[]> resultList = new ArrayList<>();
//判断是否为excel类型文件
if(!filePath.endsWith(".xls")&&!filePath.endsWith(".xlsx"))
{
throw new BaseException("文件不是excel类型");
}
FileInputStream fis =null;
Workbook wookbook = null;
int flag = 0;
try
{
//获取一个绝对地址的流
fis = new FileInputStream(filePath);
}
catch(Exception e)
{
e.printStackTrace();
}
try
{
//2003版本的excel,用.xls结尾
wookbook = new HSSFWorkbook(fis);//得到工作簿
}
catch (Exception ex)
{
try
{
//2007版本的excel,用.xlsx结尾
fis = new FileInputStream(filePath);
wookbook = new XSSFWorkbook(fis);//得到工作簿
} catch (IOException e)
{
e.printStackTrace();
}
}
//得到一个工作表
Sheet sheet = wookbook.getSheetAt(0);
//获得表头
Row rowHead = sheet.getRow(0);
//根据不同的data放置不同的表头
/* Set<String> headSet = new HashSet<>();*/
//判断表头列数是否与预期的列数一致
if(rowHead.getPhysicalNumberOfCells() != cellNameList.size())
{
throw new BaseException("表头列数与要导入的数据库不对应");
}
//判断表头与预期数据是否相符
while (flag < cellNameList.size()){
Cell cell = rowHead.getCell(flag);
String cellName=cellNameList.get(flag);
if (getRightTypeCell(cell).equals(cellName))
{
//headSet.add(cellName);
}else{
throw new BaseException("表头["+getRightTypeCell(cell)+"]不合规范,请修改后重新导入");
}
flag++;
}
/*if(headSet.size()!= cellNameList.size()){
throw new BaseException("表头不合规范,请修改后重新导入");
}*/
//获得数据的总行数
int totalRowNum = sheet.getLastRowNum();
if(0 == totalRowNum)
{
throw new BaseException("Excel内没有数据");
}
//要获得属性
String name = "";
//获得所有数据
for(int i = 1 ; i <= totalRowNum ; i++)
{
//获得第i行对象
Row row = sheet.getRow(i);
String [] cells=new String[cellNameList.size()];
for(int j=0;j<cellNameList.size();j++){
name = (String) getRightTypeCell(row.getCell(j));
cells[j]=name;
}
resultList.add(cells);
}
return resultList;
}
/**
* 把EXCEL Cell原有数据转换成String类型
* @param cell 一个单元格的对象
* @return 返回该单元格相应的类型的值
*/
public static String getRightTypeCell(Cell cell) {
if(cell==null) return "";
String cellSring="";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING: // 字符串
cellSring = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_NUMERIC: // 数字
if(HSSFDateUtil.isCellDateFormatted(cell)){
//用于转化为日期格式
Date d = cell.getDateCellValue();
DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
cellSring= formater.format(d);
}else{
// 用于格式化数字,只保留数字的整数部分
DecimalFormat df = new DecimalFormat("########");
cellSring= df.format(cell.getNumericCellValue());
}
//cellSring=String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
cellSring=String.valueOf(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA: // 公式
cellSring=String.valueOf(cell.getCellFormula());
break;
case HSSFCell.CELL_TYPE_BLANK: // 空值
cellSring="";
break;
case HSSFCell.CELL_TYPE_ERROR: // 故障
cellSring="";
break;
default:
cellSring="ERROR";
break;
}
return cellSring;
}
3.业务逻辑即Service层,代码如下
/**
* 批量导入藏品
* @param file
* @return
* @throws Exception
*/
public List<Rfid> importRfid(MultipartFile file) throws Exception {
List<Rfid> resultList=new ArrayList<>();
String origName = file.getOriginalFilename();
String name = FilesService.trimExt(origName);
String ext = FilesService.getExt(origName);
if (ext != null) {
ext = ext.toLowerCase();
}
String fileName = name+"_"+filesService.generateFileName(new Date());
String fullPath= uploadPathHelper.getRootPath()+ uploadPathHelper.getFilePath() + fileName;
File f = new File(uploadPathHelper.getRootPath()+ uploadPathHelper.getFilePath());
if (!f.exists()) {
f.mkdirs();
}
String url =fullPath+ "." + ext;
File f1 = new File(url);
f1.createNewFile();
file.transferTo(f1);
List<String[]> resultString= excelUtil.getDataFromExcel(url,this.getCellNameList());
resultString.forEach(rfidArray->{
Rfid rfid=new Rfid();
rfid.setName(rfidArray[0]);
rfid.setRfidTypeId(rfidArray[1]);
rfid.setRfidTypeName(rfidArray[2]);
rfid.setTypeName(rfidArray[3]);
rfid.setAge(rfidArray[4]);
rfid.setStylist(rfidArray[5]);
rfid.setBrand(rfidArray[6]);
rfid.setContriesRegions(rfidArray[7]);
rfid.setTexture(rfidArray[8]);
rfid.setTechnology(rfidArray[9]);
rfid.setMeasure(rfidArray[10]);
rfid.setColour(rfidArray[11]);
rfid.setEnterTime(TimeUtil.getDate(rfidArray[12]));
if(rfidArray[13]!=null)
rfid.setRfidCout(Integer.parseInt(rfidArray[13]));
rfid.setSource(rfidArray[14]);
rfid.setKeyword(rfidArray[15]);
rfid.setLocationInformation(rfidArray[16]);
rfid.setDescription(rfidArray[17]);
try {
resultList.add( this.save(rfid,null));
} catch (Exception e) {
e.printStackTrace();
}
});
//导入完成,删除导入文件
File delExt=new File(url);
if(delExt.exists()){
delExt.delete();
}
return resultList;
}
/**
*要导入Excel字段名称
*
**/
public List<String> getCellNameList(){
//导入藏品的字段名称
List<String> cellNameList =new ArrayList<>();
cellNameList.add("名称");
cellNameList.add("藏品类别");
cellNameList.add("藏品类别名称");
cellNameList.add("藏品分类");
cellNameList.add("藏品年代");
cellNameList.add("设计师");
cellNameList.add("品牌");
cellNameList.add("国家地区");
cellNameList.add("材质");
cellNameList.add("工艺");
cellNameList.add("尺寸");
cellNameList.add("颜色");
cellNameList.add("入藏时间");
cellNameList.add("包含藏品数量");
cellNameList.add("藏品来源");
cellNameList.add("关键词");
cellNameList.add("仓库位置信息");
cellNameList.add("描述");
return cellNameList;
}
4.控制层代码
@ResponseBody
@PostMapping("importRfid")
public String importRfid(MultipartFile file) throws Exception {
return Result.succeedResultByMsgAndDate("藏品导入成功",rfidService.importRfid(file));
}
到此Excel批量导入数据完成。