AI智慧社区--Excel表的导入导出

Excel表导入导出的环境配置

1.导入依赖

 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>${easypoi.version}</version></dependency>

2.配置Excel的导入导出以及文件上传的路径

upload:face: D:/community/upload/face/excel: D:/community/upload/excel/urlPrefix: http://localhost:8181/

3.配置文件的导出以及上传的本地映射路径

package com.southwind.configuration;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {@Value("${upload.face}")String face;@Value("${upload.excel}")String excel;@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {/*** 假设前端要访问的faceUrl为  http://localhost:8181/community/upload/face/+生成的文件名* 会被映射为 D:/community/upload/face/+生成的文件名*/registry.addResourceHandler("/community/upload/face/**").addResourceLocations("file:"+face);registry.addResourceHandler("/community/upload/excel/**").addResourceLocations("file:"+excel);}
}

一、Excel表的导出

@GetMapping("/exportExcel")public Result exportExcel(PersonListForm personListForm){//获取用户的列表,拿到要导出的数据PageVO pageVO = this.personService.personList(personListForm);//只需要list数据,进行导出List list = pageVO.getList();//path:D:/community/upload/excel/String path = excel;//导入文件path = ExcelUtil.ExpPersonInfo(list,path);return Result.ok().put("data", path);}
package com.southwind.util;import com.southwind.vo.PersonVO;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.BorderStyle;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;public class ExcelUtil {public static String ExpPersonInfo(List<PersonVO> info, String path){// // 声明 POIFSFileSystem 对象,用于处理 Excel 文件的输入流POIFSFileSystem fs = null;//从第二行开始写int headRow = 2;//目标文件名称String descfile = null;try {//复制文件//文件路径:D:/community/upload/excel/personInfo.xlsString srcfile = path + "personInfo.xls";//编辑导入文件的文件名Date date = new Date();SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");String dateStr = format.format(date);descfile = dateStr + ".xls";try {///文件的输入流,用于读取模板文件FileInputStream fis = new FileInputStream(srcfile);//文件的输出流,用于写入新文件FileOutputStream fos = new FileOutputStream(path+descfile);byte [] buffer = new byte[1024*4];//如果缓冲区中还有内容,继续写while(fis.read(buffer) != -1){fos.write(buffer);}fis.close();fos.close();} catch (Exception e) {e.printStackTrace();}//写数据fs = new POIFSFileSystem(new FileInputStream(path + descfile));FileOutputStream fos = new FileOutputStream(path + descfile);//创建 HSSFWorkbook 对象,用于操作 Excel 文件HSSFWorkbook wb1 = new HSSFWorkbook(fs);//获取第一个工作表HSSFSheet sheet = wb1.getSheetAt(0);//获取人员信息列表的大小int size = info.size();int col = 0;//创建一个单元格样式对象HSSFCellStyle style = wb1.createCellStyle();style.setBorderLeft(BorderStyle.THIN);style.setBorderRight(BorderStyle.THIN);style.setBorderTop(BorderStyle.THIN);style.setBorderBottom(BorderStyle.THIN);for(int i = 0;i < size;i++){col = 0;PersonVO p = info.get(i);HSSFRow row = sheet.createRow(i+headRow);HSSFCell cell = null;//写入居民IDcell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getPersonId());//写入小区名称cell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getCommunityName());//居住的楼栋cell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getTermName());//房号cell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getHouseNo());//用户名cell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getUserName());//性别cell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getSex());//手机号cell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getMobile());//居住类型cell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getPersonType());//备注cell = row.createCell(col++);cell.setCellStyle(style);cell.setCellValue(p.getRemark());}wb1.write(fos);fos.close();} catch (Exception e) {e.printStackTrace();}return descfile;}}

Excel表的导出流程

1. 控制器层接收请求

在控制器中,定义了一个 @GetMapping 注解的方法 exportExcel,用于处理 /exportExcel 的 GET 请求,接收一个 PersonListForm 对象作为参数,具体步骤如下:

  • 获取人员列表数据:调用 personServicepersonList 方法,传入 personListForm 参数,获取包含人员信息的分页对象 PageVO

  • 提取数据列表:从 PageVO 对象中提取出人员信息列表 list,该列表将用于后续的 Excel 导出。

  • 指定文件保存路径:定义一个字符串 path,用于指定 Excel 文件的保存路径,这里的 excel 变量应该是在配置文件中定义的路径字符串。

  • 调用导出工具类方法:调用 ExcelUtil 工具类的 ExpPersonInfo 方法,将人员信息列表 list 和保存路径 path 作为参数传入,执行具体的导出操作。

  • 返回结果:将导出文件的路径封装在 Result 对象中返回给客户端。

2. 工具类实现 Excel 导出

ExcelUtil 工具类中的 ExpPersonInfo 方法实现了具体的 Excel 导出逻辑,步骤如下:

2.1 初始化变量
  • 声明 POIFSFileSystem 对象 fs,用于处理 Excel 文件的输入流。
  • 定义 headRow 变量,指定数据从 Excel 文件的第二行开始写入。
  • 定义 descfile 变量,用于存储导出文件的名称。
2.2 复制模板文件
  • 指定模板文件路径:拼接模板文件的完整路径 srcfile,模板文件名为 personInfo.xls
  • 生成导出文件名:使用当前时间生成一个唯一的文件名 descfile,格式为 yyyyMMddHHmmss.xls
  • 复制文件:通过 FileInputStream 读取模板文件,通过 FileOutputStream 将模板文件内容复制到新文件中。
2.3 写入数据
  • 创建工作簿和工作表:使用 POIFSFileSystem 读取新文件,创建 HSSFWorkbook 对象 wb1 来操作 Excel 文件,并获取第一个工作表 sheet
  • 获取数据列表大小:获取人员信息列表 info 的大小,用于循环写入数据。
  • 创建单元格样式:创建一个 HSSFCellStyle 对象 style,设置单元格的边框样式为细边框。
  • 循环写入数据:遍历人员信息列表 info,为每一条记录创建一行 HSSFRow,并在该行中创建多个单元格 HSSFCell,将人员信息的各个字段(如居民 ID、小区名称、房号等)写入对应的单元格中,并设置单元格的样式。
2.4 保存文件
  • 使用 HSSFWorkbookwrite 方法将数据写入到文件输出流 fos 中。
  • 关闭文件输出流 fos
2.5 返回文件名

返回导出文件的名称 descfile
同时会将路径映射为本地路径

二、Excel表的导入

 @LogAnnotation("导入数据")@PostMapping("/parsefile/{fileName}")public Result parsefile(@PathVariable("fileName") String fileName,HttpSession session){//获取用户信息User user = (User) session.getAttribute("user");//用于处理输入流的POIFSFileSystem fs = null;//用于处理Excel的HSSFWorkbook wb = null;try {//basePath:D:/community/upload/excel/用户名String basePath = excel + fileName;fs = new POIFSFileSystem(new FileInputStream(basePath));wb = new HSSFWorkbook(fs);} catch (Exception e) {e.printStackTrace();}HSSFSheet sheet = wb.getSheetAt(0);Object[][] data = null;int r = sheet.getLastRowNum()+1;int c = sheet.getRow(0).getLastCellNum();int headRow = 2;data = new Object[r - headRow][c];for (int i = headRow; i < r; i++) {HSSFRow row = sheet.getRow(i);for (int j = 0; j < c; j++) {HSSFCell cell = null;try {cell = row.getCell(j);try {cell = row.getCell(j);DataFormatter dataFormater = new DataFormatter();String a = dataFormater.formatCellValue(cell);data[i - headRow][j] = a;} catch (Exception e) {data[i-headRow][j] = "";if(j==0){try {double d = cell.getNumericCellValue();data[i - headRow][j] = (int)d + "";}catch(Exception ex){data[i-headRow][j] = "";}}}} catch (Exception e) {System.out.println("i="+i+";j="+j+":"+e.getMessage());}}}int row = data.length;int col = 0;String errinfo = "";headRow = 3;String[] stitle={"ID","小区名称","所属楼栋","房号","姓名","性别","手机号码","居住性质","状态","备注"};errinfo = "";for (int i = 0; i < row; i++) {Person single = new Person();single.setPersonId(0);single.setState(1);single.setFaceUrl("");try {col=1;String communityName = data[i][col++].toString();QueryWrapper<Community> queryWrapper = new QueryWrapper<>();queryWrapper.eq("community_name", communityName);Community community = this.communityService.getOne(queryWrapper);if( community == null){errinfo += "Excel文件第" + (i + headRow) + "行小区名称不存在!";return Result.ok().put("status", "fail").put("data", errinfo);}single.setCommunityId(community.getCommunityId());single.setTermName(data[i][col++].toString());single.setHouseNo(data[i][col++].toString());single.setUserName(data[i][col++].toString());single.setSex(data[i][col++].toString());single.setMobile(data[i][col++].toString());single.setPersonType(data[i][col++].toString());single.setRemark(data[i][col++].toString());single.setCreater(user.getUsername());this.personService.save(single);} catch (Exception e) {e.printStackTrace();}}return Result.ok().put("status", "success").put("data","数据导入完成!");}

Excel表的导入流程

1. 接收请求并获取用户信息

  • 请求映射:使用 @PostMapping("/parsefile/{fileName}") 注解,表明该方法处理 /parsefile/{fileName} 路径的 POST 请求,{fileName} 作为路径变量传入。
  • 获取用户信息:从 HttpSession 中获取当前登录用户的信息,存储在 User 对象 user 中,后续用于记录数据的创建者。

2. 读取 Excel 文件

  • 文件路径拼接:将全局变量 excel 和传入的文件名 fileName 拼接成完整的文件路径 basePath
  • 文件读取:使用 POIFSFileSystemHSSFWorkbook 读取 Excel 文件。如果读取过程中出现异常,会打印异常堆栈信息。

3. 解析 Excel 数据到二维数组

  • 获取工作表:从 HSSFWorkbook 中获取第一个工作表 sheet
  • 计算行列数:获取工作表的最后一行索引 r 和第一行的最后一个单元格索引 c,用于确定数据的范围。
  • 数据初始化:由于数据从第三行(索引为 2)开始,所以 headRow 设为 2,创建一个二维数组 data 用于存储解析后的数据。
  • 遍历单元格:使用双重循环遍历工作表中的每一个单元格,从第三行开始。对于每个单元格,使用 DataFormatter 格式化其值并存储到 data 数组中。如果单元格为空或出现异常,将该位置的值设为空字符串。对于第一列(索引为 0),如果单元格是数值类型,将其转换为整数后再转换为字符串存储。

4. 处理解析后的数据并保存到数据库

  • 数据遍历:遍历 data 数组中的每一行数据。
  • 对象初始化:创建一个 Person 对象 single,并初始化一些默认值,如 personId 设为 0,state 设为 1,faceUrl 设为空字符串。
  • 小区名称验证:从 data 数组中获取小区名称,使用 QueryWrapper 查询数据库中是否存在该小区。如果不存在,将错误信息添加到 errinfo 中,并返回失败结果。
  • 数据赋值:如果小区名称验证通过,将解析后的数据依次设置到 single 对象中,包括小区 ID、所属楼栋、房号、姓名、性别、手机号码、居住性质、备注等。同时,将创建者设置为当前登录用户的用户名。
  • 数据保存:调用 personServicesave 方法将 single 对象保存到数据库中。如果保存过程中出现异常,会打印异常堆栈信息。

5. 返回结果

  • 如果在数据处理过程中没有出现小区名称不存在的错误,最后返回成功结果,表明数据导入成功。

在这里插入图片描述

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

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

相关文章

【C++】B2122 单词翻转

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 &#x1f4af;一、我的做法代码实现&#xff1a;代码解析思路分析 &#x1f4af;二、老师的第一种做法代码实现&a…

【流媒体】搭建流媒体服务器

搭建Windows Nginx服务器 搭建 下载nginx工具包解压至本地&#xff0c;并在cmd窗口中切换至nginx所在的本地目录修改 conf/nginx.conf 文件&#xff0c;更改其端口号 server中的 listen的端口号从 80改为 8080&#xff0c;因为80经常被其他服务占用&#xff0c;导致无法打开 …

编程AI深度实战:给vim装上AI

系列文章&#xff1a; 编程AI深度实战&#xff1a;私有模型deep seek r1&#xff0c;必会ollama-CSDN博客 编程AI深度实战&#xff1a;自己的AI&#xff0c;必会LangChain-CSDN博客 编程AI深度实战&#xff1a;给vim装上AI-CSDN博客 编程AI深度实战&#xff1a;火的编程AI&…

MySQL锁详解

MySQL锁详解 数据库的锁机制锁的分类行级锁与表级锁行级锁之共享锁与排他锁乐观锁与悲观锁悲观锁乐观锁 Innodb存储引擎的锁机制行级锁与表级锁的使用区分三种行锁的算法死锁的问题多版本并发控制MVCC 数据库的锁机制 什么是锁&#xff1f;锁是一种保障数据的机制 为何要用锁…

100 ,【8】 buuctf web [蓝帽杯 2021]One Pointer PHP(别看)

进入靶场 没提示&#xff0c;去看源代码。 user.php <?php // 定义一个名为 User 的类&#xff0c;该类可用于表示用户相关信息或执行与用户有关的操作 class User{// 声明一个公共属性 $count&#xff0c;可在类的内部和外部直接访问// 这个属性可能用于记录与用户相关…

【leetcode练习·二叉树拓展】归并排序详解及应用

本文参考labuladong算法笔记[拓展&#xff1a;归并排序详解及应用 | labuladong 的算法笔记] “归并排序就是二叉树的后序遍历”——labuladong 就说归并排序吧&#xff0c;如果给你看代码&#xff0c;让你脑补一下归并排序的过程&#xff0c;你脑子里会出现什么场景&#xff…

解决PyG安装中torch-sparse安装失败问题:详细指南

1 问题描述 最近在学习GNN&#xff0c;需要使用PyTorch Geometric&#xff08;PyG&#xff09;库。在安装PyG的过程中&#xff0c;遇到了torch-sparse安装失败的问题&#xff0c;错误提示为&#xff1a; ERROR: Failed building wheel for torch-sparse本文将详细记录问题的解…

四、GPIO中断实现按键功能

4.1 GPIO简介 输入输出&#xff08;I/O&#xff09;是一个非常重要的概念。I/O泛指所有类型的输入输出端口&#xff0c;包括单向的端口如逻辑门电路的输入输出管脚和双向的GPIO端口。而GPIO&#xff08;General-Purpose Input/Output&#xff09;则是一个常见的术语&#xff0c…

分析哲学:从 语言解剖到 思想澄清的哲学探险

分析哲学&#xff1a;从 语言解剖 到 思想澄清 的哲学探险 第一节&#xff1a;分析哲学的基本概念与公式解释 【通俗讲解&#xff0c;打比方来讲解&#xff01;】 分析哲学&#xff0c;就像一位 “语言侦探”&#xff0c;专注于 “解剖语言”&#xff0c;揭示我们日常使用的语…

XCCL、NCCL、HCCL通信库

XCCL提供的基本能力 XCCL提供的基本能力 不同的XCCL 针对不同的网络拓扑&#xff0c;实现的是不同的优化算法的&#xff08;不同CCL库最大的区别就是这&#xff09; 不同CCL库还会根据自己的硬件、系统&#xff0c;在底层上面对一些相对应的改动&#xff1b; 但是对上的API接口…

【数据结构篇】时间复杂度

一.数据结构前言 1.1 数据结构的概念 数据结构(Data Structure)是计算机存储、组织数据的⽅式&#xff0c;指相互之间存在⼀种或多种特定关系的数 据元素的集合。没有⼀种单⼀的数据结构对所有⽤途都有⽤&#xff0c;所以我们要学各式各样的数据结构&#xff0c; 如&#xff1a…

700. 二叉搜索树中的搜索

二叉搜索树中的搜索 已解答 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 示例 1: 输入&#xff1a;root [4,2,7,1,3], v…

Spring Cloud工程搭建

目录 工程搭建 搭建父子工程 创建父工程 Spring Cloud版本 创建子项目-订单服务 声明项⽬依赖 和 项⽬构建插件 创建子项目-商品服务 声明项⽬依赖 和 项⽬构建插件 工程搭建 因为拆分成了微服务&#xff0c;所以要拆分出多个项目&#xff0c;但是IDEA只能一个窗口有一…

Rust中使用ORM框架diesel报错问题

1 起初环境没有问题&#xff1a;在Rust开发的时候起初使用的是mingw64平台加stable-x86_64-pc-windows-gnu编译链&#xff0c;当使用到diesel时会报错&#xff0c;如下&#xff1a; x86_64-w64-mingw32/bin/ld.exe: cannot find -lmysql具体信息很长这是主要信息是rust找不到链…

【C++】P1765 手机

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;问题描述题目内容示例&#xff1a; 键盘布局 &#x1f4af;我的做法思路问题与优化我的代码实现分析与问题 &#x1f4af;老师的做法思路老师的代码实现分析优点 &#x1f…

本地快速部署DeepSeek-R1模型——2025新年贺岁

一晃年初六了&#xff0c;春节长假余额马上归零了。今天下午在我的电脑上成功部署了DeepSeek-R1模型&#xff0c;抽个时间和大家简单分享一下过程&#xff1a; 概述 DeepSeek模型 是一家由中国知名量化私募巨头幻方量化创立的人工智能公司&#xff0c;致力于开发高效、高性能…

3 卷积神经网络CNN

1 Image Classification (Neuron Version) – 1.1 Observation 1 1.2 Observation 2 如果不同的receptive field需要相同功能的neuron&#xff0c;可以使这些neuron共享参数 1.3 Benefit of Convolutional Layer 2 Image Classification (Filter Version) 不用担心filter大小…

QT交叉编译环境搭建(Cmake和qmake)

介绍一共有两种方法&#xff08;基于qmake和cmake&#xff09;&#xff1a; 1.直接调用虚拟机中的交叉编译工具编译 2.在QT中新建编译套件kits camke和qmake的区别&#xff1a;CMake 和 qmake 都是自动化构建工具&#xff0c;用于简化构建过程&#xff0c;管理编译设置&…

STM32 对射式红外传感器配置

这次用的是STM32F103的开发板&#xff08;这里面的exti.c文件没有how to use this driver 配置说明&#xff09; 对射式红外传感器 由一个红外发光二极管和NPN光电三极管组成&#xff0c;M3固定安装孔&#xff0c;有输出状态指示灯&#xff0c;输出高电平灯灭&#xff0c;输出…

SQL优化

1.插入数据 &#xff08;1&#xff09;insert优化 批量插入&#xff1a;insert into tb_test values(1,tom),(2,cat),(3.jerry); 手动提交事务&#xff1a; start transaction; insert into tb_test values(1,tom),(2,cat),(3.jerry); insert into tb_test values(12,tom),(22…