当前位置:   article > 正文

基于RuoYi-Flowable-Plus、RuoYi-Vue-Plus(v4.7.x)框架Excel导入功能实现保姆教程

ruoyi-flowable-plus

自己原来框架是ruoyi官网框架,网上搜到的Excel导入教程都是老版本的,由于为了适配flowable流程,直接把原有项目移植到ruoyi-vue-plus v4.7.0框架上,发现按照老版本的Excel导入代码不能使用了,自己仿照SysUser重新写了一下导入,分享给大家希望有所帮助。

前端

1.在所需模块的index.vue中的< script >< /script >中增加如下代码:

import { getToken } from "@/utils/auth";

  1. // 用户导入参数
  2. upload: {
  3. // 是否显示弹出层(用户导入)
  4. open: false,
  5. // 弹出层标题(用户导入)
  6. title: "",
  7. // 是否禁用上传
  8. isUploading: false,
  9. // 是否更新已经存在的用户数据
  10. updateSupport: 0,
  11. // 设置上传的请求头部
  12. headers: { Authorization: "Bearer " + getToken() },
  13. // 上传的地址
  14. url: process.env.VUE_APP_BASE_API + "/complaint/complaint/importData"
  15. },

  1. <!-- 用户导入对话框 -->
  2. <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
  3. <el-upload
  4. ref="upload"
  5. :limit="1"
  6. accept=".xlsx, .xls"
  7. :headers="upload.headers"
  8. :action="upload.url + '?updateSupport=' + upload.updateSupport"
  9. :disabled="upload.isUploading"
  10. :on-progress="handleFileUploadProgress"
  11. :on-success="handleFileSuccess"
  12. :auto-upload="false"
  13. drag
  14. >
  15. <i class="el-icon-upload"></i>
  16. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  17. <div class="el-upload__tip text-center" slot="tip">
  18. <div class="el-upload__tip" slot="tip">
  19. <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
  20. </div>
  21. <span>仅允许导入xls、xlsx格式文件。</span>
  22. <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
  23. </div>
  24. </el-upload>
  25. <div slot="footer" class="dialog-footer">
  26. <el-button type="primary" @click="submitFileForm">确 定</el-button>
  27. <el-button @click="upload.open = false">取 消</el-button>
  28. </div>
  29. </el-dialog>

2.在< template >< /template >中添加导入按钮事件:

  1. <el-col :span="1.5">
  2. <el-button
  3. type="info"
  4. plain
  5. icon="el-icon-upload2"
  6. size="mini"
  7. @click="handleImport"
  8. v-hasPermi="['complaint:complaint:import']"
  9. >导入</el-button>
  10. </el-col>

  1. <!-- 用户导入对话框 -->
  2. <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
  3. <el-upload
  4. ref="upload"
  5. :limit="1"
  6. accept=".xlsx, .xls"
  7. :headers="upload.headers"
  8. :action="upload.url + '?updateSupport=' + upload.updateSupport"
  9. :disabled="upload.isUploading"
  10. :on-progress="handleFileUploadProgress"
  11. :on-success="handleFileSuccess"
  12. :auto-upload="false"
  13. drag
  14. >
  15. <i class="el-icon-upload"></i>
  16. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  17. <div class="el-upload__tip text-center" slot="tip">
  18. <div class="el-upload__tip" slot="tip">
  19. <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
  20. </div>
  21. <span>仅允许导入xls、xlsx格式文件。</span>
  22. <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
  23. </div>
  24. </el-upload>
  25. <div slot="footer" class="dialog-footer">
  26. <el-button type="primary" @click="submitFileForm">确 定</el-button>
  27. <el-button @click="upload.open = false">取 消</el-button>
  28. </div>
  29. </el-dialog>

 后端

1.在生成目录的controller目录下,加入导入数据和导入数据模版的接口,如图放在ruoyi-admin/src/main/java/com/ruoyi/opti/controller

  1. /**
  2. * 导入数据
  3. *
  4. * @param file 导入文件
  5. * @param updateSupport 是否更新已存在数据
  6. */
  7. @Log(title = "投诉工单导入", businessType = BusinessType.IMPORT)
  8. @SaCheckPermission("complaint:complaint:import")
  9. @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  10. public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
  11. ExcelResult<OptiComplaintVo> result = ExcelUtil.importExcel(file.getInputStream(), OptiComplaintVo.class,
  12. new OptiComplaintImportListener(updateSupport));
  13. return R.ok(result.getAnalysis());
  14. }
  15. /**
  16. * 获取导入模板
  17. */
  18. @PostMapping("/importTemplate")
  19. public void importTemplate(HttpServletResponse response) {
  20. ExcelUtil.exportExcel(new ArrayList<>(), "投诉工单", OptiComplaintBo.class, response);
  21. }

 2.同目录下写一个监听XXXListener,对照源码自己改改,其中需要写一个selectByXXX确保字段唯一的判别函数

  1. /**
  2. * 系统用户自定义导入
  3. *
  4. * @author Lion Li
  5. */
  6. @Slf4j
  7. public class OptiComplaintImportListener extends AnalysisEventListener<OptiComplaintVo> implements ExcelListener<OptiComplaintVo> {
  8. private final IOptiComplaintService optiComplaintService;
  9. private final Boolean isUpdateSupport;
  10. private int successNum = 0;
  11. private int failureNum = 0;
  12. private final StringBuilder successMsg = new StringBuilder();
  13. private final StringBuilder failureMsg = new StringBuilder();
  14. public OptiComplaintImportListener(Boolean isUpdateSupport) {
  15. // String initPassword = SpringUtils.getBean(ISysConfigService.class).selectConfigByKey("sys.user.initPassword");
  16. this.optiComplaintService = SpringUtils.getBean(IOptiComplaintService.class);
  17. this.isUpdateSupport = isUpdateSupport;
  18. }
  19. @Override
  20. public void invoke(OptiComplaintVo optiComplaintVo, AnalysisContext context) {
  21. OptiComplaintVo complaintVo = this.optiComplaintService.selectComplaintByWorkOrderNum(optiComplaintVo.getWorkOrderNum());
  22. try {
  23. // 验证是否存在这个用户
  24. if (ObjectUtil.isNull(complaintVo)) {
  25. complaintVo = BeanUtil.toBean(optiComplaintVo, OptiComplaintVo.class);
  26. ValidatorUtils.validate(complaintVo);
  27. optiComplaintService.insertByVo(complaintVo);
  28. successNum++;
  29. successMsg.append("<br/>").append(successNum).append("、工单编号 ").append(complaintVo.getWorkOrderNum()).append(" 导入成功");
  30. } else if (isUpdateSupport) {
  31. Long complaintId = complaintVo.getComplaintId();
  32. complaintVo = BeanUtil.toBean(optiComplaintVo, OptiComplaintVo.class);
  33. complaintVo.setComplaintId(complaintId);
  34. ValidatorUtils.validate(complaintVo);
  35. optiComplaintService.updateByVo(complaintVo);
  36. successNum++;
  37. successMsg.append("<br/>").append(successNum).append("、工单编号 ").append(complaintVo.getWorkOrderNum()).append(" 更新成功");
  38. } else {
  39. failureNum++;
  40. failureMsg.append("<br/>").append(failureNum).append("、工单编号 ").append(complaintVo.getWorkOrderNum()).append(" 已存在");
  41. }
  42. } catch (Exception e) {
  43. failureNum++;
  44. String msg = "<br/>" + failureNum + "、工单编号 " + complaintVo.getWorkOrderNum() + " 导入失败:";
  45. failureMsg.append(msg).append(e.getMessage());
  46. log.error(msg, e);
  47. }
  48. }
  49. @Override
  50. public void doAfterAllAnalysed(AnalysisContext context) {
  51. }
  52. @Override
  53. public ExcelResult<OptiComplaintVo> getExcelResult() {
  54. return new ExcelResult<OptiComplaintVo>() {
  55. @Override
  56. public String getAnalysis() {
  57. if (failureNum > 0) {
  58. failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
  59. throw new ServiceException(failureMsg.toString());
  60. } else {
  61. successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
  62. }
  63. return successMsg.toString();
  64. }
  65. @Override
  66. public List<OptiComplaintVo> getList() {
  67. return null;
  68. }
  69. @Override
  70. public List<String> getErrorList() {
  71. return null;
  72. }
  73. };
  74. }
  75. }

 3.service层代码

  1. /**
  2. * 通过工单编号查询投诉
  3. *
  4. * @param workOrderNum 工单编号
  5. * @return 投诉对象信息
  6. */
  7. OptiComplaintVo selectComplaintByWorkOrderNum(String workOrderNum);

4.impl实现接口

  1. /**
  2. * 通过工单编号查询投诉
  3. *
  4. * @param workOrderNum 工单编号
  5. * @return 投诉对象信息
  6. */
  7. @Override
  8. public OptiComplaintVo selectComplaintByWorkOrderNum(String workOrderNum) {
  9. return baseMapper.selectComplaintByWorkOrderNum(workOrderNum);
  10. }

 

5.Mapper层代码

  1. /**
  2. * 投诉工单Mapper接口
  3. *
  4. * @author ruoyi
  5. * @date 2024-03-14
  6. */
  7. public interface OptiComplaintMapper extends BaseMapperPlus<OptiComplaintMapper, OptiComplaint, OptiComplaintVo> {
  8. OptiComplaintVo selectComplaintByWorkOrderNum(String workOrderNum);
  9. }

6.Xml代码,位置在同目录的resources/mapper/XXX中

  1. <resultMap type="com.ruoyi.opti.domain.vo.OptiComplaintVo" id="OptiComplaintVoResult">
  2. <result property="XXX" column="XXX"/>
  3. </resultMap>
  4. <select id="selectComplaintByWorkOrderNum" parameterType="String" resultMap="OptiComplaintVoResult">
  5. select * from opti_complaint oc where oc.work_order_num = #{workOrderNum} limit 1
  6. </select>

7.如果框架是Bo、Vo类型的,则需要新增Vo类的接口和实现类

  1. /**
  2. * 新增投诉工单Vo
  3. */
  4. Boolean insertByVo(OptiComplaintVo vo);
  5. /**
  6. * 修改投诉工单Vo
  7. */
  8. Boolean updateByVo(OptiComplaintVo vo);

 

  1. /**
  2. * 新增投诉工单Vo
  3. */
  4. @Override
  5. public Boolean insertByVo(OptiComplaintVo vo) {
  6. OptiComplaint add = BeanUtil.toBean(vo, OptiComplaint.class);
  7. validEntityBeforeSave(add);
  8. boolean flag = baseMapper.insert(add) > 0;
  9. if (flag) {
  10. vo.setComplaintId(add.getComplaintId());
  11. }
  12. return flag;
  13. }
  14. /**
  15. * 修改投诉工单Vo
  16. */
  17. @Override
  18. public Boolean updateByVo(OptiComplaintVo vo) {
  19. OptiComplaint update = BeanUtil.toBean(vo, OptiComplaint.class);
  20. validEntityBeforeSave(update);
  21. return baseMapper.updateById(update) > 0;
  22. }

 

以上就是所有代码需要修改的部分,重点在监听那块,亲测有效,互相交流用,如有问题还请指出。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号