背景
图书馆项目中用到excel的导入导出,不过组长整理了文档,我们可以按照组长整理的文档来。不过,就算是有了文档我们也是遇到了很多问题,做了一些分析之后清晰了很多,说明什么呢?文档是帮助我们思考,不是让我们坐享其成的。
操作
配置文件
在Pom文件中加入下面的配置:
<version.JExcel>1.0.0-SNAPSHOT</version.JExcel>
<!--导入导出的依赖-->
<dependency>
<groupId>org.jplus</groupId>
<artifactId>J-Excel</artifactId>
<version>${version.JExcel}</version>
</dependency>
注解
我们在整个实体中增加注解类注解@ExcelModelConfig
导入的时候,我们提供相应的文字,例如班级:土木一班,但是我们在数据库增加的一条数据确实这样的:className:土木一班。这个时候需要我们在实体中添加注解,让她知道,班级对应的字段是className。如下:@Lang(value=”属性对应要导出的名字”)
导出同上,我们要让它认识到导出的班级的字段是className。
主外键关联,我们用字典管理。说明一下,我们在班级表中有一个年级的外键:gradeId,但是我们导入的时候,在班级表里插入的数据时年级:一年级,但是我们数据库存的时候,应该是一年级对应的gradeId。首先我们添加注解:@InputDicConfig(dicCode=”gradeId”),其次我们需要将主外键进行关联:
Map<Serializable,Serializable> dictDataMap=new HashMap<>();
Map<Serializable,Serializable> gradeData=new HashMap<>();
Map<Serializable,Serializable> majorData=new HashMap<>();
gradeData.put("11", "土木1班");
gradeData.put("10", "土木2班");
gradeData.put( "9","工管1班");
majorData.put("1", "土木工程");
majorData.put("2", "信息技术");
dictDataMap.put("gradeId", (Serializable) gradeData);
dictDataMap.put("majorId", (Serializable) majorData)
excel解析
String filePath = UploadFileUtil.upload(response, request);
Map<Serializable,Serializable> map = new HashMap<>();
map.put("sheetName","sheet1");
map.put("Class",BookType.class);
List<BookType> importListParentType=ExcelUtil.importExcel(filePath,response,map);
实例分析
导出
/**
* 下载模板--刘雅雯--2017年11月3日20:31:24
* @param requst
* @param response
* @return
*/
@GET
@Path("/downBookType")
@ApiOperation(value = "下载模板", response = BookType.class, responseContainer = "List", tags = "Android")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "成功", response = BookType.class)
,
@ApiResponse(code = 400, message = "Not Found", response = BookType.class)})
public ItooResult downExcel(@Context HttpServletRequest requst,@Context HttpServletResponse response){
Map<Serializable,Serializable> map=new HashMap<>();
//sheet的名字
map.put("sheetName","sheet1");
map.put("columns",new String[]{"name","PID","Pname","remark"});
//导出的表格标题
map.put("title","图书类别管理");
List<BookType> bookTypeList = new ArrayList<>();
BookType bookTypeView=new BookType();
bookTypeView.setName("诗歌");
bookTypeView.setPID("文学类");
bookTypeView.setPname("文学类");
bookTypeView.setRemark("刘雅雯测试数据");
bookTypeList.add(bookTypeView);
map.put("dataList",(Serializable)bookTypeList);
try {
ExcelUtil.exportExcel(map,response);
log.info("下载模板成功");
return ItooResult.build("0000", "下载成功");
} catch (Exception e) {
log.error("下载模板失败");
return ItooResult.build("1111", "下载失败");
}
}
导入
我们表中有两个字段:id和pid,其中的主外键关联是一张表进行关联的,根据我们的pid我们要找到对应id下的name是什么;再有就是添加一条记录中我们涉及到了父类和子类的关系,即当父类中没有的话我们需要先添加一条父类,再进行子类的添加。那么问题就来了,因为涉及到了主外键的关联,因此需要进行两次excel解析。
@POST
@Path("/importBookType/")
@Consumes({"multipart/form-data"})
@Produces({ "application/json" })
@ApiOperation(value = "通过excel导入图书分类", notes = "Adds items to the system", response = void.class, tags= "PC")
@ApiResponses(value = {
@ApiResponse(code = 201, message = "item created", response = void.class),
@ApiResponse(code = 400, message = "invalid input, object invalid", response = void.class),
@ApiResponse(code = 409, message = "an existing item already exists", response = void.class) })
/**
* 导入-刘雅雯重构--2017年11月3日20:30:33
*
*/
public ItooResult importBookType(@Context HttpServletResponse response,@Context HttpServletRequest request)
throws NotFoundException ,Exception{
String filePath = UploadFileUtil.upload(response, request);
Map<Serializable,Serializable> map = new HashMap<>();
map.put("sheetName","sheet1");
map.put("Class",BookType.class);
//将查询出来的外键关联值放入map中
Map<Serializable,Serializable> dictDataMap=new HashMap<>();
Map<Serializable,Serializable> classData=new HashMap<>();
//当插入子类和父类时:先查询导入中是否有父类,如果没有的话就先添加父类
try{
//获取excel的数据
List<BookType> importListParentType =ExcelUtil.importExcel(filePath,response,map);
TBookAndType bookTypeEntity =new TBookAndType();
BookType bookTypeList =new BookType();
for (int i=0; i<importListParentType.size();i++){
bookTypeList=importListParentType.get(i);
//判断是父类名称是否为null,如果为null则不用添加
if (bookTypeList.getPID()!=null)
{
//通过父类名称查询是否有该条记录
List<TBookAndType> bookTypeTemp=bookTypeService.findTypeIdByTypeName(bookTypeList.getPname());
//没有这条记录,则添加一条
if (bookTypeTemp!=null && bookTypeTemp.size()==0){
bookTypeEntity.setpId("0");
bookTypeEntity.setName(bookTypeList.getPname());
bookTypeEntity.setId(bookTypeList.getId());
bookTypeEntity.setShelfId("");
bookTypeEntity.setRemark(bookTypeList.getRemark());
bookTypeEntity.setoperator("");
//添加
bookTypeService.addBookType(bookTypeEntity);
}else{
continue;
}
}else{
continue;
}
}
}
catch (Exception e)
{
log.error("导入失败");
return ItooResult.build("1111", "教师信息导入失败");
}
//获取父类名称和键值的对应关系
List<TBookAndType> tBookAndTypeList =bookTypeService.findAllbookType();
if (tBookAndTypeList!=null && tBookAndTypeList.size()!=0){
for (int i =0 ;i<tBookAndTypeList.size();i++){
classData.put(tBookAndTypeList.get(i).getId(),tBookAndTypeList.get(i).getName());
}
}
dictDataMap.put("PID",(Serializable)classData);
boolean flag = false;
try{
//获取excel中的数据
List<BookType> importList = ExcelUtil.importExcel(filePath,response,map,dictDataMap);
TBookAndType bookTypeEntity = new TBookAndType();
BookType bookType =new BookType();
for(int n = 0; n<importList.size();n++){
bookType = importList.get(n);
//判断要添加的类别名称是否已经存在,若存在执行n+1
List<TBookAndType> bookTypeList=bookTypeService.findTypeIdByTypeName(bookType.getName());
if (bookTypeList!=null && bookTypeList.size()!=0){
continue;
}
bookTypeEntity.setId(bookType.getId());
bookTypeEntity.setName(bookType.getName());
if (bookType.getPID()==null){
bookTypeEntity.setpId("0");
}else {
bookTypeEntity.setpId(bookType.getPID());
}
bookTypeEntity.setRemark(bookType.getRemark());
bookTypeEntity.setShelfId("");
bookTypeEntity.setoperator("");
bookTypeService.addBookType(bookTypeEntity);
}
log.info("导入成功");
return ItooResult.build("0000", "图书类型信息导入成功",flag);
}catch(Exception e){
log.error("导入失败");
return ItooResult.build("1111", "教师信息导入失败");
}
}
End
代码的调试,导入的过程可以分成两部分,第一部分:从excel中获取数据,第二部分添加到数据库中。不过我们前端访问的时候就要多加一部分:上传到服务器上。代码调试的过程中思路很重要。
文档的学习,多加练习自己看起来用起来才不会很被动~