Apache POI(使用Java读写Excel表格数据)

1.Apache POI简介

Apache POI是一个开源的Java库,用于操作Microsoft Office格式的文件。它支持各种Office文档的读写功能,包括Word文档、Excel电子表格、PowerPoint演示文稿、Outlook电子邮件等。Apache POI提供了一组API,使得Java开发者能够轻松地在Java应用程序中处理Office文件。

Apache POI的主要特点包括:

  1. 功能丰富:Apache POI提供了广泛的操作,如创建、修改、读取和写入Office文件。

  2. 跨平台:由于它是用Java编写的,因此可以在任何支持Java的平台上运行,包括Windows、Linux和macOS。

  3. 支持多种文件格式:Apache POI支持旧的Office文件格式(如.xls、.doc)和新的Office Open XML格式(如.xlsx、.docx)。

  4. 社区支持:作为一个开源项目,Apache POI有一个活跃的社区,不断更新和改进库。

  5. 易于集成:Apache POI可以轻松地集成到Java应用程序中,无论是桌面应用程序还是Web应用程序。

  6. 灵活的API:Apache POI提供了多种API,以适应不同的操作需求,从简单的文本操作到复杂的样式和格式处理。

Apache POI包含几个主要的组件,每个组件负责处理不同类型的Office文件:

  • POIFS(Poor Obfuscation Implementation File System):用于处理Microsoft Office旧版本的文件格式,如HSSF(Horrible SpreadSheet Format)和HWPF(Horrible Word Processor Format)。
  • XSSF(XML SpreadSheet Format):用于处理Excel 2007及以后版本的XML文件格式(.xlsx)。
  • HSSF(Horrible SpreadSheet Format):用于处理Excel 97-2003版本的文件格式(.xls)。
  • HWPF(Horrible Word Processor Format):用于处理Word 97-2003版本的文件格式(.doc)。
  • XWPF(XML Word Processor Format):用于处理Word 2007及以后版本的XML文件格式(.docx)。
  • HSLF(Horrible Slide Layout Format)和XSLF(XML Slide Layout Format):用于处理PowerPoint演示文稿。
  • HDGF(Horrible Diagram Graphics Format)和XDGF(XML Diagram Graphics Format):用于处理Visio文件。
  • HSMF(Horrible Sticky Note Format):用于处理Outlook电子邮件文件。

Apache POI是Java开发者处理Office文件的首选库,因为它提供了强大的功能和灵活性,同时还得到了广泛的应用和社区支持。

2.引入依赖: 

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.16</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.16</version>
        </dependency>

3. 读写Excel表格 入门示例

3.1 写Excel表格:(如果不存在就创建新的Excel表格,如果已经存在则覆盖Excel表格的内容)

代码:

void write() throws IOException {

    // 创建一个新的Excel工作簿对象
    XSSFWorkbook excel = new XSSFWorkbook();
    
    // 在工作簿中创建一个名为"info"的工作表
    XSSFSheet sheet = excel.createSheet("info");

    // 创建第一行(表头)
    XSSFRow row = sheet.createRow(0);
    // 在第一行创建单元格并设置内容为"姓名"
    row.createCell(0).setCellValue("姓名");
    // 在第一行创建单元格并设置内容为"年龄"
    row.createCell(1).setCellValue("年龄");
    // 在第一行创建单元格并设置内容为"班级"
    row.createCell(2).setCellValue("班级");

    // 创建第二行(数据)
    row = sheet.createRow(1);
    // 在第二行创建单元格并设置内容为"张三"
    row.createCell(0).setCellValue("张三");
    // 在第二行创建单元格并设置内容为"17"
    row.createCell(1).setCellValue("17");
    // 在第二行创建单元格并设置内容为"1班"
    row.createCell(2).setCellValue("1班");

    // 创建第三行(数据)
    row = sheet.createRow(2);
    // 在第三行创建单元格并设置内容为"李四"
    row.createCell(0).setCellValue("李四");
    // 在第三行创建单元格并设置内容为"18"
    row.createCell(1).setCellValue("18");
    // 在第三行创建单元格并设置内容为"2班"
    row.createCell(2).setCellValue("2班");

    // 创建一个文件输出流,指定要写入的文件路径
    FileOutputStream out = new FileOutputStream(new File("D:\\info.xlsx"));
    // 将Excel工作簿写入文件输出流
    excel.write(out);
    // 关闭文件输出流
    out.close();
    // 关闭Excel工作簿,释放资源
    excel.close();
}

生成的Excel表格如下所示: 

 3.2 读Excel表格:

void read() throws IOException {
    // 创建一个文件输入流,用于读取指定路径的Excel文件
    FileInputStream in = new FileInputStream(new File("D:\\info.xlsx"));

    // 使用文件输入流创建一个XSSFWorkbook对象,该对象代表整个Excel工作簿
    XSSFWorkbook excel = new XSSFWorkbook(in);
    
    // 从工作簿中获取第一个工作表,索引为0
    XSSFSheet sheet = excel.getSheetAt(0);

    // 获取工作表中最后一行的编号
    int lastRowNum = sheet.getLastRowNum();

    // 遍历工作表中的所有行,包括空行和有数据的行
    for(int i = 0; i <= lastRowNum; i++) {
        // 获取指定编号的行
        XSSFRow row = sheet.getRow(i);

        // 如果行不为空,则读取第一个和第二个单元格的数据
        if(row != null) {
            // 获取第一个单元格的数据,并转换为字符串
            String cellValue1 = row.getCell(0).getStringCellValue();
            // 获取第二个单元格的数据,并转换为字符串
            String cellValue2 = row.getCell(1).getStringCellValue();
            // 打印单元格的数据
            System.out.println(cellValue1 + " " + cellValue2);
        }
    }

    // 关闭文件输入流,释放资源
    in.close();
    
    // 关闭XSSFWorkbook对象,释放资源
    excel.close();
}

4.导出Excel表格数据

4.1 设计Excel模版文件

4.2 根据该模版表格创建实体BusinessDataVO 

/**
 * 数据概览
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BusinessDataVO implements Serializable {

    private Double turnover;//营业额

    private Integer validOrderCount;//有效订单数

    private Double orderCompletionRate;//订单完成率

    private Double unitPrice;//平均客单价

    private Integer newUsers;//新增用户数

}

4.3 Controller:

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

4.4 ServiceImple:(实现exportBusinessData方法)

    /**
     * 导出运营数据报表
     * @param response
     */
    public void exportBusinessData(HttpServletResponse response) {
        //1. 查询数据库,获取营业数据---查询最近30天的运营数据
        LocalDate dateBegin = LocalDate.now().minusDays(30);
        LocalDate dateEnd = LocalDate.now().minusDays(1);

        //查询概览数据
        BusinessDataVO businessDataVO = 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(businessDataVO.getTurnover());
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());

            //获得第5行
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice());

            //填充明细数据
            for (int i = 0; i < 30; i++) {
                LocalDate date = dateBegin.plusDays(i);
                //查询某一天的营业数据
                BusinessDataVO businessData = 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(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(6).setCellValue(businessData.getNewUsers());
            }

            // 设置内容类型为Excel文件
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            // 设置内容处置为附件,并指定文件名
            response.setHeader("Content-Disposition", "attachment; filename=\"business_data.xlsx\"");


            //3. 通过输出流将Excel文件下载到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            //关闭资源
            out.close();
            excel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

说明:其中 workspaceService.getBusinessData(LocalDateTime begin, LocalDateTime end)方法是获取时间段统计营业数据即根据时间段获取BusinessDataVO的相应数据

    /**
     * 根据时间段统计营业数据
     * @param begin
     * @param end
     * @return
     */
    public BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end) {
        /**
         * 营业额:当日已完成订单的总金额
         * 有效订单:当日已完成订单的数量
         * 订单完成率:有效订单数 / 总订单数
         * 平均客单价:营业额 / 有效订单数
         * 新增用户:当日新增用户的数量
         */

        Map map = new HashMap();
        map.put("begin",begin);
        map.put("end",end);

        //查询总订单数
        Integer totalOrderCount = orderMapper.countByMap(map);

        map.put("status", Orders.COMPLETED);
        //营业额
        Double turnover = orderMapper.sumByMap(map);
        turnover = turnover == null? 0.0 : turnover;

        //有效订单数
        Integer validOrderCount = orderMapper.countByMap(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();
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Mybatis】动态SQL标签2

choose (when, otherwise)标签是使用举例 类似switch...case&#xff0c;从上到下匹配&#xff0c;找到匹配的条件&#xff0c;就结束匹配其他的&#xff01; set标签是使用举例 set这个标签是用在更新操作上的 set标签代替sql中的set关键字&#xff0c;可以把set语句后多余的…

【精选案例】Sellfy | 电子商务平台怎么利用客户裂变系统实现用户增长?

Sellfy是一种基于云的电子商务解决方案&#xff0c;特别为数字内容创作者所设计。 一、主要目标用户&#xff1a; Sellfy主要针对的是包括作家、插画家、设计师、音乐家和电影制作人在内的数字内容创作者&#xff0c;他们可以在Sellfy上在线销售自己的产品。 二、平台特点&a…

商淘云电商分账系统如何为企业降低连锁财务成本

当今激烈的市场竞争中&#xff0c;连锁品牌企业面临着多样化的挑战&#xff0c;其中财务管理尤为关键。商淘云连锁收银系统作为一款专为连锁品牌量身定制的解决方案&#xff0c;不仅可以帮助企业实现总部入账管控财务、银行结算规范财务的目标&#xff0c;还能通过分账系统优化…

Django里的ModelForm组件

ModelForm组件 自动生成HTML标签 自动读取关联数据表单验证 错误提示数据库进行&#xff1a;新建&#xff0c;修改 步骤如下&#xff1a; 创建类 # 在 views.py 文件里# 创建一个类 class AssetModelForm(forms.ModelForm):class Meta:model models.AssetSet #fields [n…

IDEA完整卸载和破解安装

1、完全卸载IDEA 1.卸载 2、清理注册表 windows R 输入 regedit 打开注册表 3、系统文件清理 C:\用户\${用户名称}\IdeaProjects\ # 如果你想删除 IDEA 相关&#xff0c;则只需要删除 JetBrains 目录下包含 IDEA 的文件夹即可 C:\用户\${用户名称}\AppData\Roaming\JetBra…

NPDP|智造业产品经理的战略智慧与行动之道

在智能制造风起云涌的时代&#xff0c;智造业产品经理的角色愈发重要。他们不仅需要具备深厚的行业知识&#xff0c;更要拥有前瞻的战略眼光和高效的行动能力。那么&#xff0c;智造业产品经理如何进行战略思考与行动呢&#xff1f;本文将为您揭示其中的奥秘。 洞察市场趋势&am…

File类操作文件方法详解及其简单应用

一、File 类介绍 Java 中的 File 类是 java.io 包的一部分&#xff0c;它提供了操作文件和目录的能力。File 类可以用来表示文件系统中的文件或目录。 二、路径 在讲File用法之前咱们先介绍一下路径是什么&#xff1f; 在计算机中&#xff0c;路径&#xff08;Path&#xff0…

Python中__init__.py文件的作用

作用 在Python中,__init__.py 文件有几个重要的作用,主要与包的管理和模块的导入相关。具体来说,它有以下几个功能: 标识包: __init__.py 文件存在的主要目的是标识包含它的目录是一个Python包。没有这个文件,Python解释器不会将该目录视为包的一部分。因此,即使文件夹中…

王炸级产品:字节跳动的Seed-TTS

在人工智能的快速发展中&#xff0c;文本到语音&#xff08;TTS&#xff09;技术已成为连接数字世界与人类沟通的重要桥梁。而字节跳动推出的Seed-TTS模型&#xff0c;无疑是这一领域的一个突破性进展&#xff0c;它以其卓越的性能和高度的自然度&#xff0c;被誉为TTS模型中的…

翻译《The Old New Thing》- What’s with this MSH_MOUSEWHEEL message?

Whats with this MSH_MOUSEWHEEL message? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080806-00/?p21353 Raymond Chen 2008年06月06日 MSH_MOUSEWHEEL 消息是怎么回事&#xff1f; 硬件团队正在研发一种鼠标滚轮设备&#xff0c;并…

14 个必须了解的微服务设计原则

想象一下&#xff0c;一个机场有各种各样的业务&#xff0c;每个部门都是一个精心设计的微服务&#xff0c;专门用于预订、值机和行李处理等特定操作。机场架构必须遵循这个精心设计的架构的基本设计原则&#xff0c;反映微服务的原则。 例如&#xff0c;航空公司独立运营&…

什么是视频号招商团长?如何加入成为视频号招商团长

视频号招商团长&#xff0c;是通过微信视频号平台的线上和线下活动&#xff0c;撮合商家和达人进行合作&#xff0c;帮助商家、达人在视频号成长发展&#xff1b;同时还可以通过邀请内容创作者入驻微信视频号并为其提供支持&#xff1b;从而获取佣金收益的&#xff0c;而其作用…

【西瓜书】4.决策树

1 递归返回情况 &#xff08;1&#xff09;结点包含样本全为同一类别 &#xff08;2&#xff09;属性集为空&#xff0c;没有属性可供划分了 或 有属性&#xff0c;但是在属性上划分的结果都一样 &#xff08;3&#xff09;结点为空结点 **结束时判定该结点的类别遵循如下规则&…

Orange Pi AI Pro 开箱 记录

香橙派 AIpro&#xff08;OrangePi AIpro&#xff09;是一款面向AI开发的强大开发板&#xff0c;提供了高性能和多功能的开发环境。我将结合自己的开发经验&#xff0c;详细介绍这款开发板的性能、适用场景及使用体验。 一、产品概述 香橙派 AIpro配备了强大的硬件配置&#…

101、对称二叉树

给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 题解&#xff1a;要确认是否对称&#xff0c;其实就是要同时遍历左右两边的子树&#xff0c;若某一侧的某个节点与其对称的节点不同&#xff0c;则返回false。 先比较根节点的左右节点&#xff0c;若相同则开始递…

Python 识别图片形式pdf的尝试(未解决)

想识别出pdf页面右下角某处的编号。pdf是图片形式页面。查了下方法&#xff0c;有源码是先将页面提取成jpg&#xff0c;再用pytesseract提取图片文件中的内容。 直接用图片来识别。纯数字的图片&#xff0c;如条形码&#xff0c;可识别。带中文的不可以&#xff0c;很乱。 识别…

uniapp小程序src引用服务器图片时全局变量与图片路径拼接

理论上&#xff0c;应该在main.js中定义一个全局变量&#xff0c;然后在页面的<image>标签上的是src直接使用即可 main.js 页面上 看上去挺靠谱的&#xff0c;实际上小程序后台会报一个错 很明显这种方式小程序是不认的&#xff0c;这就头疼了&#xff0c;还想过另外一个…

Linux本地搭建DataEase并发布公网远程访问进行数据分析

文章目录 前言1. 安装DataEase2. 本地访问测试3. 安装 cpolar内网穿透软件4. 配置DataEase公网访问地址5. 公网远程访问Data Ease6. 固定Data Ease公网地址 前言 DataEase 是开源的数据可视化分析工具&#xff0c;帮助用户快速分析数据并洞察业务趋势&#xff0c;从而实现业务…

MySQL之查询性能优化(八)

查询性能优化 MySQL查询优化器的局限性 MySQL的万能"嵌套循环"并不是对每种查询都是最优的。不过还好&#xff0c;MySQL查询优化器只对少部分查询不适用&#xff0c;而且我们往往可以通过改写查询让MySQL高效地完成工作。还有一个好消息&#xff0c;MySQL5.6版本正…

JavaWeb3 Ajax+Axios+Element+Nginx部署

Ajax 异步JS和XML 1.数据交换&#xff1a;给服务器发送请求&#xff0c;并获取服务器相应的数据 2.异步交互&#xff1a;在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更新部分网页 同步与异步 原生Ajax <!DOCTYPE html> <html> <body><…