jeeSite 表单页面的Excel 导入功能

698 阅读4分钟

jeeSite 表单页面的Excel 导入功能

前言

本文是在使用jeeSiteV4.3版本的框架的基础上实现的Excel的导入功能,若您没有使用过jeeSite 框架,可以直接忽略本文。

使用Excel 导入的字段其实三种类型,一种是普通的类型,就是Excel 里写的什么,我们就是直接插入到数据库中;还有一种是字典类型的,Excel写的是键,我们需要将对应的键(汉字)转化为代码(通常是编号) ;剩下的一种是对象类型的,比如说员工类型,需要将Excel中的岗位名称转化为数据库中的岗位编码。

接下来,我们分别介绍一下。

普通类型

需要在实体类型的构造方法上写@ExcelFields,sort 是Excel列表字段的顺序,align 是否居中

 @ExcelFields({
             @ExcelField(title="工程登记编码", attrName="engineeringRegistration", align= ExcelField.Align.CENTER, sort=10),   
     })
     public Quality() {
         this(null);
     }

字典类型

需要在普通类型的基础上再添加 dictType="professional_category" ,这是你字典数据中的配置的

 @ExcelFields({
             @ExcelField(title="专业大类", attrName="firstType",dictType="professional_category", align= ExcelField.Align.LEFT, sort=70),
             @ExcelField(title="专业小类", attrName="secondType",dictType="professional_category", align= ExcelField.Align.CENTER, sort=80), 
     })
     public Quality() {
         this(null);
     }

对象类型

需要在普通类型的基础上再添加 fieldType=,这代表的实体类型,会自动将你Excel 中 列表中写的汉字转换为对应的编码

 @ExcelFields({
             @ExcelField(title="归属公司名称", attrName="office", align = ExcelField.Align.CENTER, sort=40,fieldType=OfficeType.class),
             @ExcelField(title="项目经理姓名", attrName="employee", align= ExcelField.Align.CENTER, sort=140,fieldType= EmployeeType.class),
             
     })
     public Quality() {
         this(null);
     }

我们可以看看OfficeType这个类,EmployeeType 原框架中没有,我们也可以自己参考的写一个。

image.png

OfficeType

 /**
  * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
  * No deletion without permission, or be held responsible to law.
  */
 package com.jeesite.common.utils.excel.fieldtype;
 ​
 import java.util.List;
 ​
 import com.jeesite.common.lang.StringUtils;
 import com.jeesite.modules.sys.entity.Office;
 import com.jeesite.modules.sys.utils.EmpUtils;
 ​
 /**
  * 字段类型转换
  * @author ThinkGem
  * @version 2020-3-5
  * @example fieldType = OfficeType.class
  */
 public class OfficeType implements FieldType {
 ​
     private List<Office> list;
     
     public OfficeType() {
         list = EmpUtils.getOfficeAllList();
     }
     
     /**
      * 获取对象值(导入)
      */
     public Object getValue(String val) {
         for (Office e : list){
             if (StringUtils.trimToEmpty(val).equals(e.getOfficeName())){
                 return e;
             }
         }
         return null;
     }
 ​
     /**
      * 设置对象值(导出)
      */
     public String setValue(Object val) {
         if (val != null && ((Office)val).getOfficeName() != null){
             return ((Office)val).getOfficeName();
         }
         return StringUtils.EMPTY;
     }
     
 }
 ​

EmployeeType

 /**
  * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
  * No deletion without permission, or be held responsible to law.
  */
 package com.jeesite.common.utils.excel.fieldtype;
 ​
 import com.jeesite.common.lang.StringUtils;
 import com.jeesite.common.utils.SpringUtils;
 import com.jeesite.modules.sys.entity.Employee;
 import com.jeesite.modules.sys.service.EmployeeService;
 ​
 ​
 import java.util.List;
 ​
 /**
  * 字段类型转换
  * @author ThinkGem
  * @version 2020-3-5
  * @example fieldType = EmployeeType.class
  */
 public class EmployeeType implements FieldType {
 ​
     private List<Employee> list;
 ​
 ​
     private static EmployeeService employeeService = SpringUtils.getBean(EmployeeService.class);;
     
     public EmployeeType() {
         Employee where = new Employee();
         where.setStatus(Employee.STATUS_NORMAL);
         list = employeeService.findList(where);
     }
     
     /**
      * 获取对象值(导入)
      */
     public Object getValue(String val) {
         for (Employee e : list){
             if (StringUtils.trimToEmpty(val).equals(e.getEmpName())){
                 return e;
             }
         }
         return null;
     }
 ​
     /**
      * 设置对象值(导出)
      */
     public String setValue(Object val) {
         if (val != null && ((Employee)val).getEmpName() != null){
             return ((Employee)val).getEmpName();
         }
         return StringUtils.EMPTY;
     }
     
 }
 ​

至此,实体类型上的配置,我们讲完了。接下来,就到前台页面中

前端

jeeSite 框架中无需我们配置Excel 模板,它会根据实体类中的ExcelFields 自动配置Excel,我点击下载的时候,就会有Excel

image.png

 <div class="box-tools pull-right">
                 <a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
                 <!--<a href="#" class="btn btn-default" id="btnExport"><i class="glyphicon glyphicon-export"></i> ${text('导出')}</a>-->
                 <a href="#" class="btn btn-default" id="btnImport"><i class="glyphicon glyphicon-import"></i> ${text('导入')}</a>
             </div>
 ​
 //js
 $('#btnImport').click(function(){
     js.layer.open({
         type: 1,
         area: ['400px'],
         title: '${text("导入质检任务数据")}',
         resize: false,
         scrollbar: true,
         content: js.template('importTpl'),
         success: function(layero, index){
             layero.find('input[type="checkbox"]').iCheck();
         },
         btn: ['<i class="fa fa-check"></i> ${text("导入")}',
             '<i class="fa fa-remove"></i> ${text("关闭")}'],
         btn1: function(index, layero){
             var form = {
                 inputForm: layero.find('#inputForm'),
                 file: layero.find('#file').val()
             };
             if (form.file == '' || (!js.endWith(form.file, '.xls') && !js.endWith(form.file, '.xlsx'))){
                 js.showMessage("${text('文件不正确,请选择后缀为“xls”或“xlsx”的文件。')}", null, 'warning');
                 return false;
             }
             js.ajaxSubmitForm(form.inputForm, function(data){
                 js.showMessage(data.message);
                 if(data.result == Global.TRUE){
                     js.layer.closeAll();
                 }
                 page();
             }, "json");
             return true;
         }
     });
 });
 ​
 ​
 // 配置文件
 <script id="importTpl" type="text/template">//<!--
 <form id="inputForm" action="${ctx}/importData" method="post" enctype="multipart/form-data"
     class="form-horizontal mt20 mb10" style="overflow:auto;max-height:200px;">
     <div class="row">
         <div class="col-xs-12 col-xs-offset-1">
             <input type="file" id="file" name="file" class="form-file"/>
             <div class="mt10 pt5">
                 <a href="${ctx}/importTemplate" class="btn btn-default btn-xs"><i class="fa fa-file-excel-o"></i> ${text('下载模板')}</a>
             </div>
             <font color="red" class="pull-left mt10">
                 ${text('提示:仅允许导入“xls”或“xlsx”格式文件!')}
             </font>
         </div>
     </div>
 </form>
 //--></script>

后端

Controller

 /**
      * 下载导入用户数据模板
      */
     @RequestMapping(value = "importTemplate")
     public void importTemplate(HttpServletResponse response) {
         Quality empUser = new Quality();
         User user = UserUtils.getUser();
 ​
         List<Quality> list = ListUtils.newArrayList(empUser);
         String fileName = "任务数据模板.xlsx";
         try(ExcelExport ee = new ExcelExport("任务数据", Quality.class, ExcelField.Type.IMPORT)){
             ee.setDataList(list).write(response, fileName);
         }
     }
 ​
     /**
      * 导入用户数据
      */
     @ResponseBody
     @PostMapping(value = "importData")
     public String importData(MultipartFile file, String updateSupport) {
         try {
             boolean isUpdateSupport = Global.YES.equals(updateSupport);
             String message = qualityService.importData(file, isUpdateSupport);
             return renderResult(Global.TRUE, "posfull:"+message);
         } catch (Exception ex) {
             return renderResult(Global.FALSE, "posfull:"+ex.getMessage());
         }
     }

Service

 /**
      * 导入用户数据
      * @param file 导入的用户数据文件
      * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
      */
     @Transactional(readOnly=false)
     public String importData(MultipartFile file, Boolean isUpdateSupport) {
         if (file == null){
             throw new ServiceException(text("请选择导入的数据文件!"));
         }
         int successNum = 0; int failureNum = 0;
         StringBuilder successMsg = new StringBuilder();
         StringBuilder failureMsg = new StringBuilder();
         try(ExcelImport ei = new ExcelImport(file, 2, 0)){
             List<Quality> list = ei.getDataList(Quality.class);
             for (Quality quality : list) {
                 try{
                     // 验证数据文件
                     ValidatorUtils.validateWithException(quality);
                     // 部门为空验证
                     if (StringUtils.isBlank(quality.getOffice().getOfficeName())) {
                         failureNum++;
                         failureMsg.append("<br/>" + failureNum
                                 + " 导入失败:所属公司不能为空");
                         continue;
                     }
                     if (StringUtils.isBlank(quality.getEmployee().getEmpName())) {
                         failureNum++;
                         failureMsg.append("<br/>" + failureNum
                                 + " 导入失败:项目经理不能为空");
                         continue;
                     }
 ​
                     
                     // 当前登录人
                     String createby = UserUtils.getUser().getUserName();
                     quality.setCreateUser(createby);
                     quality.setCreateTime(new Date());
 ​
                         this.save(quality);
                         successNum++;
                         successMsg.append("<br/>" + successNum + "任务信息 " + "导入成功");
 ​
                 } catch (Exception e) {
                     failureNum++;
                     String msg = "<br/>" + failureNum +  " 导入失败:";
                     if (e instanceof ConstraintViolationException){
                         ConstraintViolationException cve = (ConstraintViolationException)e;
                         for (ConstraintViolation<?> violation : cve.getConstraintViolations()) {
                             msg += Global.getText(violation.getMessage()) + " ("+violation.getPropertyPath()+")";
                         }
                     }else{
                         msg += e.getMessage();
                     }
                     failureMsg.append(msg);
                     logger.error(msg, e);
                 }
             }
         } catch (Exception e) {
             failureMsg.append(e.getMessage());
             logger.error(e.getMessage(), e);
         }
         if (failureNum > 0) {
             failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
             throw new ServiceException(failureMsg.toString());
         }else{
             successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
         }
         return successMsg.toString();
     }

最后

到此,jeeSite 表单页面的Excel 导入功能,就已经完成,希望可以帮助到大家。欢迎大家评论,点赞,转发。