Excel匯入操作
在專案開發的過程中,我們經常會用到excel 表格的匯入匯出,剛解決難免會遇到很多問題,我們使用的是J-Excel 封裝好的工具,下面就總結一下具體的操作流程.
一:pom.xml中新增依賴
(1)對於SSM 的專案需要在api的POM檔案中加入對J-Excel的依賴
<dependency> <groupId>org.jplus</groupId> <artifactId>J-Excel</artifactId> <scope>provided</scope> </dependency>
在web的POM檔案中加入對J-Excel的依賴
<dependency>
<groupId>org.jplus</groupId>
<artifactId>J-Excel</artifactId>
</dependency>
另外有匯入功能的,在Web的POM中加入對commons-fileupload的依賴
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> </dependency>
如果有匯入的功能,則在web的spring-mvc.xml中加入:
<!-- SpringMVC上傳檔案時,需要配置MultipartResolver處理器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8" /> <!-- 指定所上傳檔案的總大小不能超過10485760000B。注意maxUploadSize屬性的限制不是針對單個檔案,而是所有檔案的容量之和 --> <property name="maxUploadSize" value="10485760000"></property> <property name="maxInMemorySize" value="40960"></property> </bean>
(2)對於springboot 的專案,因為沒有springmvc並且集成了multipartResolver.所以直接在該專案的pom檔案中新增依賴即可:
<dependency>
<groupId>org.jplus</groupId>
<artifactId>J-Excel</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
二:實體類的配置
1、 加入類註解 @ExcelModelConfig
2、 Excel表格需要匯入的欄位對應的每個屬性加入註解@Lang(value=”屬性對應excel表頭要匯入的名字”)
3、 預設情況下屬性值是可以為空的,如果不允許為空,則加入不為空註解。根據不同的資料型別使用不同的註解:
日期型:@InputDateConfig(nullable=false)
字元型:@InputTextConfig(nullable=false)
數字型:@InputIntConfig(nullable=false)
如下式我配置的實體類:
package com.dmsdbj.integral.training.entity;
import com.dmsdbj.cloud.tool.business.BaseEntity;
import lombok.*;
import lombok.experimental.*;
import io.swagger.annotations.*;
import org.jplus.hyberbin.excel.annotation.ExcelModelConfig;
import org.jplus.hyberbin.excel.annotation.Lang;
import org.jplus.hyberbin.excel.annotation.input.InputDicConfig;
import javax.persistence.*;
import java.io.Serializable;
/**
* TrainingProgram實體
* 培養計劃專案表
*
* @author 李娜
* @version 0.0.2
* @since 0.0.2 2018-09-18 11:04:05
*/
@ApiModel(value = "TrainingProgramEntity:培養計劃專案表")
@Data
@NoArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "tit_training_program")
@ExcelModelConfig
public class TrainingProgramEntity extends BaseEntity implements Serializable{
/**
* 專案名稱
*/
@Lang(value = "專案名稱")
@ApiModelProperty(value = "專案名稱")
@Column(name = "name")
private String name;
/**
* 所屬等級id
*/
@InputDicConfig(dicCode="levelId")
@ApiModelProperty(value = "所屬等級id")
@Column(name = "level_id")
private String levelId;
/**
* 該專案在該等級序列
*/
@Lang(value = "該等級序列")
@ApiModelProperty(value="該等級序列")
@Column(name = "project_order")
private Integer projectOrder;
/**
* 培養計劃等級
*/
@Lang(value = "等級")
@ApiModelProperty(value="等級")
@Column(name = "level_order")
private Integer levelOrder;
/**
* 該級別所獲得積分
*/
@Lang(value = "該級別所獲得積分")
@ApiModelProperty(value = "該級別所獲得積分")
@Column(name = "integral")
private Integer integral;
/**
* 專案介紹
*/
@Lang(value = "專案介紹")
@ApiModelProperty(value = "專案介紹")
@Column(name = "description")
private String description;
}
三.在controller中呼叫J-Excel封裝的匯入的方法
/**
* 匯入excel資料培養計劃專案
* @return 匯入的結果
* @author 李娜
* @since 0.0.2 2018年10月26日16:26:39
*/
@ResponseBody
@RequestMapping(value={"/importTraining/{file}"},method=RequestMethod.POST)
@ApiOperation(value="匯入Excel")
public IntegralResult importTraining(@RequestParam(value="file") MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response){
List<TrainingProgramEntity> trainingList=new ArrayList<>();
//將excel解析成list
if (multipartFile.isEmpty()){
return IntegralResult.build("1111","匯入檔案為空",null);
}
Map<Serializable,Serializable> map=new HashMap<>(16);
//**sheet的名稱*//*
map.put("sheetName","培養計劃"); //必須與表格sheet的名稱相對應
map.put("Class",TrainingProgramEntity.class);//匯入對應的實體類
try{
//讀取excel表格資料
trainingList= ExcelUtil.importExcel(multipartFile.getOriginalFilename(),map,request,response);
if(CollectionUtils.isEmpty(trainingList)){
return IntegralResult.build("1111","讀取Excel返回結果為空!",null);
}else
{
//查詢出所有的等級
IntegralResult<LevelModel> LevelResult=queryAllLevel();
String levelList= JsonUtil.beanToJson(LevelResult.getData(), true);
//將查詢出來的級別轉化成需要的list的型別
Gson gson=new Gson();
ArrayList<LevelModel> list = new ArrayList<LevelModel>();
Type listType = new TypeToken<List<LevelModel>>() {}.getType();
list = gson.fromJson(levelList, listType);
//將查詢出來的級別迴圈放入Map中, key為LevelOrderId級別,value為levelId即級別對應的id
Map<Integer,String> levelMap=new HashMap<>();
for(LevelModel level:list){
levelMap.put(level.getLevelOrderId(),level.getId());
}
//為表格中每個實體物件新增上levelId
for(TrainingProgramEntity training: trainingList){
if(levelMap.containsKey(training.getLevelOrder())){
training.setLevelId(levelMap.get(training.getLevelOrder()));
}
}
//批量匯入培養計劃資料
Iterable<TrainingProgramEntity> training=trainingProgramService.insert(trainingList);
return IntegralResult.build("0000","操作成功",training);
}
}catch(Exception e){
log.error("Excel匯入異常", e);
return IntegralResult.build("1111", "操作異常,請重新匯入");
}
}
這樣就可以把excel匯入到資料庫中了
匯入操作遇到的問題:
1.獲取sheetname 報NullException
原因:
//**sheet的名稱*//*
map.put("sheetName","培養計劃"); //必須與表格sheet的名稱相對應
map.put("Class",TrainingProgramEntity.class);//匯入對應的實體類
在這裡給sheetName賦值,在原始碼中會根據sheetName 來獲取要解析的表格,但是我傳入的表格中sheetName不是培養計劃,這樣的話就會報NullExcption了
2.Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path
返回的資料解析錯誤
IntegralResult<LevelModel> LevelResult=queryAllLevel();
//返回Object型別強轉成List 型別
List<LevelModel> list= (List)LevelResult.getData();
Map<Integer,String> levelMap=new HashMap<>();
//將查詢出來的級別迴圈放入Map中, key為LevelOrderId級別,value為levelId即級別對應的id
for(LevelModel level:list){
levelMap.put(level.getLevelOrderId(),level.getId());
}
當執行到for(LevelModel level:list)時就會報錯.
java.util.LinkedHashMap cannot be cast to com.dmsdbj.integral.kernel.api.model.LevelModel 或
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path
原因:返回資料解析錯誤,沒有轉換成我們期望的list型別
解決辦法:
用 TypeToken 轉一下
//查詢出所有的等級
IntegralResult<LevelModel> LevelResult=queryAllLevel();
String levelList= JsonUtil.beanToJson(LevelResult.getData(), true);
//將查詢出來的級別轉化成需要的list的型別
Gson gson=new Gson();
ArrayList<LevelModel> list = new ArrayList<LevelModel>();
Type listType = new TypeToken<List<LevelModel>>() {}.getType();
list = gson.fromJson(levelList, listType);