Excel文件解析--超大Excel文件读写

使用POI写入

        当我们想在Excel文件中写入100w条数据时,我们用普通的XSSFWorkbook对象写入时会发现,只有在将100w条数据全部加载入内存后才会用write()方法统一写入,这样效率很低,所以我们引入了SXSSFWorkbook进行超大Excel文件的读写。

        SXSSFWorkbook可以通过构造参数来控制:当数据写入内存量达到参数值时,就把这些数据flush到Excel文件中

public class Demo02_SXSSFWorkbook {public static void main(String[] args) {String Path="D://IO流//0421.xlsx";try (Workbook workbook = new SXSSFWorkbook(1000);FileOutputStream out=new FileOutputStream(Path)){//生成SheetSheet sheet=workbook.createSheet();for(int i=0;i<1000000;i++) {Row row =sheet.createRow(i);Cell cell0=row.createCell(0);cell0.setCellValue(UUID.randomUUID().toString());Cell cell1=row.createCell(1);cell1.setCellValue(new Date());}//写入输出流workbook.write(out);}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

使用EasyExcel写入

        使用EasyExcel,我们首先要导入相关jar包

         这是一个普通的Order类:

public class Order {private String orderId;private Double payment;public Order() {this.orderId=LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+UUID.randomUUID().toString().substring(0,5);this.payment=Math.random()*1000;}public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}public Double getPayment() {return payment;}public void setPayment(Double payment) {this.payment = payment;}@Overridepublic String toString() {return "Order [orderId=" + orderId + ", payment=" + payment + "]";}
}

        然后我们来通过EasyExcel来将100w条数据写入excel文件:

public class Text_order {public static void main(String[] args) {EasyExcel.write("D://IO流//422.xlsx",Order.class).sheet("订单数据").dowrite(creatOrderData());}//生成100w条数据private static List<Order> creatOrderData(){List<Order> orderList=new ArrayList<Order>();for(int i=0;i<1000000;i++) {orderList.add(new Order());}return orderList;}
}

运行结果: 

        我们发现,Order类中的成员变量名就是我们生成的Excel文件中的列头。那么如果我们想自定义列头时,我们可以用:@ExcelProperty("列头名")

public class Order {@ExcelProperty("订单编号")private String orderId;@ExcelProperty("支付金额")private Double payment;public Order() {...}
}

运行结果:

        那么,当我们想加入一列日期数据时:

public class Order {@ExcelProperty("订单编号")private String orderId;@ExcelProperty("支付金额")private Double payment;@ExcelProperty("创建时间")private LocalDateTime  creatTime;public Order() {this.orderId=LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+UUID.randomUUID().toString().substring(0,5);this.payment=Math.random()*1000;this.creatTime=LocalDateTime.now();}public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}public Double getPayment() {return payment;}public void setPayment(Double payment) {this.payment = payment;}public LocalDateTime getCreatTime() {return creatTime;}public void setCreatTime(LocalDateTime creatTime) {this.creatTime = creatTime;}@Overridepublic String toString() {return "Order [orderId=" + orderId + ", payment=" + payment+ ", creatTime=" + creatTime + "]";}
}

运行结果:

通过阅读报错提示(Can not find 'Converter' support class LocalDateTime.) ,我们大概可以知道,是因为找不到一个支持LocalDateTime类的转换器,所以为了解决这个问题,我们可以自己写一个比较器类:

public class LocalDateTimeConverter implements Converter<LocalDateTime> {//Excel文件中的类型@Overridepublic CellDataTypeEnum supportExcelTypeKey() {// TODO Auto-generated method stubreturn CellDataTypeEnum.STRING;}//程序中的类型@Overridepublic Class supportJavaTypeKey() {// TODO Auto-generated method stubreturn LocalDateTime.class;}//将LocalDateTime类型的数据转换成String//并封装到一个Excel文件中的CellData@Overridepublic CellData convertToExcelData(LocalDateTime value,         ExcelContentProperty arg1,GlobalConfiguration arg2)throws Exception {// TODO Auto-generated method stubreturn new CellData<>(value.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss")));}//从CellData中获取一个String类型的数据//并转换成LocalDateTime@Overridepublic LocalDateTime convertToJavaData(CellData cellData,             ExcelContentProperty arg1,GlobalConfiguration arg2)throws Exception {// TODO Auto-generated method stubreturn LocalDateTime.parse(				            cellData.getStringValue(),DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"));}
}

        当我们写好这个比较器后,就需要给成员变量creatTime显示的设置好比较器:

public class Order {@ExcelProperty("订单编号")private String orderId;@ExcelProperty("支付金额")private Double payment;//设置LocalDateTime对应转换器@ExcelProperty(value="创建时间",converter=LocalDateTimeConverter.class)private LocalDateTime  creatTime;public Order() {...}
}

运行结果:

Excel文件解析的应用

案例一:检查Excel文件

//检查demo-data.xlsx文件中的人员信息格式是否正确,具体要求如下:

// 1.序号是否连续
// 2.检查性别是否为男或女
// 3.身份证号
// 3.1 身份证号码格式(必须为18位)
// 3.2 身份证号码不能重复
// 3.3 身份证号码开头两位是否与籍贯符合
// 北京 11 天津12 河北 13 山西14 内蒙古 15
// 陕西61 甘肃62 青海 63
// 4.学历只能填写:大专、本科、硕士、其它
// 5.体重在40-180之间

public class Work01 {public static void main(String[] args) {List<String> errorMsgList=validateDataExcel("D:\\IO流\\demo-    data.xlsx");if(errorMsgList.size()==0){System.out.println("文件检查无误");}else {//显示错误信息for(String err:errorMsgList) {System.out.println(err);}}}public static List<String> validateDataExcel(String path){//创建一个list用于保存错误提示信息ArrayList<String> errorList=new ArrayList<String>();//创建一个set用于检查身份证账号是否重复的集合HashSet<String> idcardNoSet=new HashSet<String>();//创建一个HashMap用于检查身份证号码开头两位是否与籍贯符合HashMap<String,String> provinceMap=new HashMap<String,String>(){//匿名构造代码块{put("11","北京");put("12","天津");put("13","河北");put("14","山西");put("15","内蒙古");put("61","陕西");put("62","甘肃");put("63","青海");}};//创建一个用于检查学历的listList<String> eduList=Arrays.asList("大专","硕士","本科","其他");try(Workbook workbook=new XSSFWorkbook(path)){Sheet sheet=workbook.getSheetAt(0);//获取每个Cell中的数据for(int i =1;i<sheet.getLastRowNum();i++){//1.序号是否连续Cell cellId=row.getRow(0);//通过当前行数获取正确的序号int rowNum=row.getRowNum();//获取文件中的序号int id=(int)cellId.getNumericCellValue();if(rowNum!=id) {errorList.add(String.format("%d行的数据不连续",rowNum));		}//2.检查性别是否为男或女String gender =row.getCell(2).getStringCellValue();if(!ender.equals("男")&&!ender.equals("女")){errorList.add(String.format("%d行的性别有误",rowNum));}// 3.身份证号String idCardNo=row.getCell(3).getStringCellValue();// 3.1 身份证号码格式(必须为18位)if(idCardNo.length()!=18) {errorList.add(String.format("%d行的身份证号码长度有误",rowNum));}// 3.2 身份证号码不能重复//如果成功添加进idcardNoSet集合,说明该身份证号没有重复//如果添加不成功,代表有重复if(!idcardNoSet.add(idCardNo)){errorList.add(String.format("%d行的身份证号码重复",rowNum));}// 3.3 身份证号码开头两位是否与籍贯符合// 北京 11 天津12 河北 13 山西14 内蒙古 15// 陕西61 甘肃62 青海 63String idCardNoHomeCode=idCardNo.substring(0,2);//根据身份证号码前两位,在provinceMap中获取正确的籍贯省份名称String homeValue=provinceMap.get(idCardNoHomeCode);// 获取表格中当前行的籍贯省份String home=row.getCell(6).getStringCellValue();if(homeValue!=home) {errorList. add(String. format("%d行的身份证籍贯信息不一致! ", rowNum));}// 4.学历只能填写:大专、本科、硕士、其它//通过在eduList列表中查找来判断学历信息是否符合规范String eduValue = row.getCell(7). getStringCellValue();if(!eduList.contains(eduValue)) {errorList. add(String. format("%d行的学历信息不符合规范! ", rowNum));}}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return errorList;}}

运行结果:

1行的身份证籍贯信息不一致! 
1行的学历信息不符合规范! 
2行的身份证籍贯信息不一致! 
3行的身份证籍贯信息不一致! 
4行的数据不连续
4行的身份证籍贯信息不一致! 
5行的身份证籍贯信息不一致! 
5行的学历信息不符合规范! 
6行的身份证籍贯信息不一致! 
7行的身份证号码长度有误
7行的身份证籍贯信息不一致! 
8行的身份证籍贯信息不一致! 
9行的身份证号码长度有误
9行的身份证籍贯信息不一致! 
9行的学历信息不符合规范! 
10行的身份证籍贯信息不一致! 
11行的身份证号码长度有误
11行的身份证籍贯信息不一致! 
12行的数据不连续
12行的身份证籍贯信息不一致! 
13行的身份证号码长度有误
13行的身份证籍贯信息不一致! 
14行的身份证籍贯信息不一致! 
14行的学历信息不符合规范! 
15行的身份证籍贯信息不一致! 
15行的学历信息不符合规范! 
16行的性别有误
16行的身份证籍贯信息不一致! 
17行的身份证籍贯信息不一致! 
18行的数据不连续
18行的身份证籍贯信息不一致! 
19行的身份证籍贯信息不一致! 
20行的身份证籍贯信息不一致! 
21行的身份证籍贯信息不一致! 
22行的身份证籍贯信息不一致! 
23行的身份证籍贯信息不一致! 
24行的身份证号码重复
24行的身份证籍贯信息不一致! 
25行的性别有误
25行的身份证籍贯信息不一致! 
26行的身份证籍贯信息不一致! 
27行的身份证籍贯信息不一致! 
28行的身份证籍贯信息不一致! 
29行的身份证籍贯信息不一致! 
30行的身份证籍贯信息不一致! 
31行的身份证籍贯信息不一致! 
32行的身份证籍贯信息不一致! 
33行的身份证号码重复
33行的身份证籍贯信息不一致! 
34行的身份证籍贯信息不一致! 
35行的身份证籍贯信息不一致! 
36行的身份证号码长度有误
36行的身份证籍贯信息不一致! 
37行的身份证籍贯信息不一致! 
38行的身份证籍贯信息不一致! 
39行的身份证籍贯信息不一致! 
40行的身份证籍贯信息不一致! 
41行的身份证籍贯信息不一致! 
42行的身份证籍贯信息不一致! 
43行的身份证籍贯信息不一致! 
44行的身份证籍贯信息不一致! 
45行的身份证籍贯信息不一致! 
46行的身份证籍贯信息不一致! 
47行的身份证籍贯信息不一致! 
 

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

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

相关文章

java开发之路——node.js安装

1. 安装node.js 最新Node.js安装详细教程及node.js配置 (1)默认的全局的安装路径和缓存路径 npm安装模块或库(可以统称为包)常用的两种命令形式&#xff1a; 本地安装(local)&#xff1a;npm install 名称全局安装(global)&#xff1a;npm install 名称 -g本地安装和全局安装…

【Leetcode】string类刷题

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;Leetcode刷题 目录 1.仅反转字母2.字符串中第一个唯一字符3.验证回文串4.字符串相加5.反转字符串I I6.反转字符串中的单词III7.字符串相乘8.把字符串转换为整数 1.仅反转字母 题目链接&#xff1a;…

一篇文章带您了解面向对象(java)

1.简单理解面向过程编程和面向对象编程 面向过程编程&#xff1a;开发一个一个的方法&#xff0c;有数据需要处理&#xff0c;我们就可以调用方法来处理。 package com.web.quictstart;public class demo1 {public static void main(String[] args) {totalScore("张三&q…

mac上VMware fusion net模式无法正常使用的问题

更新时间&#xff1a;2024年04月22日21:39:04 1. 问题 环境&#xff1a; intel芯片的macbook pro VMware fusion 13.5.1 无法将“Ethernet0”连接到虚拟网络“/dev/vmnet8”。在这里显示这个之后&#xff0c;应该是vmnet8的网段发生了冲突&#xff0c;所以导致无法正常使用…

前端开发攻略---拖动归类,将元素拖拽到相应位置

1、演示 2、代码 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"widthdevice-…

2024年Q1季度平板电视行业线上市场销售数据分析

Q1季度平板电视线上市场表现不如预期。 根据鲸参谋数据显示&#xff0c;2024年1月至3月线上电商平台&#xff08;京东天猫淘宝&#xff09;平板电视累计销量约360万件&#xff0c;环比下降12%&#xff0c;同比下降30%&#xff1b;累计销售额约99亿元&#xff0c;环比下降28%&a…

学习STM32第十七天

备份域详解 一、简介 在参考手册的电源控制章节&#xff0c;提到了备份域&#xff0c;BKPR是在RTC外设中用到&#xff0c;包含20个备份数据寄存器&#xff08;80字节&#xff09;&#xff0c;备份域包括4KB的备份SRAM&#xff0c;以32位、16位或8位模式寻址&#xff0c;在VBAT…

C++初阶学习第二弹——C++入门(下)

C入门&#xff08;上&#xff09;&#xff1a;C初阶学习第一弹——C入门&#xff08;上&#xff09;-CSDN博客 目录 一、引用 1.1 引用的实质 1.2 引用的用法 二、函数重载 三、内敛函数 四、auto关键字 五、总结 前言&#xff1a; 在上面一章我们已经讲解了C的一些基本…

Vue2进阶之Vue2高级用法

Vue2高级用法 mixin示例一示例二 plugin插件自定义指令vue-element-admin slot插槽filter过滤器 mixin 示例一 App.vue <template><div id"app"></div> </template><script> const mixin2{created(){console.log("mixin creat…

【Java网络编程】TCP通信(Socket 与 ServerSocket)和UDP通信的三种数据传输方式

目录 1、TCP通信 1.1、Socket 和 ServerSocket 1.3、TCP通信示例 2、UDP的三种通信&#xff08;数据传输&#xff09;方式 1、TCP通信 TCP通信协议是一种可靠的网络协议&#xff0c;它在通信的两端各建立一个Socket对象 通信之前要保证连接已经建立&#xff08;注意TCP是一…

【Interconnection Networks 互连网络】Torus 网络拓扑

1. Torus 网络拓扑2. Torus 网络拓扑结构References 1. Torus 网络拓扑 Torus 和 Mesh 网络拓扑&#xff0c;又可以称为 k-ary n-cubes&#xff0c;在规则的 n 维网格中包裹着 N k^n 个节点&#xff0c;每个维度都有 k 个节点&#xff0c;并且最近邻居之间有通道。k-ary n-c…

YOLOv9有效改进专栏汇总|未来更新卷积、主干、检测头注意力机制、特征融合方式等创新![2024/4/21]

​ 专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 专栏介绍 YOLOv9作为最新的YOLO系列模型&#xff0c;对于做目标检测的同学是必不可少的。本专栏将针对2024年最新推出的YOLOv9检测模型&#xff0…

《HCIP-openEuler实验指导手册》1.3Apache动态功能模块加载卸载练习

1.3.1 配置思路 mod_status 模块可以帮助管理员通过web界面监控Apache运行状态&#xff0c;通过LoadModule指令加载该模块&#xff0c;再配置相关权限&#xff0c;并开启ExtendedStatus后&#xff0c;即可使用该模块。 1.3.2 配置步骤 检查mod_status模块状态&#xff08;使…

net模块

建立TCP的链接 1 发送消息的服务 2 接收消息 2 建立http的链接让浏览器进行访问 import net from netconst html <h1>TCP</h1>const respinseHeaders [HTTP/1.1 200 OK,Content-Type:text/html,Content-Length: html.length,\r\n,html]const http net.create…

RK3568 学习笔记 : u-boot 通过 tftp 网络更新 u-boot自身

前言 开发板型号&#xff1a; 【正点原子】 的 RK3568 开发板 AtomPi-CA1 使用 虚拟机 ubuntu 20.04 收到单独 编译 RK3568 u-boot 使用 rockchip Linux 内核的设备树 【替换】 u-boot 下的 rk3568 开发板设备树文件&#xff0c;解决 u-boot 下千兆网卡设备能识别但是无法 Pi…

Spring(下)

接上篇&#xff0c;从第八个问题讲起 八.Spring工厂创建复杂对象 1.什么是复杂对象 简单对象就是可以直接new出来的&#xff0c;也就是直接调用构造方法创建 所以复杂对象就是不能直接通过调用构造方法创建。就比如JDBC中的Connection 2.三种方法 &#xff08;1&#xff…

【华为 ICT HCIA eNSP 习题汇总】——题目集18

1、SSH默认工作使用的TCP端口号是&#xff08;&#xff09;。 A、20 B、21 C、22 D、23 考点&#xff1a;①传输层 ②应用层 解析&#xff1a;&#xff08;C&#xff09; SSH为建立在应用层和传输层上的安全协议&#xff0c;是对TCP/IP协议的传输层以上的SSH会话流程进行加密的…

必应搜索广告与谷歌搜索广告对比那个更好?

搜索引擎广告作为企业获取潜在客户的重要渠道之一&#xff0c;其效果直接关系到营销策略的成功与否。两大搜索引擎巨头——谷歌&#xff08;Google&#xff09;和必应&#xff08;Bing&#xff09;各自提供了广告平台&#xff0c;即谷歌广告&#xff08;Google Ads&#xff09;…

【Web】2022DASCTF X SU 三月春季挑战赛 题解(全)

目录 ezpop calc upgdstore ezpop 瞪眼看链子 fin#__destruct -> what#__toString -> fin.run() -> crow#__invoke -> fin#__call -> mix.get_flag() exp <?php class crow {public $v1;public $v2;}class fin {public $f1; }class what {public $a; }…

力扣hot100(python解析)

文章目录 13. 合并区间14. 轮转数组 13. 合并区间 合并区间 数组 排序 思路&#xff1a; 代码&#xff1a; class Solution:def merge(self, intervals):result []if len(intervals) 0:return result # 区间集合为空直接返回intervals.sort() # 默认按照区间的左边界进…