java poi导入Excel、导出excel
java poi导入Excel、导出excel
导出meven架包
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.1</version></dependency>
导入Excel
public void uploadFile(HttpServletRequest request, HttpServletResponse response, @RequestParam(value="file",required = false) MultipartFile file) {return import(request, response, file);}public void import(HttpServletRequest request, HttpServletResponse response, MultipartFile file) {long startTime = System.currentTimeMillis();//解析ExcelList<DTO> excelInfo = ReadPatientExcelUtil.getExcelInfo(file);if(excelInfo!=null && excelInfo.size()>0){for (int i = 0; i < excelInfo.size(); i++) {DTO dto = excelInfo.get(i);}}else{System.out.println("导入失败,请注意参数格式!");}long endTime = System.currentTimeMillis();String time = String.valueOf((endTime - startTime) / 1000);log.info("导入数据用时:"+time+"秒");return ResponseMsg.success("导入成功!");}
ReadPatientExcelUtil
import com.ly.directserver.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.NumberToTextConverter;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/**** 解析导入Excel数据* @author manba*/
@Slf4j
public class ReadPatientExcelUtil {//总行数private static int totalRows = 0;//总条数private static int totalCells = 0;//错误信息接收器private static String errorMsg;/**** 读取Excel* @param mFile* @return*/public static List<DTO> getExcelInfo(MultipartFile mFile) {String fileName = mFile.getOriginalFilename();//获取文件名try {if (!validateExcel(fileName)) {// 验证文件名是否合格return null;}boolean isExcel2003 = true;// 根据文件名判断文件是2003版本还是2007版本if (isExcel2007(fileName)) {isExcel2003 = false;}List<DTO> agentList = getExcel(mFile.getInputStream(), isExcel2003);return agentList;} catch (Exception e) {e.printStackTrace();}return null;}public static List<DTO> getAgentExcel(InputStream is, boolean isExcel2003) {try {Workbook wb = null;if (isExcel2003) {// 当excel是2003时,创建excel2003wb = new HSSFWorkbook(is);} else {// 当excel是2007时,创建excel2007wb = new XSSFWorkbook(is);}List<DTO> DTOS = readExcelValue(wb);// 读取Excel里面客户的信息return DTOS;} catch (IOException e) {e.printStackTrace();}return null;}private static List<DTO> readExcelValue(Workbook wb) {//默认会跳过第一行标题// 得到第一个shellSheet sheet = wb.getSheetAt(0);// 得到Excel的行数totalRows = sheet.getPhysicalNumberOfRows();// 得到Excel的列数(前提是有行数)if (totalRows > 1 && sheet.getRow(0) != null) {totalCells = sheet.getRow(0).getPhysicalNumberOfCells();}List<DTO> DTOS = new ArrayList<>();// 循环Excel行数for (int r = 1; r < totalRows; r++) {Row row = sheet.getRow(r);if (row == null) {continue;}DTO DTO = new DTO();// 循环Excel的列for (int c = 0; c < totalCells ; c++) {Cell cell = row.getCell(c);if (null != cell) {if (c == 0) { //第一列//如果是纯数字if (cell.getCellTypeEnum() == CellType.NUMERIC) {cell.setCellType(CellType.NUMERIC);int a =(int) cell.getNumericCellValue();}} else if (c == 1) {//如果是doubleif (cell.getCellTypeEnum() == CellType.NUMERIC) {cell.setCellType(CellType.NUMERIC);}double stringCellValue = cell.getNumericCellValue();} else if (c == 2) {if (cell.getCellTypeEnum() == CellType.STRING) {cell.setCellType(CellType.STRING);//如果是字符串String str = cell.getStringCellValue();}else if (cell.getCellTypeEnum() == CellType.NUMERIC) {cell.setCellType(CellType.NUMERIC);//如果是数字,需要转换为字符串String desc = NumberToTextConverter.toText(cell.getNumericCellValue());}}}}//将excel解析出来的数据赋值给对象添加到list中// 添加到listDTOS.add(DTO);}return DTOS;}}
导出Excel
public void exportCollectRecord(HttpServletResponse res){File file = createExcelFile();FileUtils.downloadFile(res, file, file.getName());}public static File createExcelFile(List<DTO> list) {Workbook workbook = new XSSFWorkbook();//创建一个sheet,括号里可以输入sheet名称,默认为sheet0Sheet sheet = workbook.createSheet();Row row0 = sheet.createRow(0);int columnIndex = 0;row0.createCell(columnIndex).setCellValue("xxx");row0.createCell(++columnIndex).setCellValue("xxx");row0.createCell(++columnIndex).setCellValue("xxx");for (int i = 0; i < list.size(); i++) {DTO dto = list.get(i);Row row = sheet.createRow(i + 1);for (int j = 0; j < columnIndex + 2; j++) {row.createCell(j);}columnIndex = 0;row.getCell(columnIndex).setCellValue("xxx");row.getCell(++columnIndex).setCellValue("xxx");row.getCell(++columnIndex).setCellValue("xxx");}//调用PoiUtils工具包return PoiUtils.createExcelFile(workbook, DateUtils.fmtDateToStr(new Date(), "yyyy-MM-dd HH_mm_ss") );}
PoiUtils
import org.apache.poi.ss.usermodel.Workbook;
import java.io.*;public class PoiUtils {/*** 生成Excel文件* @param workbook* @param fileName* @return*/public static File createExcelFile(Workbook workbook, String fileName) {OutputStream stream = null;File file = null;try {//用了createTempFile,这是创建临时文件,系统会自动给你的临时文件编号,所以后面有号码,你用createNewFile的话就完全按照你指定的名称来了file = File.createTempFile(fileName, ".xlsx");stream = new FileOutputStream(file.getAbsoluteFile());workbook.write(stream);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {//这里调用了IO工具包控制开关IOUtils.closeQuietly(workbook);IOUtils.closeQuietly(stream);}return file;}}
FileUtils
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.lang.reflect.Method;
import java.security.MessageDigest;public class FileUtils {/*** 下载文件* @param response* @param file* @param newFileName*/public static void downloadFile(HttpServletResponse response, File file, String newFileName) {try {response.setHeader("Content-Disposition", "attachment; filename=" + new String(newFileName.getBytes("ISO-8859-1"), "UTF-8"));BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());InputStream is = new FileInputStream(file.getAbsolutePath());BufferedInputStream bis = new BufferedInputStream(is);int length = 0;byte[] temp = new byte[1 * 1024 * 10];while ((length = bis.read(temp)) != -1) {bos.write(temp, 0, length);}bos.flush();bis.close();bos.close();is.close();} catch (Exception e) {e.printStackTrace();}}// 将输入流使用指定编码转化为字符串public static String inputStream2String(InputStream inputStream, String charset) throws Exception {// 建立输入流读取类InputStreamReader reader = new InputStreamReader(inputStream, charset);// 设定每次读取字符个数char[] data = new char[512];int dataSize = 0;// 循环读取StringBuilder stringBuilder = new StringBuilder();while ((dataSize = reader.read(data)) != -1) {stringBuilder.append(data, 0, dataSize);}return stringBuilder.toString();}private static DocumentBuilderFactory documentBuilderFactory = null;public static <T> T parseXml2Obj(String xml, Class<T> tclass) throws Exception {if (isEmpty(xml)) throw new NullPointerException("要解析的xml字符串不能为空。");if (documentBuilderFactory == null) { // 文档解析器工厂初始documentBuilderFactory = DocumentBuilderFactory.newInstance();}// 拿到一个文档解析器。DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();// 准备数据并解析。byte[] bytes = xml.getBytes("UTF-8");Document parsed = documentBuilder.parse(new ByteArrayInputStream(bytes));// 获取数据T obj = tclass.newInstance();Element documentElement = parsed.getDocumentElement();NodeList childNodes = documentElement.getChildNodes();for (int i = 0; i < childNodes.getLength(); i++) {Node item = childNodes.item(i);// 节点类型是 ELEMENT 才读取值// 进行此判断是因为如果xml不是一行,而是多行且有很好的格式的,就会产生一些文本的node,这些node内容只有换行符或空格// 所以排除这些换行符和空格。if (item.getNodeType() == Node.ELEMENT_NODE) {String key = item.getNodeName();String value = item.getTextContent();// 拿到设置值的set方法。Method declaredMethod = tclass.getDeclaredMethod("set" + key, String.class);if (declaredMethod != null) {declaredMethod.setAccessible(true);declaredMethod.invoke(obj, value); // 设置值}}}return obj;}// 将二进制数据转换为16进制字符串。public static String byte2HexString(byte[] src) {StringBuilder stringBuilder = new StringBuilder();if (src == null || src.length <= 0) {return null;}for (byte b : src) {String hv = Integer.toHexString(b & 0xFF);if (hv.length() < 2) {stringBuilder.append(0);}stringBuilder.append(hv);}return stringBuilder.toString();}// 对字符串进行sha1加签public static String sha1(String context) throws Exception {// 获取sha1算法封装类MessageDigest sha1Digest = MessageDigest.getInstance("SHA-1");// 进行加密byte[] digestResult = sha1Digest.digest(context.getBytes("UTF-8"));// 转换为16进制字符串return byte2HexString(digestResult);}public static boolean isEmpty(String value) {return value == null || value.length() == 0;}}
相关文章:
java poi导入Excel、导出excel
java poi导入Excel、导出excel 导出meven架包 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.1</version></dependency>导入Excel public void uploadFile(HttpServletRequ…...

【算法与数据结构】101、LeetCode对称二叉树
文章目录 一、题目二、递归法三、迭代法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、递归法 思路分析:这道题目标就是要对比左右两半的树是否对称,因此对比不是左右节点是否相等&…...
【N32L40X】学习笔记04-gpio中断库
gpio中断 该函数库的目的就是在统一的地方配置,将配置的不同项放置在一个结构体内部使用一个枚举来定义一个的别名 NVIC 寄存器 NVIC 相关的寄存器定义了可以在 core_cm4.h 文件中找到。我们直接通过程序的定义来分 析 NVIC 相关的寄存器,其定义如下…...

Godot 4 着色器 - Shader调试
我之前用OpenCV进行图像相关处理,觉得已经很不错,结合GDI可以实现流畅的动画效果 直到近来用Shader后才发现,着色器更上一层楼,原来这是入了GPU的坑 Shader编程限制很多,各种不支持,看在它性能不错功能炫…...

liunx时间慢几分钟,定时更新系统时间
#!/bin/sh hwclock --hctosys echo "执行成功" 定时5分钟执行一次...

C# 委托详解
一.委托的概念 C#中委托也叫代理,委托提供了后期绑定机制(官方解释),功能类似于C中的函数指针,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行。 二.委托的用法…...

chatGPT 学习分享:内含PPT分享下载
InstructGPT论文地址: Training language models to follow instructions with human feedbackchatGPT地址:openAI个人整理的PPT(可编辑),下载地址:chatGPT学习分享PPT...
使用CRM进行数据分析的四大好处
使用CRM数据分析系统够帮助企业更好地了解客户需求和行为习惯,提供个性化的服务,从而提高客户满意度和忠诚度。使用CRM数据分析系统可以为企业带来一些好处,包括提高客户洞察力、加强营销策略、提高运营效率等。 1.提高客户洞察力:…...

Excel“牛人”变现方案参考
有几种方式可以通过Excel技能实现变现: 1. 提供Excel咨询和培训服务:如果你对Excel非常熟悉,你可以提供咨询和培训服务,帮助他人解决Excel使用中的问题或提高他们的Excel技能。 2. 制作和销售Excel模板:你可以根据市…...

vscode和jetbrains IDEA添加免费的gpt代码生成插件
vscode和jetbrains IDEA添加免费的gpt代码生成插件 VSCODE添加代码智能生成插件 一、打开vscode添加扩展 打开vscode,点击扩展,搜索 aws toolkit 二、连接到AWS 如图,选择添加connectiong to aws 选择 Sign up or Sign in …...

【C#】医学实验室云LIS检验信息系统源码 采用B/S架构
基于B/S架构的医学实验室云LIS检验信息系统,整个系统的运行基于WEB层面,只需要在对应的工作台安装一个浏览器软件有外网即可访问,技术架构:Asp.NET CORE 3.1 MVC SQLserver Redis等。 一、系统概况 本系统是将各种生化、免疫、…...
linux:AWS LightSail 设置虚拟内存
参考: https://www.cnblogs.com/fallin/p/13186236.html 总结: #2G的swap文件 sudo dd if/dev/zero of/swapfile bs1M count2048 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile sudo echo /swapfile none swap defaults 0 0 &g…...
“华为杯”研究生数学建模竞赛2016年-【华为杯】E题:粮食最低收购价问题研究
目录 摘 要: 第 1 章 前 言 1.1 研究的目的与意义 1.2 文献综述...

idea项目依赖全部找不到
目录 1,出错现象2,解决3,其他尝试 1,出错现象 很久没打开的Java项目,打开之后大部分依赖都找不到,出现了所有的含有import语句的文件都会报错和一些注解报红报错,但pom文件中改依赖是确实被引入…...

自动驾驶数据标注有哪些?
自动驾驶汽车:人工智能(AI)的焦点 人工智能驱动汽车解决方案的市场规模预计到 2025年将增长十倍以上,提升车内体验的商机领域以及 AI 模型的无偏见训练数据的重要性。在本篇中,我们将介绍车外体验的关键组成部分,以及自动驾驶数据…...
ChatGPT:人工智能语言模型的巅峰之作
一、 ChatGPT 的前世今生 ChatGPT 是 GPT(Generative Pre-trained Transformer)系列模型的最新成员,其前身 GPT-3 在推出后引起了广泛关注。OpenAI 团队不断优化和训练,终于推出了 ChatGPT,这一最先进的语言模型&#…...

【unity之IMGUI实践】敌方逻辑封装实现【六】
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:uni…...
llvm向用户抛出warning、error信息
1、抛出error信息并终止程序 使用DiagnosticInfoUnsupported可以向用户抛出error信息并且终止程序,效果如同report_fatal_error、Error。后端用法如下: void xxxx::reportErrorMsg(const MachineFunction &MF)const {const Function &F MF.ge…...

微服务学习笔记-----Nacos安装教程(Windows和Linux版本)
Nacos安装教程 Nacos安装指南1.Windows安装1.1.下载安装包1.2.解压1.3.端口配置1.4.启动1.5.访问 2.Linux安装2.1.安装JDK2.2.上传安装包2.3.解压2.4.端口配置2.5.启动 3.Nacos的依赖 Nacos安装指南 1.Windows安装 开发阶段采用单机安装即可。 1.1.下载安装包 在Nacos的Git…...
程序员面试系列,docker常见面试题
原文链接 什么是Docker?它的主要作用是什么?Docker和虚拟机之间有什么区别?Docker的主要组件有哪些?Docker镜像和容器的区别是什么?如何构建Docker镜像?请简要描述构建过程。如何创建和启动一个Docker容器…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...