Excel+vue+java实现批量处理功能

需求背景:
产品创建流程比较复杂,有时候需要一次性创建多至10+个,所以做了Excel维护产品信息,直接导入创建的功能。能极大提高效率。

简要概括实现:
一、参考单个创建,设计创建模板,表头对应填写字段名,后续每一行为每一个创建对象填写参数值。
二、页面添加批量创建按钮,实现点击时打开批量上传窗口。
三、添加窗口采用el-dialog组件,点击确定调批量处理接口。
四、前端实现批量操作窗口各种操作函数(上传文件、取消、确定)。
五、后端增加批量处理接口。
六、实现处理接口:循环读表数据调单个处理接口,并包装创建结果返回前端。

具体如下。
一、参考单个创建,设计创建模板,表头对应填写字段名,后续每一行为每一个创建对象填写参数值。如图:
在这里插入图片描述

二、页面添加批量创建按钮,实现点击时打开批量上传窗口。
页面对应.vue文件样式增加代码:

<el-button type="primary" size="mini" @click="openUploadFileDialog">批量创建</el-button>
<e-link type="primary'href="/template/批量创建产品模板.xlsx" download="批量创建产品模板.xlsx">下载文件模板</e-ink>

三、添加窗口采用el-dialog组件,点击确定调批量处理接口。
页面对应.vue文件样式增加代码:

<div>
<div>
<el-dialog
title="批量创建"
:visible.sync="dialogVisible"
width="30%"><span>
<el-upload
class="upload-demo"
ref="createProdlnBulk"
drag
:action="uploadURL" // 批量创建接
accept=".xlsx,.xls" // 限制文件类型
:auto-upload="false
:limit="1"
:file-list="fileList" //定义file-list接收文件,上传成功后清空
:on-success="handleFilUploadSuccess" // 上传成功后调用
:before-upload="beforeUpload" // 选中文件后调用
<i class="el-icon-upload"></i>
<div class="el-upload_text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload_tip"slot="tip">只能上传 excel 文件,且不超过500kb</div>
</el-upload></span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleUpload()">确定</ el-button>
</span></el-dialog></div>

四、前端实现批量操作窗口各种操作函数。
页面对应.vue文件js脚本增加代码:

<script>
import { createProd} from'@/api/prod'
import request from@/utils/request'
import'@/utils/dialog' 
data() {return {
response:'',
// 如果是多环境,可以获取基础url地址+接口设置上传地址
uploadURL:request.defaults.baseURL+'/ xxx/createProdlnBulk',
dialogVisible: false, 
fileList:[],
},
methods:{
// 文件上传成功时的函数 
handleFilUploadSuccess(res,file,fileList) {
// console.log(res,file,fileList)
$message.success("创建完成")
console.log("res.data")
// 接收响应数据,可用于展示在页面
this.response = res.data
// 上传成功后跳到responseTab页( <el-container>组件的特性),并展示响应数据
this.activeName ='responseTab'
// 重置文件 this.fileList =[]
},
openUploadFileDialog (){ 
this.dialogVisible=true;
},
beforeUpload(file) {
// 拦截下非Excel文件 
const isExcel =file.type==='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.type==='application/vnd.ms-excel';
if (!isExcel) {
this.$message.error('只能上传Excel文件!');
return isExcel;
},
handleRemove(file,fileList){
console.log(file,fileList);
},
submitUpload(){
this.$refs.createProdInBulk.submit();
},
}}
</script>

五、后端增加批量处理接口。
controller层增加代码:

@RequestMapping(value= {"/{env}/xxx/createProdlnBulk"},method=RequestMethod.POST)public ResponseInfo createProdlnBulk(@PathV ariable String env, @Valid FileWorkDTO fileWorkDTO, HttpServletRequest request,@RequestParam("file") MultipartFile file) throws IOException {
return createProdServicelmpl.createProdlnBulk(env, file);
}

六、实现处理接口:循环读表数据调单个处理接口,并包装创建结果返回前端。
createProdServicelmpl类增加代码:

public ResponseInfo createProdlnBulk(String env, MultipartFile file) throws BizException,IOException{
// System.out.println("request=" + httpRequest);
System.out.println("file.toString() ="+ file.toString());
String allRes ="批量创建结果:";  // 响应内容
// 获取文件数据流 
try (
InputStream inputStream =file.getlnputStream()Workbook workbook= WorkbookFactory.create(inputStream);
Sheet sheet =workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
rowIterator.next(); //跳过表头
Row headerRow = sheet.getRow(0); // 获取表头行
// 遍历文件所有行(表头行除外)
while(rowlterator.hasNext()){
Row row =
rowIterator.next();
if(isRowEmpty(row)) {
continue; // 如果整行数据为空,则跳过
}
//当前行数据检查:空值检查、Date相关字段检查
Iterator<Cell> cellIterator1 = row.cellIterator();
while(cellIterator1.hasNext()){
Cell cell =cellIterator1.next();
if(cell.getStringCellValue().isEmpty()){
return newResponselnfo(RetCode.ERROR_CODE,RetCode.ERROR_MSG,cell.getColumnIndex()+"列数据为空");
String value =cell.getCellTypeEnum().toString().equals("STRING") ? cell.getStringCellValue():String.valueOf(cell.getNumericCellValue());
if(headerRow.getCell(cell.getColumnIndex()).getStringCellValue().contains("Date") && value.length() != 8){
System.out.println("key+value = " + header Row.getCell(cell.getColumn Index()).getStringCellValue()+value);
return newResponselnfo(RetCode.ERROR_CODE,"表格类型或值错误","表格类型或值错误");
}
// 获取当前行全部字段值(如果模板字段跟创建接口字段统一,直接遍历获取就行,比较方便)
Map<String,Object> request = new HashMap<>();
Iterator<Cell> cellIterator =
row.cellIterator();
while(cellIterator.hasNext()){
Cell cell =cellIterator.next();
if(cell.getStringCellValue().isEmpty()){
// return newResponselnfo(RetCode.ERR OR_CODE,RetCode.ERROR_ MSG,cell.getColumnIndex()+"列数据为空");//
}
System.out.println("headerR ow.getCell(cell.getColumnlndex()).getStringCellValue()=" +headerRow.getCell(cell.getColumnIndex()).getStringCellValue());
String value =cell.getCellTypeEnum().tostring().equals("STRING") ? cell.getStringCellValue(): String.valueOf(cell.getNumericCellValue());
request.put(headerRow.getCell(cell.getColumnIndex()).getStringCellValue(),value);
// 调用单个创建接口,创建产品
request.put("createType","1");
request.put("requestld","createProdinBulk-" + DateUtil.getUUID());
insertOprLog(env,request); // 插入操作历史记录
Responselnfo<T>res = createProd("fat",request);// 调用创建产品的逻辑
// 收集单个创建结果
allRes +=res.getData() +"\n";
System.out.println("res.getData()="+ res.getData());
}
// 更新历史记录结果 
updateOprLog(jsonResponse, request.get("reque stld").toString());
} catch (Exception e) {
e.printStackTrace(); 
return new Response Info(RetCode.ERROR_CODE, RetCode.ERROR_MSG, allRes);
}
return new Responselnf o(RetCode.SUCCESS_CODE, RetCode.SUCCESS_MSG, allRes);
}

七、一些坑。
1>、上传后文件未清除,每次要点x再重新上传。
解决:定义 fileList 接收文件,上传成功后把fileList清空。具体:
el-dialog组件加: file-list=“fileList”
return {}中加 fileList 定义
handleFilUploadSuccess()函数里,把fileList清空。

2>、Excel表的单元格数据获取失败,报格式错误。是因为单元格默认格式有可能是number值,统一用 STRING获取就会异常。
解决方案:
//单元格值获取

String value =cell.getCellTypeEnum().toString().equals("STRING") ?cell.getStringCellValue():String.valueOf(cell.getNume ricCellValue());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/364352.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《昇思25天学习打卡营第12天 | 昇思MindSpore基于MindSpore的GPT2文本摘要》

12天 本节学习了基于MindSpore的GPT2文本摘要。 1.数据集加载与处理 1.1.数据集加载 1.2.数据预处理 2.模型构建 2.1构建GPT2ForSummarization模型 2.2动态学习率 3.模型训练 4.模型推理

javaScript利用indexOf()查找字符串的某个字符出现的位置

1 创建字符串 2 利用indexof()查询字符串的字符 3 利用while循环判断indexOf是否等于-1&#xff0c;不等于-1就打印一次并且索引号1去查下一个字符 //创建字符串var str1234567812311231;var indexstr.indexOf(1);//查询该字符while(index !-1)//indexOf()没有查到会返回-1{…

【linux/shell案例实战】解决Linux和Windows的换行符CRLF和LF问题

目录 一.什么是Linux 和 Windows 的换行符 CRLF 和 LF 二.使用Linux 中命令 dos2unix 和 unix2dos 实现CRLF 和LF的转换 三.使用 windows 中的代码编辑器实现 CRLF 和 LF 的转换&#xff08;Notepad&#xff09; 一.什么是Linux 和 Windows 的换行符 CRLF 和 LF CR是Carria…

探索区块链:颠覆性技术的崛起

目录 一、引言 二、区块链技术概述 三、区块链应用场景 四、区块链面临的挑战 五、区块链的未来展望 六、结语 一、引言 在数字化浪潮的推动下&#xff0c;区块链技术以其独特的去中心化、透明性和不可篡改性等特性&#xff0c;正在逐步改变我们的生活。从金融领域到供应…

vue组件全局注册

描述&#xff1a; vue组件的注册分为局部和全局注册两部分&#xff0c;局部注册相对容易&#xff0c;不做赘述&#xff1b;而不同框架的注册方法又有所不同&#xff0c;下面针对vite框架和vue-cli框架的注册分别进行说明 vue组件全局注册 一、vite框架中全局组件注册二、Vue-cl…

Vue 项目运行时,报错Error: Cannot find module ‘node:path‘

Vue 项目运行时&#xff0c;报错Error: Cannot find module ‘node:path’ internal/modules/cjs/loader.js:883throw err;^Error: Cannot find module node:path Require stack: - D:\nodejs\node_modules\npm\node_modules\node_modules\npm\lib\cli.js - D:\nodejs\node_mo…

C++:enum枚举共用体union

enum枚举 C继承C的枚举用法 (1)典型枚举类型定义&#xff0c;枚举变量定义和使用 (2)枚举类型中的枚举值常量不能和其他外部常量名称冲突&#xff1a; 举例1宏定义&#xff0c;举例2另一个枚举 // 定义一个名为Color的枚举类型 enum Color {RED, // 红色&#xff0c;默认值…

从云原生视角看 AI 原生应用架构的实践

本文核心观点&#xff1a; 基于大模型的 AI 原生应用将越来越多&#xff0c;容器和微服务为代表的云原生技术将加速渗透传统业务。API 是 AI 原生应用的一等公民&#xff0c;并引入了更多流量&#xff0c;催生企业新的生命力和想象空间。AI 原生应用对网关的需求超越了传统的路…

机器人控制系列教程之关节空间运动控制器搭建(1)

机器人位置控制类型 机器人位置控制分为两种类型&#xff1a; 关节空间运动控制—在这种情况下&#xff0c;机器人的位置输入被指定为一组关节角度或位置的向量&#xff0c;这被称为机器人的关节配置&#xff0c;记作q。控制器跟踪一个参考配置&#xff0c;记作 q r e f q_{re…

Windows kubectl终端日志聚合(wsl+ubuntu+cmder+kubetail)

Windows kubectl终端日志聚合 一、kubectl终端日志聚合二、windows安装ubuntu子系统1. 启用wsl支持2. 安装所选的 Linux 分发版 三、ubuntu安装kubetail四、配置cmder五、使用 一、kubectl终端日志聚合 k8s在实际部署时&#xff0c;一般都会采用多pod方式&#xff0c;这种情况下…

MYSQL存储过程的创建

关于存储过程的题目 1、创建存储过程,查看user表中的所有数据 2、创建存储过程avg_order_quantity,返回所有订单的平均工资 3、创建存储过程show_max_bprice,用来查看bookS的单价最贵的价格 4、创建存储过程show_min_bprice,用来查看bookS的单价最低的价格&#xff0c;并将…

【java】【控制台】【javaSE】 初级java家教管理系统控制台命令行程序项目

更多项目点击&#x1f446;&#x1f446;&#x1f446;完整项目成品专栏 【java】【控制台】【javaSE】 初级java家教管理系统控制台命令行程序项目 获取源码方式项目说明&#xff1a;功能点数据库涉及到&#xff1a; 项目文件包含&#xff1a;项目运行环境 &#xff1a;截图其…

【Nginx】源码安装

1.安装地址 Nginx官网&#xff1a;nginx: download 2.下载依赖 //一键安装上面四个依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 3.上传解压编译安装 //解压压缩包tar -xvf nginx-1.26.1.tar.gz //进入nginx cd nginx-1.26.1/ //安装到指定位…

mysql解压版本安装5.7

1. 官网下载好解压版本 我这边5.7版本 https://dev.mysql.com/downloads/file/?id523570 mysql官网 创建 my.ini文件 内容如下 [client] #客户端设置&#xff0c;即客户端默认的连接参数# socket /data/mysqldata/3306/mysql.sock #用于本地连接的socket套接字 # 默…

昇思MindSpore学习笔记5--数据变换Transforms

摘要&#xff1a; 昇思MindSpore的数据变换&#xff0c;包括通用变换Common Transforms、图像变换Vision Transforms、标准化Normalize、文本变换Text Transforms、匿名函数变换Lambda Transforms。 一、数据变换Transforms概念 原始数据需预处理后才能送入神经网络进行训练…

OLMo:真正完全开源的大模型

最近&#xff0c;又有一家机构AI2&#xff08;Allen Institute for AI&#xff09;开源了一个LLM&#xff1a;OLMo&#xff0c;它的英文全称就叫Open Language Model。相比之前开源的大模型&#xff0c;OLMo的独特之处是完全开源&#xff0c;除了训练的模型&#xff0c;OLMo还开…

vmware安装debian11

安装vmware16 下载镜像 https://repo.huaweicloud.com/debian-cd/ https://repo.huaweicloud.com/debian-cd/11.7.0/amd64/iso-dvd/ 安装 安装完成之后重启&#xff0c;输入账号密码进入&#xff0c;安装ssh服务器即可使用

记一次elementui时间线的实现

实现效果 点击展开&#xff0c;每次累加五条数据进行展示 实现思路 起始本质上就是一个分页查询&#xff0c;只不过按新的形式展示&#xff0c;然后也不统计总数&#xff0c;每次只展示固定的5条数据点击加载更多&#xff0c;就展示下一页&#xff0c;页的页数进行1&#xff…

HarmonyOS SDK助力鸿蒙原生应用“易感知、易理解、易操作”

6月21-23日&#xff0c;华为开发者大会&#xff08;HDC 2024&#xff09;盛大开幕。6月23日上午&#xff0c;《HarmonyOS开放能力&#xff0c;使能应用原生易用体验》分论坛成功举办&#xff0c;大会邀请了多位华为技术专家深度解读如何通过根技术、开放能力、场景化控件等亮点…

什么是中断?---STM32篇

目录 一&#xff0c;中断的概念 二&#xff0c;中断的意义 三&#xff0c;中断的优先级 四&#xff0c;中断的嵌套 如果一个高优先级的中断发生&#xff0c;它会立即打断当前正在处理的中断&#xff08;如果其优先级较低&#xff09;&#xff0c;并首先处理这个高优…