当前位置: 首页 > news >正文

SpringBoot + Vue实现批量导入导出功能的标准方案

用固定资产管理系统中的资产模块进行示范批量导入导出功能

下面我将提供一个完整的SpringBoot + Vue实现的固定资产批量导入导出功能,这个项目大家也可以进行看我的资产管理系统

项目:https://blog.csdn.net/qq_46108094

在这里插入图片描述

下面开始项目实操

后端实现 (Spring Boot)

1. 实体类 (Assets.java)

package com.example.demo.entity;import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;@Data
@TableName("assets")
public class Assets {@TableId(type = IdType.AUTO)private Long id;private String assetCode;      // 资产编码private String assetName;      // 资产名称private String assetType;      // 资产类型private String specification;  // 规格型号private BigDecimal unitPrice;  // 单价private Integer quantity;      // 数量private BigDecimal totalValue; // 总价值private String department;     // 使用部门private String user;           // 使用人private String location;       // 存放地点private String status;         // 状态:在用、闲置、报废等@TableField(fill = FieldFill.INSERT)private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;
}

2. 控制器 (AssetsController.java)

package com.example.demo.controller;import com.example.demo.entity.Assets;
import com.example.demo.service.AssetsService;
import com.example.demo.common.Result;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;@RestController
@RequestMapping("/assets")
public class AssetsController {@Resourceprivate AssetsService assetsService;/*** 导出所有资产数据*/@GetMapping("/export")public void export(HttpServletResponse response) throws Exception {// 查询所有数据List<Assets> list = assetsService.list();// 在内存操作,写出到浏览器ExcelWriter writer = ExcelUtil.getWriter(true);// 自定义标题别名writer.addHeaderAlias("assetCode", "资产编码");writer.addHeaderAlias("assetName", "资产名称");writer.addHeaderAlias("assetType", "资产类型");writer.addHeaderAlias("specification", "规格型号");writer.addHeaderAlias("unitPrice", "单价");writer.addHeaderAlias("quantity", "数量");writer.addHeaderAlias("totalValue", "总价值");writer.addHeaderAlias("department", "使用部门");writer.addHeaderAlias("user", "使用人");writer.addHeaderAlias("location", "存放地点");writer.addHeaderAlias("status", "状态");writer.addHeaderAlias("createTime", "创建时间");// 一次性写出list内的对象到excel,使用默认样式,强制输出标题writer.write(list, true);// 设置浏览器响应的格式response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");String fileName = URLEncoder.encode("固定资产列表", "UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");ServletOutputStream out = response.getOutputStream();writer.flush(out, true);out.close();writer.close();}/*** 导入Excel数据*/@PostMapping("/import")public Result importData(MultipartFile file) throws Exception {InputStream inputStream = file.getInputStream();ExcelReader reader = ExcelUtil.getReader(inputStream);// 通过JavaBean的方式读取Excel内的对象,要求表头必须是英文,与JavaBean的属性对应List<Assets> list = reader.readAll(Assets.class);if (CollUtil.isEmpty(list)) {return Result.error("Excel文件中没有数据");}// 批量保存boolean result = assetsService.saveBatch(list);return result ? Result.success("导入成功") : Result.error("导入失败");}/*** 下载导入模板*/@GetMapping("/template")public void downloadTemplate(HttpServletResponse response) throws Exception {// 创建空数据示例Assets template = new Assets();template.setAssetCode("ASSET-001");template.setAssetName("示例资产");template.setAssetType("电子设备");template.setSpecification("标准型号");template.setUnitPrice(new BigDecimal("1000.00"));template.setQuantity(1);template.setTotalValue(new BigDecimal("1000.00"));template.setDepartment("行政部");template.setUser("张三");template.setLocation("A区101室");template.setStatus("在用");List<Assets> list = CollUtil.newArrayList(template);// 在内存操作,写出到浏览器ExcelWriter writer = ExcelUtil.getWriter(true);// 自定义标题别名writer.addHeaderAlias("assetCode", "资产编码");writer.addHeaderAlias("assetName", "资产名称");writer.addHeaderAlias("assetType", "资产类型");writer.addHeaderAlias("specification", "规格型号");writer.addHeaderAlias("unitPrice", "单价");writer.addHeaderAlias("quantity", "数量");writer.addHeaderAlias("totalValue", "总价值");writer.addHeaderAlias("department", "使用部门");writer.addHeaderAlias("user", "使用人");writer.addHeaderAlias("location", "存放地点");writer.addHeaderAlias("status", "状态");// 只导出别名字段writer.setOnlyAlias(true);// 一次性写出list内的对象到excel,使用默认样式,强制输出标题writer.write(list, true);// 设置浏览器响应的格式response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");String fileName = URLEncoder.encode("固定资产导入模板", "UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");ServletOutputStream out = response.getOutputStream();writer.flush(out, true);out.close();writer.close();}
}

3. 服务接口 (AssetsService.java)

package com.example.demo.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.Assets;
import java.util.List;public interface AssetsService extends IService<Assets> {// 可以添加自定义方法
}

4. 服务实现 (AssetsServiceImpl.java)

package com.example.demo.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.Assets;
import com.example.demo.mapper.AssetsMapper;
import com.example.demo.service.AssetsService;
import org.springframework.stereotype.Service;@Service
public class AssetsServiceImpl extends ServiceImpl<AssetsMapper, Assets> implements AssetsService {// 实现自定义方法
}

5. 统一返回结果类 (Result.java)

package com.example.demo.common;import lombok.Data;
import java.io.Serializable;@Data
public class Result implements Serializable {private int code;private String msg;private Object data;public static Result success() {Result result = new Result();result.setCode(200);result.setMsg("成功");return result;}public static Result success(Object data) {Result result = new Result();result.setCode(200);result.setMsg("成功");result.setData(data);return result;}public static Result success(String msg, Object data) {Result result = new Result();result.setCode(200);result.setMsg(msg);result.setData(data);return result;}public static Result error() {Result result = new Result();result.setCode(500);result.setMsg("失败");return result;}public static Result error(String msg) {Result result = new Result();result.setCode(500);result.setMsg(msg);return result;}public static Result error(int code, String msg) {Result result = new Result();result.setCode(code);result.setMsg(msg);return result;}
}

前端实现 (Vue + Element UI)

1. 固定资产页面 (Assets.vue)

<template><div class="app-container"><!-- 搜索和操作区域 --><div class="filter-container"><el-input v-model="listQuery.assetName" placeholder="资产名称" style="width: 200px;" class="filter-item" /><el-select v-model="listQuery.department" placeholder="使用部门" clearable style="width: 200px" class="filter-item"><el-option v-for="item in departmentOptions" :key="item" :label="item" :value="item" /></el-select><el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button><el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">新增</el-button><el-button type="success" plain @click="exportData">批量导出</el-button><el-button type="info" plain @click="handleImport">批量导入</el-button></div><!-- 数据表格 --><el-table:key="tableKey"v-loading="listLoading":data="list"borderfithighlight-current-rowstyle="width: 100%;"><el-table-column label="ID" prop="id" align="center" width="80"><template slot-scope="{row}"><span>{{ row.id }}</span></template></el-table-column><el-table-column label="资产编码" width="120" align="center"><template slot-scope="{row}"><span>{{ row.assetCode }}</span></template></el-table-column><el-table-column label="资产名称" min-width="150"><template slot-scope="{row}"><span>{{ row.assetName }}</span></template></el-table-column><el-table-column label="资产类型" width="120" align="center"><template slot-scope="{row}"><span>{{ row.assetType }}</span></template></el-table-column><el-table-column label="规格型号" width="120" align="center"><template slot-scope="{row}"><span>{{ row.specification }}</span></template></el-table-column><el-table-column label="单价" width="100" align="center"><template slot-scope="{row}"><span>¥{{ row.unitPrice }}</span></template></el-table-column><el-table-column label="数量" width="80" align="center"><template slot-scope="{row}"><span>{{ row.quantity }}</span></template></el-table-column><el-table-column label="总价值" width="120" align="center"><template slot-scope="{row}"><span>¥{{ row.totalValue }}</span></template></el-table-column><el-table-column label="使用部门" width="120" align="center"><template slot-scope="{row}"><span>{{ row.department }}</span></template></el-table-column><el-table-column label="使用人" width="100" align="center"><template slot-scope="{row}"><span>{{ row.user }}</span></template></el-table-column><el-table-column label="存放地点" width="120" align="center"><template slot-scope="{row}"><span>{{ row.location }}</span></template></el-table-column><el-table-column label="状态" width="100" align="center"><template slot-scope="{row}"><el-tag :type="row.status | statusFilter">{{ row.status }}</el-tag></template></el-table-column><el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width"><template slot-scope="{row,$index}"><el-button type="primary" size="mini" @click="handleUpdate(row)">编辑</el-button><el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="handleDelete(row,$index)">删除</el-button></template></el-table-column></el-table><pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" /><!-- 批量导入对话框 --><el-dialog title="批量导入资产" :visible.sync="importVisible" width="40%" :close-on-click-modal="false" destroy-on-close><div style="margin-bottom: 20px;"><el-alerttitle="导入说明"type="info":closable="false"show-icon><div slot="default"><p>1. 请先<a href="javascript:void(0);" @click="downloadTemplate" style="color: #409EFF; text-decoration: underline;">下载模板</a>,按照模板格式填写数据</p><p>2. 仅支持xlsx格式文件,且文件大小不超过10MB</p><p>3. 每次最多导入1000条数据</p></div></el-alert></div><el-uploadclass="upload-demo"dragaction="#":auto-upload="false":on-change="handleUploadChange":before-upload="beforeUpload":file-list="fileList":limit="1"accept=".xlsx,.xls"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip" slot="tip">只能上传xlsx/xls文件,且不超过10MB</div></el-upload><div slot="footer" class="dialog-footer"><el-button @click="importVisible = false">取 消</el-button><el-button type="primary" :loading="importLoading" @click="submitImport">确 定</el-button></div></el-dialog></div>
</template><script>
import { fetchList, importAssets } from '@/api/assets'
import Pagination from '@/components/Pagination'export default {name: 'AssetsList',components: { Pagination },filters: {statusFilter(status) {const statusMap = {'在用': 'success','闲置': 'info','报废': 'danger'}return statusMap[status]}},data() {return {tableKey: 0,list: null,total: 0,listLoading: true,listQuery: {page: 1,limit: 20,assetName: undefined,department: undefined},departmentOptions: ['行政部', '财务部', '技术部', '市场部', '人事部'],importVisible: false,importLoading: false,fileList: [],uploadFile: null}},created() {this.getList()},methods: {getList() {this.listLoading = truefetchList(this.listQuery).then(response => {this.list = response.data.itemsthis.total = response.data.totalthis.listLoading = false})},handleFilter() {this.listQuery.page = 1this.getList()},handleCreate() {// 新增资产逻辑},handleUpdate(row) {// 编辑资产逻辑},handleDelete(row, index) {// 删除资产逻辑},// 导出数据exportData() {window.open(`${process.env.VUE_APP_BASE_API}/assets/export`)},// 打开导入对话框handleImport() {this.importVisible = truethis.fileList = []},// 下载模板downloadTemplate() {window.open(`${process.env.VUE_APP_BASE_API}/assets/template`)},// 上传文件前的校验beforeUpload(file) {const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.type === 'application/vnd.ms-excel'const isLt10M = file.size / 1024 / 1024 < 10if (!isExcel) {this.$message.error('只能上传Excel文件!')}if (!isLt10M) {this.$message.error('上传文件大小不能超过10MB!')}return isExcel && isLt10M},// 文件改变时的回调handleUploadChange(file, fileList) {const isExcel = file.raw.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.raw.type === 'application/vnd.ms-excel'if (!isExcel) {this.$message.error('只能上传Excel文件!')this.fileList = []return false}this.uploadFile = file.raw},// 提交导入submitImport() {if (!this.uploadFile) {this.$message.warning('请先选择文件')return}this.importLoading = trueconst formData = new FormData()formData.append('file', this.uploadFile)importAssets(formData).then(response => {this.importLoading = falsethis.$message({message: response.msg || '导入成功',type: 'success'})this.importVisible = falsethis.getList() // 刷新列表}).catch(() => {this.importLoading = false})}}
}
</script><style scoped>
.filter-container {margin-bottom: 20px;
}
.upload-demo {text-align: center;
}
</style>

2. API接口 (assets.js)

import request from '@/utils/request'export function fetchList(query) {return request({url: '/assets/list',method: 'get',params: query})
}export function importAssets(data) {return request({url: '/assets/import',method: 'post',data,headers: {'Content-Type': 'multipart/form-data'}})
}

使用说明

1. 后端依赖

在pom.xml中添加以下依赖:

<!-- Hutool工具包 -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.17</version>
</dependency><!-- MyBatis Plus -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3.4</version>
</dependency><!-- Lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

2. 功能特点

  1. 批量导出:将数据库中的固定资产数据导出为Excel文件
  2. 批量导入:通过Excel模板批量导入固定资产数据
  3. 模板下载:提供标准导入模板,确保数据格式一致性
  4. 数据校验:前端和后端都对上传文件进行校验
  5. 用户体验:提供清晰的操作指引和反馈

3. 使用流程

  1. 点击"批量导入"按钮打开导入对话框
  2. 下载导入模板并按照格式填写数据
  3. 将填写好的Excel文件拖拽或点击上传
  4. 点击确定开始导入,系统会显示导入结果
  5. 导入成功后,页面数据自动刷新

这个实现方案提供了完整的固定资产批量导入导出功能,包含了前后端代码
大家可以通过这个进行修改然后直接集成到自己的SpringBoot + Vue项目中

http://www.dtcms.com/a/343217.html

相关文章:

  • k8sday13数据存储(1.5/2)
  • 基于Matlab多技术融合的红外图像增强方法研究
  • C++---滑动窗口平滑数据
  • 瑞派亚宠展专访 | 以数智化重塑就医体验,共筑宠物健康新生态
  • 区块链存证操作
  • echarts关系图(Vue3)节点背景图连线设置
  • 2025.7.19卡码刷题-回溯算法-组合
  • IOS购买订阅通知信息解析说明Java
  • 设计模式3-模板方法模式
  • 爬虫基础学习-项目实践:每次请求,跟换不同的user-agent
  • 茶饮业内卷破局,从人力管理入手
  • iOS 手势与控件事件冲突解决清单
  • 一本通1342:【例4-1】最短路径问题
  • 【Docker基础】Docker-Compose核心配置文件深度解析:从YAML语法到高级配置
  • 一个状态机如何启动/停止另一个状态机
  • C++ 常见的排序算法详解
  • CPP学习之priority_queue的使用及模拟实现
  • 3维模型导入到3Dmax中的修改色彩简单用法----第二讲
  • Kotlin 中适用集合数据的高阶函数(forEach、map、filter、groudBy、fold、sortedBy)
  • AI客服系统架构与实现:大模型、知识库与多轮对话的最佳实践
  • 蛋白质分析常用数据库2
  • QT开发---QT布局与QSS样式设置
  • 网络打印机自动化部署脚本
  • 工业机器人远程监控与运维物联网解决方案
  • 精准评估新纪元:AI得贤招聘官AI面试智能体6.3,重新定义AI面试
  • 赛灵思ZYNQ官方文档UG585自学翻译笔记与代码示例:Quad-SPl Flash 闪存控制器
  • 深度剖析字节跳动VeOmni框架
  • MySQL索引优化之索引条件字段类型不同
  • POI读和写
  • C2ComponentStore