当前位置:网站首页>jeeSite 表单页面的Excel 导入功能
jeeSite 表单页面的Excel 导入功能
2022-07-07 04:56:00 【涛涛之海】
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 原框架中没有,我们也可以自己参考的写一个。
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
<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 导入功能,就已经完成,希望可以帮助到大家。欢迎大家评论,点赞,转发。
边栏推荐
- Pytorch(六) —— 模型调优tricks
- Common validation comments
- C language flight booking system
- JSON data flattening pd json_ normalize
- These five fishing artifacts are too hot! Programmer: I know, delete it quickly!
- Info | webrtc M97 update
- 2022 National latest fire-fighting facility operator (primary fire-fighting facility operator) simulation questions and answers
- Avatary的LiveDriver试用体验
- Recursive method to construct binary tree from preorder and inorder traversal sequence
- 力扣(LeetCode)187. 重复的DNA序列(2022.07.06)
猜你喜欢
探索干货篇!Apifox 建设思路
Problem solving: unable to connect to redis
Record a stroke skin bone error of the skirt
These five fishing artifacts are too hot! Programmer: I know, delete it quickly!
【数字IC验证快速入门】15、SystemVerilog学习之基本语法2(操作符、类型转换、循环、Task/Function...内含实践练习)
Explore dry goods! Apifox construction ideas
互动送书-《Oracle DBA工作笔记》签名版
Cnopendata list data of Chinese colleges and Universities
[quick start of Digital IC Verification] 17. Basic grammar of SystemVerilog learning 4 (randomization)
[2022 ciscn] replay of preliminary web topics
随机推荐
[quickstart to Digital IC Validation] 15. Basic syntax for SystemVerilog Learning 2 (operator, type conversion, loop, Task / Function... Including practical exercises)
Value sequence (subsequence contribution problem)
[CV] Wu Enda machine learning course notes | Chapter 8
Introduction to basic components of wechat applet
自定义类加载器加载网络Class
Qt学习26 布局管理综合实例
[UVM practice] Chapter 2: a simple UVM verification platform (2) only driver verification platform
Ansible
Avatary的LiveDriver试用体验
The principle and implementation of buffer playback of large video files
2022 tea master (intermediate) examination questions and mock examination
Few-Shot Learning && Meta Learning:小样本学习原理和Siamese网络结构(一)
【数字IC验证快速入门】10、Verilog RTL设计必会的FIFO
Es FAQ summary
Chip design data download
Linux server development, MySQL cache strategy
互动送书-《Oracle DBA工作笔记》签名版
OpenJudge NOI 2.1 1752:鸡兔同笼
LeetCode 90:子集 II
mysql多列索引(组合索引)特点和使用场景