自己原来框架是ruoyi官网框架,网上搜到的Excel导入教程都是老版本的,由于为了适配flowable流程,直接把原有项目移植到ruoyi-vue-plus v4.7.0框架上,发现按照老版本的Excel导入代码不能使用了,自己仿照SysUser重新写了一下导入,分享给大家希望有所帮助。
前端
1.在所需模块的index.vue中的< script >< /script >中增加如下代码:
import { getToken } from "@/utils/auth";
// 用户导入参数
upload: {
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: "",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/complaint/complaint/importData"
},
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
</div>
<span>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</el-dialog>
2.在< template >< /template >中添加导入按钮事件:
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-upload2"
size="mini"
@click="handleImport"
v-hasPermi="['complaint:complaint:import']"
>导入</el-button>
</el-col>
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
</div>
<span>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</el-dialog>
后端
1.在生成目录的controller目录下,加入导入数据和导入数据模版的接口,如图放在ruoyi-admin/src/main/java/com/ruoyi/opti/controller
/**
* 导入数据
*
* @param file 导入文件
* @param updateSupport 是否更新已存在数据
*/
@Log(title = "投诉工单导入", businessType = BusinessType.IMPORT)
@SaCheckPermission("complaint:complaint:import")
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
ExcelResult<OptiComplaintVo> result = ExcelUtil.importExcel(file.getInputStream(), OptiComplaintVo.class,
new OptiComplaintImportListener(updateSupport));
return R.ok(result.getAnalysis());
}
/**
* 获取导入模板
*/
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) {
ExcelUtil.exportExcel(new ArrayList<>(), "投诉工单", OptiComplaintBo.class, response);
}
2.同目录下写一个监听XXXListener,对照源码自己改改,其中需要写一个selectByXXX确保字段唯一的判别函数
/**
* 系统用户自定义导入
*
* @author Lion Li
*/
@Slf4j
public class OptiComplaintImportListener extends AnalysisEventListener<OptiComplaintVo> implements ExcelListener<OptiComplaintVo> {
private final IOptiComplaintService optiComplaintService;
private final Boolean isUpdateSupport;
private int successNum = 0;
private int failureNum = 0;
private final StringBuilder successMsg = new StringBuilder();
private final StringBuilder failureMsg = new StringBuilder();
public OptiComplaintImportListener(Boolean isUpdateSupport) {
// String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword");
this.optiComplaintService = SpringUtils.getBean(IOptiComplaintService.class);
this.isUpdateSupport = isUpdateSupport;
}
@Override
public void invoke(OptiComplaintVo optiComplaintVo, AnalysisContext context) {
OptiComplaintVo complaintVo = this.optiComplaintService.selectComplaintByWorkOrderNum(optiComplaintVo.getWorkOrderNum());
try {
// 验证是否存在这个用户
if (ObjectUtil.isNull(complaintVo)) {
complaintVo = BeanUtil.toBean(optiComplaintVo, OptiComplaintVo.class);
ValidatorUtils.validate(complaintVo);
optiComplaintService.insertByVo(complaintVo);
successNum++;
successMsg.append("<br/>").append(successNum).append("、工单编号 ").append(complaintVo.getWorkOrderNum()).append(" 导入成功");
} else if (isUpdateSupport) {
Long complaintId = complaintVo.getComplaintId();
complaintVo = BeanUtil.toBean(optiComplaintVo, OptiComplaintVo.class);
complaintVo.setComplaintId(complaintId);
ValidatorUtils.validate(complaintVo);
optiComplaintService.updateByVo(complaintVo);
successNum++;
successMsg.append("<br/>").append(successNum).append("、工单编号 ").append(complaintVo.getWorkOrderNum()).append(" 更新成功");
} else {
failureNum++;
failureMsg.append("<br/>").append(failureNum).append("、工单编号 ").append(complaintVo.getWorkOrderNum()).append(" 已存在");
}
} catch (Exception e) {
failureNum++;
String msg = "<br/>" + failureNum + "、工单编号 " + complaintVo.getWorkOrderNum() + " 导入失败:";
failureMsg.append(msg).append(e.getMessage());
log.error(msg, e);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
@Override
public ExcelResult<OptiComplaintVo> getExcelResult() {
return new ExcelResult<OptiComplaintVo>() {
@Override
public String getAnalysis() {
if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
} else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
@Override
public List<OptiComplaintVo> getList() {
return null;
}
@Override
public List<String> getErrorList() {
return null;
}
};
}
}
3.service层代码
/**
* 通过工单编号查询投诉
*
* @param workOrderNum 工单编号
* @return 投诉对象信息
*/
OptiComplaintVo selectComplaintByWorkOrderNum(String workOrderNum);
4.impl实现接口
/**
* 通过工单编号查询投诉
*
* @param workOrderNum 工单编号
* @return 投诉对象信息
*/
@Override
public OptiComplaintVo selectComplaintByWorkOrderNum(String workOrderNum) {
return baseMapper.selectComplaintByWorkOrderNum(workOrderNum);
}
5.Mapper层代码
/**
* 投诉工单Mapper接口
*
* @author ruoyi
* @date 2024-03-14
*/
public interface OptiComplaintMapper extends BaseMapperPlus<OptiComplaintMapper, OptiComplaint, OptiComplaintVo> {
OptiComplaintVo selectComplaintByWorkOrderNum(String workOrderNum);
}
6.Xml代码,位置在同目录的resources/mapper/XXX中
<resultMap type="com.ruoyi.opti.domain.vo.OptiComplaintVo" id="OptiComplaintVoResult">
<result property="XXX" column="XXX"/>
</resultMap>
<select id="selectComplaintByWorkOrderNum" parameterType="String" resultMap="OptiComplaintVoResult">
select * from opti_complaint oc where oc.work_order_num = #{workOrderNum} limit 1
</select>
7.如果框架是Bo、Vo类型的,则需要新增Vo类的接口和实现类
/**
* 新增投诉工单Vo
*/
Boolean insertByVo(OptiComplaintVo vo);
/**
* 修改投诉工单Vo
*/
Boolean updateByVo(OptiComplaintVo vo);
/**
* 新增投诉工单Vo
*/
@Override
public Boolean insertByVo(OptiComplaintVo vo) {
OptiComplaint add = BeanUtil.toBean(vo, OptiComplaint.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
vo.setComplaintId(add.getComplaintId());
}
return flag;
}
/**
* 修改投诉工单Vo
*/
@Override
public Boolean updateByVo(OptiComplaintVo vo) {
OptiComplaint update = BeanUtil.toBean(vo, OptiComplaint.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
以上就是所有代码需要修改的部分,重点在监听那块,亲测有效,互相交流用,如有问题还请指出。