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());

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CC1利用链分析

分析版本 Commons Collections 3.1 JDK 8u65 环境配置参考JAVA安全初探(三):CC1链全分析 分析过程 我的Github主页Java反序列化学习同步更新&#xff0c;有简单的利用链图 首先看下CC1利用链的RCE利用点&#xff0c;在接口Transformer 接下来查看此接口的实现类&#xf…

GBJ406-ASEMI无人机专用整流桥GBJ406

编辑&#xff1a;ll GBJ406-ASEMI无人机专用整流桥GBJ406 型号&#xff1a;GBJ406 品牌&#xff1a;ASEMI 封装&#xff1a;GBJ-4 最大重复峰值反向电压&#xff1a;600V 最大正向平均整流电流(Vdss)&#xff1a;4A 功率(Pd)&#xff1a;中小功率 芯片个数&#xff1a;…

【小学期】常用基于Swing的七个静态界面

示例1&#xff1a;基本的带按钮和标签的界面 import javax.swing.*; import java.awt.*;public class SimpleSwingApp1 {public static void main(String[] args) {JFrame frame new JFrame("Simple Swing App 1");frame.setDefaultCloseOperation(JFrame.EXIT_ON_C…

申请免费6个月SSL证书方式和证书特点槽点

当前&#xff0c;HTTPS访问已成为网站标配。随着免费证书平台的不断涌现&#xff0c;Lets Encrypt尤为瞩目&#xff0c;其提供的泛域名和多域名证书申请功能&#xff0c;显著降低了站长和企业的经济负担。从一开始&#xff0c;来此加密就支持通过Lets Encrypt申请免费的域名SSL…

OpenFAST软件中linux-gnu,linux-intel,macos-gnu,vtk,windows-intel文件的作用

在OpenFAST中&#xff0c;5MW_Land_DLL_WTurb目录下的这五个文件夹分别有不同的用途&#xff0c;主要是为了支持不同操作系统和平台的编译和仿真工作。以下是每个文件夹的总结及其作用&#xff1a; linux-gnu 作用&#xff1a;包含用于GNU编译器套件&#xff08;GCC&#xff09…

【高性能服务器】单进程服务器

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 ​ 单进程服务器 …

基于Java的地方废物回收机构管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;Java技术&#xff0c;MIS的总体思想&#xff0c;MySQL数据库 工具&#xff1a;Eclipse&#xff0c;…

落石滑坡监测报警系统:创新保障高速公路安全

​ ​​在现代交通建设中&#xff0c;高速公路的安全性和稳定性至关重要。特别是易发生落石区域&#xff0c;如何有效预防和应对落石滑坡带来的事故成为了一项关键性挑战。为此&#xff0c;落石滑坡监测报警系统应运而生&#xff0c;它通过先进的技术手段&#xff0c;为高速…

计算机网络微课堂(湖科大教书匠)TCP部分

计算机网络微课堂&#xff08;湖科大教书匠&#xff09;TCP部分 【计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;】 TCP的流量控制 一般来说&#xff0c;我们希望数据传输得更快一些。但如果发送方把数据发送得过快&#xff0c;接收方就可能来不及接收&#…

win11 (将星x17promax) 安装WSL 子系统

最初只是想着在win11系统下挂载ext4盘符&#xff0c;方便使用。 目录 0. 简介1.安装WSL子系统1.1 环境确认1.1.1 虚拟化设置1.1.2 系统设置1.1.3 开启开发者模式&#xff08;此项有必要&#xff1f;&#xff09;1.1.4 安装WSL子系统 2.WSL操作指令2.0 WSL相关命令2.1 WSL重置2.…

pytorch神经网络训练(VGG-19)

VGG-19 导包 import torchimport torch.nn as nnimport torch.optim as optimimport torchvisionfrom torchvision import datasets, transformsfrom torch.utils.data import DataLoaderimport matplotlib.pyplot as plt 数据预处理和增强 transform transforms.Compose(…

java的序列化和反序列化

一、概念 序列化是将对象的常态存储到特定的存储介质中的过程。 反序列化是将特定的存储介质中的数据重新构建对象的过程。 问题 为每个对象属性——编写读写代码&#xff0c;过程很繁琐且非常容易出错&#xff0c;如何解决&#xff1f; 二、使用Object Output Stream类实现…

C++:enum枚举共用体union

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

golang跨平台GUI框架fyne介绍与使用详解,开放案例

golang跨平台GUI框架fyne介绍与使用详解 Fyne 是一个使用 Go 编写的易于使用的 UI 工具包和应用程序 API。 它旨在构建使用单一代码库在桌面和移动设备上运行的应用程序。 通过批量调用身份证实名和三网手机实名和银行卡核验等接口&#xff0c;完成fyne框架的基本使用介绍 主要…

AES加密算法及AES-CMAC原理白话版系统解析

本文框架 前言1. AES加密理论1.1 不同AES算法区别1.2 加密过程介绍1.2.1 加密模式和填充方案选择1.2.2 密钥扩展1.2.3分组处理1.2.4多轮加密1.2.4.1字节替换1.2.4.2行移位1.2.4.3列混淆1.2.4.4轮密钥加1.3 加密模式1.3.1ECB模式1.3.2CBC模式1.3.3CTR模式1.3.4CFB模式1.3.5 OFB模…

技术周总结2024.06.17~06.23(Doris数据库)

文章目录 一、06.18 周二1.1&#xff09; 问题01&#xff1a; doris数据表写入使用 stream load好还是 inser into好 一、06.18 周二 1.1&#xff09; 问题01&#xff1a; doris数据表写入使用 stream load好还是 inser into好 对于Doris数据表的写入操作&#xff0c;通常推荐…

动手学深度学习(Pytorch版)代码实践 -计算机视觉-46语义分割和数据集

46语义分割和数据集 # 图像分割和实例分割 """ 图像分割将图像划分为若干组成区域&#xff0c;这类问题的方法通常利用图像中像素之间的相关性。 它在训练时不需要有关图像像素的标签信息&#xff0c;在预测时也无法保证分割出的区域具有我们希望得到的语义。 图…

PDF处理篇:如何调整 PDF 图像的大小

将视觉效果无缝集成到 PDF 中的能力使它们成为强大的通信工具。然而&#xff0c;笨拙的图像大小会迅速扰乱文档的流程&#xff0c;阻碍清晰度和专业性。幸运的是&#xff0c;GeekerPDF 和Adobe Acrobat等流行的应用程序提供了用户友好的解决方案来应对这一挑战。这个全面的指南…

LabVIEW项目外协时选择公司与个人兼职的比较

​在选择LabVIEW项目外协合作伙伴时&#xff0c;外协公司和个人兼职各有优劣。个人兼职成本较低且灵活&#xff0c;但在可靠性、技术覆盖面、资源和风险管理上存在不足。而外协公司拥有专业团队、丰富资源、完善的项目管理和风险控制&#xff0c;尽管成本较高&#xff0c;但能提…

30 哈希的应用

位图 概念 题目 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何判断一个数是否在这40亿个整数中 1.遍历&#xff0c;时间复杂度O(N) 2.二分查找&#xff0c;需要先排序&#xff0c;排序(N*logN)&#xff0c;二分查找&#xff0c;logN。…