Apache POI的简单介绍与应用

介绍

Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。PS: 一般情况下,POI 都是用于操作 Excel 文件,如图:
在这里插入图片描述
Apache POI 的应用场景:

  • 银行网银系统导出交易明细
  • 各种业务系统导出Excel报表
  • 批量导入业务数据

入门案例

  1. 导入Apache POI的maven坐标:
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId>
</dependency>
  1. 数据写入Excel文件:
public class POITest {/*** 通过POI创建Excel,并写入文件内容*/public static void write() throws Exception {// 在内存中创建一个Excel文件XSSFWorkbook excel = new XSSFWorkbook();// 在Excel文件中创建一个sheet页XSSFSheet sheet = excel.createSheet("info");// 在sheet页中创建行对象,rownum的编号从0开始,写1表示创建第2行XSSFRow row = sheet.createRow(1);// 在行中创建单元格, columnIndex也是从0开始,使用setCellValue写入文本内容row.createCell(1).setCellValue("姓名");row.createCell(2).setCellValue("城市");// 创建新的一行row = sheet.createRow(2);row.createCell(1).setCellValue("张三");row.createCell(2).setCellValue("成都");row = sheet.createRow(3);row.createCell(1).setCellValue("李四");row.createCell(2).setCellValue("北京");FileOutputStream out = new FileOutputStream("/home/zxy/Projects/info.xlsx");excel.write(out);// 关闭资源out.close();excel.close();}public static void main(String[] args) throws Exception{write();}
}

运行效果:
在这里插入图片描述

  1. 从Excel中读取数据
    /*** 通过POI读取Excel中的内容* @throws Exception*/public static void read() throws Exception{// 读取磁盘上已经存在的Excel文件FileInputStream in = new FileInputStream(new File("/home/zxy/Projects/info.xlsx"));XSSFWorkbook excel = new XSSFWorkbook(in);// 读取Excel文件中的第一个Sheet页XSSFSheet sheet = excel.getSheetAt(0);// 获取sheet页中数据所在最后一行的行号int lastRowNum = sheet.getLastRowNum();for (int i = 1; i <= lastRowNum; i++) {// 获得某一行XSSFRow row = sheet.getRow(i);// 获得单元格对象String cellValue1 = row.getCell(1).getStringCellValue();String cellValue2 = row.getCell(2).getStringCellValue();System.out.println(cellValue1 + "  " + cellValue2);}// 关闭资源excel.close();in.close();}public static void main(String[] args) throws Exception{read();}

效果:
在这里插入图片描述

应用

场景:导出(并下载)商户最近30天的运营数据
注意:对导出数据的请求并没有返回数据,因为报表导出功能本质上是文件下载,服务端会通过输出流将Excel文件下载到客户端浏览器。
实现步骤:

  1. 设计Excel模板文件
  2. 查询近30天的运营数据
  3. 将查询到的运营数据写入模板文件
  4. 通过输出流将Excel文件下载到客户端浏览器

虽然POI可以设置文件的字体、字号、合并单元格等格式,但这会使得代码变得非常复杂,所以提前在文本编辑器中设置好Excel的模版文件,然后通过读取模版文件来填充数据,从而可以简化代码。

具体代码:
controller部分:

	/*** 导出运营数据报表* @param response*/@GetMapping("/export")@ApiOperation("导出运营数据报表")public void export(HttpServletResponse response){reportService.exportBusinessData(response);}

Service部分:

	/*** 导出运营数据报表* @param response*/void exportBusinessData(HttpServletResponse response);

重点: Service的实现类中对应的方法:

	/*** 导出运营数据报表** @param response*/@Overridepublic void exportBusinessData(HttpServletResponse response) {// 1. 查询数据库,获取营业数据 --- 查询最近30天的数据LocalDate dateBegin = LocalDate.now().minusDays(30);LocalDate dateEnd = LocalDate.now().minusDays(1);// 查询概览数据BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(dateBegin, LocalTime.MIN), LocalDateTime.of(dateEnd, LocalTime.MAX));// 2. 通过POI将数据写入到Excel文件中InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");try {// 基于模板文件创建一个新的Excel文件XSSFWorkbook excel = new XSSFWorkbook(in);// 获取表格文件的Sheet页XSSFSheet sheet = excel.getSheet("Sheet1");// 填充数据——时间sheet.getRow(1).getCell(1).setCellValue("时间:" + dateBegin + "至" + dateEnd);// 获取第4行XSSFRow row = sheet.getRow(3);row.getCell(2).setCellValue(businessData.getTurnover());row.getCell(4).setCellValue(businessData.getOrderCompletionRate());row.getCell(6).setCellValue(businessData.getNewUsers());// 获取第5行row = sheet.getRow(4);row.getCell(2).setCellValue(businessData.getValidOrderCount());row.getCell(4).setCellValue(businessData.getUnitPrice());// 填充明细数据for (int i = 0; i < 30; i++) {LocalDate date = dateBegin.plusDays(i);// 查询某一天的数据BusinessDataVO businessDataVO = workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));// 获得某一行row = sheet.getRow(7 + i);row.getCell(1).setCellValue(date.toString());row.getCell(2).setCellValue(businessDataVO.getTurnover());row.getCell(3).setCellValue(businessDataVO.getValidOrderCount());row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());row.getCell(5).setCellValue(businessDataVO.getUnitPrice());row.getCell(6).setCellValue(businessDataVO.getNewUsers());}// 3. 通过输出流将Excel文件下载到客户端浏览器ServletOutputStream out = response.getOutputStream();excel.write(out);// 关闭资源out.close();excel.close();} catch (IOException e) {throw new RuntimeException(e);}}

代码细节补充:
workspaceService.getBusinessData:

@Overridepublic BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end) {/*** 营业额:当日完成订单的总额* 有效订单:当日完成订单的数量* 订单完成率:有效订单数 / 总订单数* 新增用户:当日新增用户的数量*/Map map = new HashMap();map.put("begin",begin);map.put("end",end);// 查询订单总数Integer totalOrderCount = orderMapper.getByMap(map);map.put("status", Orders.COMPLETED);// 营业额Double turnover = orderMapper.sumByMap(map);turnover = turnover ==null? 0.0 :turnover;// 有效订单数Integer validOrderCount = orderMapper.getByMap(map);Double unitPrice = 0.0;Double orderCompletionRate = 0.0;if(totalOrderCount != 0 && validOrderCount != 0){// 订单完成率orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;//平均客单价unitPrice = turnover / validOrderCount;}// 新增用户数Integer newUsers = userMapper.countByMap(map);return BusinessDataVO.builder().turnover(turnover).validOrderCount(validOrderCount).orderCompletionRate(orderCompletionRate).unitPrice(unitPrice).newUsers(newUsers).build();}

实现效果:
在这里插入图片描述

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

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

相关文章

SQL无列名注入

SQL无列名注入 ​ 前段时间&#xff0c;队里某位大佬发了一个关于sql注入无列名的文章&#xff0c;感觉好像很有用&#xff0c;特地研究下。 关于 information_schema 数据库&#xff1a; ​ 对于这一个库&#xff0c;我所知晓的内容并不多&#xff0c;并且之前总结SQL注入的…

【数据结构】_包装类与泛型

目录 1. 包装类 1.1 基本数据类型和对应的包装类 1.2 &#xff08;自动&#xff09;装箱和&#xff08;自动&#xff09;拆箱 1.2.1 装箱与拆箱 1.2.2 自动&#xff08;显式&#xff09;装箱与自动&#xff08;显式&#xff09;拆箱 1.3 valueOf()方法 2. 泛型类 2.1 泛…

【深度学习笔记】计算机视觉——目标检测和边界框

目标检测和边界框 前面的章节&#xff08;例如 sec_alexnet— sec_googlenet&#xff09;介绍了各种图像分类模型。 在图像分类任务中&#xff0c;我们假设图像中只有一个主要物体对象&#xff0c;我们只关注如何识别其类别。 然而&#xff0c;很多时候图像里有多个我们感兴趣…

某大型制造企业数字化转型规划方案(附下载)

目录 一、项目背景和目标 二、业务现状 1. 总体应用现状 2. 各模块业务问题 2.1 设计 2.2 仿真 2.3 制造 2.4 服务 2.5 管理 三、业务需求及预期效果 1. 总体业务需求 2. 各模块业务需求 2.1 设计 2.2 仿真 2.3 制造 2.4 服务 2.5 管理 四、…

数字化转型导师坚鹏:证券公司数字化营销

证券公司数字化营销 ——借力数字化技术实现零售业务的批量化、精准化、场景化、智能化营销 课程背景&#xff1a; 很多证券公司存在以下问题&#xff1a; 不知道如何提升证券公司数字化营销能力&#xff1f; 不知道证券公司如何开展数字化营销工作&#xff1f; 不知道…

Java虚拟机 - JVM

JVM的内存区域划分 JVM它其实也是一个进程,进程运行的过程中,会从操作系统中申请一些资源.内存就是其中的一种.这些内存就支撑了java程序的运行.JVM从系统中申请的一大块内存,会根据实际情况和使用用途来划分出不同的空间,这个就是区域划分.它一般分为 堆区, 栈区, 程序计数器…

springboot240基于Spring boot的名城小区物业管理系统

基于Spring boot的名城小区物业管理系统的设计与实现 摘要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。以前相关行业对于物业信息的管理和控制&#xff0c;采用人工登记的方式保存相关数…

InnoDB存储引擎对MVCC的实现

MVCC MVCC的目的 在搞清楚MVCC之前,我们要搞懂一个问题,MVCC到底解决的是什么问题? 我用一句话概括,那就是为了解决读-写可以一起的问题! 在我们的印象里,InnoDB可以读读并发,不能读写并发,或者写写并发 这是很正常的想法,因为如果读写并发的化,会有并发问题 而对于写写…

构建安全的REST API:OAuth2和JWT实践

引言 大家好&#xff0c;我是小黑&#xff0c;小黑在这里跟咱们聊聊&#xff0c;为什么REST API这么重要&#xff0c;同时&#xff0c;为何OAuth2和JWT在构建安全的REST API中扮演着不可或缺的角色。 想象一下&#xff0c;咱们每天都在使用的社交媒体、在线购物、银行服务等等…

Sqli-labs靶场第16关详解[Sqli-labs-less-16]自动化注入-SQLmap工具注入

Sqli-labs-Less-16 #自动化注入-SQLmap工具注入 SQLmap用户手册&#xff1a;文档介绍 - sqlmap 用户手册 以非交互式模式运行 --batch 当你需要以批处理模式运行 sqlmap&#xff0c;避免任何用户干预 sqlmap 的运行&#xff0c;可以强制使用 --batch 这个开关。这样&#xff0…

GC机制以及Golang的GC机制详解

要了解Golang的GC机制,就需要了解什么事GC,以及GC有哪几种实现方式 一.什么是GC 当一个电脑上的动态内存不再需要时&#xff0c;就应该予以释放&#xff0c;以让出内存&#xff0c;这种内存资源管理&#xff0c;称为垃圾回收&#xff08;Garbage Collection&#xff09;&#x…

最长上升子序列(LIS)简介及其例题分析

一.最长上升子序列&#xff08;LIS&#xff09;的相关知识 1.最长上升子序列&#xff08;Longest Increasing Subsequence&#xff09;&#xff0c;简称LIS&#xff0c;也有些情况求的是最长非降序子序列&#xff0c;二者区别就是序列中是否可以有相等的数。假设我们有一个序…

【论文笔记】Initializing Models with Larger Ones

Abstract 介绍权重选择&#xff0c;一种通过从预训练模型的较大模型中选择权重子集来初始化较小模型的方法。这使得知识从预训练的权重转移到更小的模型。 它还可以与知识蒸馏一起使用。 权重选择提供了一种在资源受限的环境中利用预训练模型力量的新方法&#xff0c;希望能够…

【Linux】软件管理yum | 编辑器vim | vim插件安装

目录 1. Linux软件管理yum 1.1 什么是软件包 1.2 查看软件包 1.3 如何安装软件 1.4 如何卸载软件 2. Linux编辑器vim 2.1 vim的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 2.5 简单vim配置 2.6 插件安装 1. Vim-Plug 3. coc.nvim …

如何自己系统的学python

学习Python是一项很好的投资&#xff0c;因为它是一种既强大又易于学习的编程语言&#xff0c;适用于多种应用&#xff0c;如数据分析、人工智能、网站开发等。下面是一个系统学习Python的步骤建议&#xff1a; 基础准备 安装Python&#xff1a; 访问Python官网下载最新版本的…

微信小程序-生命周期

页面生命周期 onLoad: 页面加载时触发的方法&#xff0c;在这个方法中可以进行页面初始化的操作&#xff0c;如获取数据、设置页面状态等。 onShow: 页面显示时触发的方法&#xff0c;在用户进入页面或从其他页面返回该页面时会调用此方法。可以在此方法中进行页面数据刷新、动…

Onenote软件新建笔记本时报错:无法在以下位置新建笔记本

报错现象&#xff1a; 当在OneNote软件上&#xff0c;新建笔记本时&#xff1a; 然后&#xff0c;尝试重新登录微软账户&#xff0c;也不行&#xff0c;提示报错&#xff1a; 解决办法&#xff1a; 打开一个新的记事本&#xff0c;复制粘贴以下内容&#xff1a; C:\Users\Adm…

Mysql中的事务

什么是事务&#xff1a; 多条sql语句&#xff0c;要么全部成功&#xff0c;要么全部失败。 事务的特性&#xff1a; 1&#xff1a;原子性(Atomic)&#xff1a; 组成一个事务的多个数据库操作是一个不可分割的原子单元&#xff0c;只有所有操作都成功&#xff0c;整个事务才会…

C++调用lua函数

C 调用Lua全局变量(普通) lua_getglobal(lua, "width");int width lua_tointeger(lua,-1);lua_pop(lua,1);std::cout << width << std::endl;lua_close(lua); 这几行代码要放到lua_pcall(lua, 0,0,0);之后才可以. C给lua传递变量 lua_pushstring(lua, …

Python 操作 Excel,如何又快又好?

➤数据处理是 Python 的一大应用场景&#xff0c;而 Excel 则是最流行的数据处理软件。因此用 Python 进行数据相关的工作时&#xff0c;难免要和 Excel 打交道。Python处理Excel 常用的系列库有&#xff1a;xlrd、xlwt、xlutils、openpyxl ◈xlrd &#xff0d; 用于读取 Exce…