Easy Excel合并单元格情况简单导入导出

需求

实现报表数据的导入导出,表格中部分数据是系统生成,部分数据是甲方填写,录入系统。

批号唯一

Maven

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency>

导出

看到网上都是创建自定义WriteHandler。略麻烦,可以用注解实现。

导出Bean,(bean就不给全了,涉及工艺),合并的单元格是列9,列10
 

@Data
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER,verticalAlignment = VerticalAlignmentEnum.CENTER)
@NoArgsConstructor
@AllArgsConstructor
public class ProductOne {@ContentLoopMerge(eachRow = 2)@ExcelProperty(value = {"批号", "批号", "批号", "批号"},index = 0)@ColumnWidth(20)private String column1;@ContentLoopMerge(eachRow = 2)@ExcelProperty(value = {"API放行标准", "API放行标准", "API放行标准", "API放行标准"},index = 1)private String column2;@ContentLoopMerge(eachRow = 2)@ExcelProperty(value = {"盘库月份", "盘库月份", "盘库月份", "盘库月份"},index = 2)private String column3;@ContentLoopMerge(eachRow = 2)@ExcelProperty(value = {"生产进度", "生产进度", "生产进度", "生产进度"},index = 3)private String column4;@ContentLoopMerge(eachRow = 2)@ExcelProperty(value = {"生产偏差/变更", "生产偏差/变更", "生产偏差/变更", "生产偏差/变更"},index = 4)private String column5;@ContentLoopMerge(eachRow = 2)@ExcelProperty(value = {"成品入库数量/kg", "成品入库数量/kg", "成品入库数量/kg", "成品入库数量/kg"},index = 5)private String column6;@ContentLoopMerge(eachRow = 2)@ExcelProperty(value = {"投料开始时间", "投料开始时间", "投料开始时间", "投料开始时间"},index = 6)private String column7;@ContentLoopMerge(eachRow = 2)@ExcelProperty(value = {"工序1:溶解脱色", "投料", "粗品数量(kg)", "M"},index = 7)private String column8;@ExcelProperty(value = {"工序1:溶解脱色", "投料", "精品二次结晶物数量(kg)", "/"},index = 8)private String column9;@ExcelProperty(value = {"工序1:溶解脱色", "投料", "精品二次结晶物批号", " / "},index = 9)@ColumnWidth(20)private String column10;public ProductOne(ReportProductOne bean) {this.column1 = bean.getColumn1();this.column2 = bean.getColumn2();this.column3 = bean.getColumn3();this.column4 = bean.getColumn4();this.column5 = bean.getColumn5();this.column6 = bean.getColumn6();this.column7 = bean.getColumn7();this.column8 = bean.getColumn8();this.column9 = bean.getColumn9One();this.column10 = bean.getColumn10One();}

@ContentLoopMerge(eachRow = 2) ,此注解每2行合并。loop可循环。

@OnceAbsoluteMerge 用于合并一次

下图中每个注解都非常好用

@ContentStyle ,用于正文样式,我这边上下左右都居中

数据库中,存储对象bean

public class ReportProductOne extends Model<ReportProductOne> {@TableId(type = IdType.AUTO)private Integer id;private String column1;private String column2;private String column3;private String column4;private String column5;private String column6;private String column7;private String column8;private String column9One;private String column9Two;private String column10One;private String column10Two;private Date createTime;public ReportProductOne(ProductOne productOne, String column9, String column10) {this.column1 = productOne.getColumn1();this.column2 = productOne.getColumn2();this.column3 = productOne.getColumn3();this.column4 = productOne.getColumn4();this.column5 = productOne.getColumn5();this.column6 = productOne.getColumn6();this.column7 = productOne.getColumn7();this.column8 = productOne.getColumn8();this.column9One = productOne.getColumn9();this.column10One = productOne.getColumn10();this.column9Two = column9;this.column10Two = column10;}

由此可以看出,对于批号,列9,列10。拆分的单元格也是一对一关系。

导出Controller

    @Operation(summary = "导出")@GetMapping("export2")public void export2(HttpServletResponse response) {List<ReportProductOne> list = reportProductOneService.list();List<ProductOne> result = new ArrayList<>(32);for (ReportProductOne reportProductOne : list) {ProductOne bean1 = new ProductOne(reportProductOne);ProductOne bean2 = BeanUtil.copyProperties(bean1, ProductOne.class);bean2.setColumn9(reportProductOne.getColumn9Two());bean2.setColumn10(reportProductOne.getColumn10Two());result.add(bean1);result.add(bean2);}try {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=test.xlsx");EasyExcel.write(response.getOutputStream(), ProductOne.class).autoCloseStream(Boolean.FALSE).sheet("Sheet 0").doWrite(result);} catch (IOException e) {e.printStackTrace();}}

以上bean2,其实也可以new一个,然后set列9 和列10。在导出的情况下根本没有区别,但是导入的时候会有。

导入

导入demo

导入Controller

    @Operation(summary = "批量导入")@PostMapping("import")public R userBatchImport(MultipartFile file){String originalFilename = file.getOriginalFilename();String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));if(!AuthConstant.SUFFIX_FILE_NAME.equals(suffixName)){return failed("文件格式不符合");}try {EasyExcel.read(file.getInputStream(),ProductOne.class,productOneImportBatchListener).headRowNumber(4).sheet().doRead();} catch (Exception e) {productOneImportBatchListener.clear();return failed(e.getMessage());}return success("success");}

ReadListener

public class ProductOneImportBatchListener extends AnalysisEventListener<ProductOne> {List<ProductOne> cache = new ArrayList<>(16);@Overridepublic void invoke(ProductOne bean, AnalysisContext analysisContext) {if(cache.size() % 2 == 0 && StrUtil.isEmpty(bean.getColumn1())) {throw new ExcelAnalysisException("批号必填或格式有误");}if(cache.size() % 2 == 0) {//判断批号是否存在,不存在throw}System.out.println(bean);cache.add(bean);}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {if(cache.size() % 2 != 0) {throw new ExcelAnalysisException("文档格式有误");}List<ReportProductOne> list = new ArrayList<>(32);//奇数行,都有批号for (int i = 0; i < cache.size(); i+=2) {ReportProductOne temp = new ReportProductOne(cache.get(i),cache.get(i+1).getColumn9(),cache.get(i+1).getColumn10());list.add(temp);}log.info("插入完成:共"+ list.size()+"条");clear();}public void clear(){cache.clear();}
}

解析数据

总结

虽然合并单元格,但是读取还是有2行。

如果是上面导出模板,那么导入的时候,2行在合并单元格列都能读取到数据。

如果是新增的情况,那么只有在首行能读取到导入的合并单元格数据。介于一对一关系这边忽略。非一对一可参考

如果在导出的情况下修改,那么合并单元格也只能首行能读取到数据。

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

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

相关文章

【modbus协议】libmodbus库移植基于linux平台

文章目录 下载库函数源码编译路径添加libmodbus 源码分析核心数据结构常用接口函数 开发 TCP Server 端开发TCP Client 端 下载库函数源码 编译路径添加 libmodbus 源码分析 核心数据结构 modbus_t结构体&#xff1a; 这是 libmodbus 的核心数据结构&#xff0c;代表一个 Mod…

机房巡检机器人有哪些功能和作用

随着数据量的爆炸式增长和业务的不断拓展&#xff0c;数据中心面临诸多挑战。一方面&#xff0c;设备数量庞大且复杂&#xff0c;数据中心内服务器、存储设备、网络设备等遍布&#xff0c;这些设备需时刻保持良好运行状态&#xff0c;因为任何一个环节出现问题都可能带来严重后…

从0到1学习node.js(express模块)

文章目录 Express框架1、初体验express2、什么是路由3、路由的使用3、获取请求参数4、电商项目商品详情场景配置路由占位符规则5、小练习&#xff0c;根据id参数返回对应歌手信息6、express和原生http模块设置响应体的一些方法7、其他响应设置8、express中间件8.1、什么是中间件…

如何搭建直播美颜SDK平台的最佳实践?美颜API的实现与集成详解

本篇文章&#xff0c;将从技术实现、平台搭建、API集成以及性能优化四个方面&#xff0c;为开发者详解如何搭建一个直播美颜SDK平台。 一、直播美颜SDK平台的技术架构 一般的美颜效果包括磨皮、亮肤、瘦脸、大眼等&#xff0c;这些效果的实现需要依赖图像增强和滤镜算法。核心…

【51单片机】第一个小程序 —— 点亮LED灯

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 单片机介绍LED灯介绍练习创建第一个项目点亮LED灯LED周期闪烁 单片机介绍 单片机&#xff0c;英文Micro Controller Unit&#xff0…

创建ODBC数据源SQLConfigDataSource函数的用法

网络上没有这个函数能实际落地的用法说明&#xff0c;我实践后整理一下&#xff1a; 1.头文件与额外依赖库&#xff1a; #include <odbcinst.h> #pragma comment(lib, "legacy_stdio_definitions.lib") 2.调用函数&#xff1a; if (!SQLConfigDataSourceW(…

阿里云镜像源无法访问?使用 DaoCloud 镜像源加速 Docker 下载(Linux 和 Windows 配置指南)

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f343; vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode&#x1f4ab; Gitee &#x1f…

java :String 类

在我们之前的讲解中我们已经了解了很多的Java知识&#xff0c;这节我们讲Java中字符如何定义以及关于String如何使用还有常见的string函数。 【本节目标】 1. 认识 String 类 2. 了解 String 类的基本用法 3. 熟练掌握 String 类的常见操作 4. 认识字符串常量池 5. 认识 …

江协科技STM32学习- P21 ADC模数转换器

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

基于SpringCloud的WMS管理系统源码

商品管理&#xff1a;商品类型&#xff0c;规格&#xff0c;详情等设置。 采购管理&#xff1a;采购单录入。 销售管理&#xff1a;销售单录入。 库存管理&#xff1a;库存查询、库存日志 采用前后端分离的模式&#xff0c;微服务版本前端 后端采用Spring Boot、Spring Cl…

python实现放烟花效果庆祝元旦

马上就要2025年元旦啦&#xff0c;提前祝大家新年快乐 完整代码下载地址&#xff1a;https://download.csdn.net/download/ture_mydream/89926458

vLLM推理部署Qwen2.5

vLLM vLLM 是一个用于大模型推理的高效框架。它旨在提供高性能、低延迟的推理服务&#xff0c;并支持多种硬件加速器&#xff0c;如 GPU 和 CPU。 vLLM 适用于大批量Prompt输入&#xff0c;并对推理速度要求高的场景&#xff0c;吞吐量比HuggingFace Transformers高10多倍。 …

手指关节分割系统:视觉算法突破

手指关节分割系统源码&#xff06;数据集分享 [yolov8-seg-C2f-RFAConv&#xff06;yolov8-seg-fasternet-bifpn等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Glob…

灵动AI:艺术与科技的融合

灵动AI视频官网地址&#xff1a;https://aigc.genceai.com/ 灵动AI 科技与艺术的完美融合之作。它代表着当下最前沿的影像技术&#xff0c;为我们带来前所未有的视觉盛宴。 AI 视频以强大的人工智能算法为基石&#xff0c;能够自动分析和理解各种场景与主题。无论是壮丽的自然…

网络学习/复习2套接字

LinuxCode/code26 zc/C语言程序学习 - 码云 - 开源中国

c语言中整数在内存中的存储

整数的二进制表示有三种&#xff1a;原码&#xff0c;反码&#xff0c;补码 有符号的整数&#xff0c;三种表示方法均有符号位和数值位两部分&#xff0c;符号位都是用‘0’表示“正&#xff0c;用1表示‘负’ 最高位的以为被当作符号位&#xff0c;剩余的都是数值位。 整数…

python 制作 发货单 (生成 html, pdf)

起因&#xff0c; 目的: 某个小店&#xff0c;想做个发货单。 过程: 先写一个 html 模板。准备数据&#xff0c; 一般是从数据库读取&#xff0c;也可以是 json 格式&#xff0c;或是 python 字典。总之&#xff0c;是数据内容。使用 jinja2 来渲染模板。最终的结果可以是 h…

使用 telnet 连接 dubbo 服务调用暴露的 dubbo 接口

目录 前言 环境准备 Telnet客户端 zookeeper pom 配置文件 dubbo接口 telnet连接dubbo dubbo命令 ls invoke 前言 工作中的微服务项目远程调用使用的技术是 dubbo&#xff0c;当对外提供了一个 duboo 接口时&#xff0c;无论是开发阶段自测&#xff0c;还是上线了服…

【EndNote版】如何在Word中引用文献

1、在Word中&#xff0c;鼠标光标放在所需插入文献的位置 2、点击选项卡中的“EndNote X9”&#xff0c;直接在EndNote中选中对应的文献 3、选中文献&#xff0c;点击工具栏中的“引用” 4、最后就可在Word中看到所插入的文献

华为配置BFD状态与接口状态联动实验

组网图形 图1 配置BFD状态与接口状态联动组网图 BFD简介配置注意事项组网需求配置思路操作步骤配置文件 BFD简介 为了减小设备故障对业务的影响&#xff0c;提高网络的可靠性&#xff0c;网络设备需要能够尽快检测到与相邻设备间的通信故障&#xff0c;以便及时采取措施&…