Poi实现复杂Excel导出,理解POI操作Excel思路!!!

news/2024/7/21 6:59:17 标签: excel, java

前言

对于简单excel报表导出,有很多简单的工具如easypoi,而且现在网上已经有很多工具类整合easypoi使用起来非常方便。但是简单的弊端往往无法适配一些负责场景,而我们实际生产中面临的都是客户自定以的一个负责报表导出,这是利用原始的poi去操作,不仅思路上清晰而且实现起来并不复杂。

比如导出下面格式报表:

这个表格算是典型的各个复杂场景都包含,有表头占两行、有表头占三列、有两级表头。。。

easypoi可以实现,但我们需要在实体类注解控制,甚至表格在复杂一些就处理不了了。

下面我们使用poi实现这种类型表格导出,包括表格内各种样式、字体等,理论上学会这套任何复杂报表都能实现,牛~~~

思路

POI操作Excel文档核心五步,文档操作都离不开这五步。

1、创建workbook,XSSFWorkbook创建的是.xlsx后缀文件,HSSFWorkbook创建的是.xls后缀文件

java">XSSFWorkbook workbook = new XSSFWorkbook();

2、根据workboot创建sheet

java">XSSFSheet sheet = workbook.createSheet("用户信息");

3、根据sheet创建行

java">XSSFRow row = sheet.createRow(0);

4、根据行创建单元格

java">XSSFCell cell = row.createCell(0);

5、往单元格填充数据

java">cell.setCellValue("测试");

过上面五步,我们就往excel中第一行第一个单元格插入了“测试”数据,任何复杂操作都是基于上面过程实现。

代码

java">public void export(HttpServletResponse response) {
    // 创建workbook,XSSFWorkbook创建的是.xlsx后缀文件,HSSFWorkbook创建的是.xls后缀文件
    XSSFWorkbook workbook = new XSSFWorkbook();
    // 创建sheet,并命名
    XSSFSheet sheet = workbook.createSheet("用户信息");

    // 创建标题行,坐标从0开始
    XSSFRow row0 = sheet.createRow(0);
    // 创建0行中第一个单元格,坐标从0开始
    XSSFCell cell00 = row0.createCell(0);
    // 填充当前单元格数据
    cell00.setCellValue("用户信息表");
    // 表头行占6列,需要合并,参数介绍:开始行、结束行、开始列、结束列。
    // 通过设置当前参数,合并单元格,比如下面表示行合并0-0行,列合并0-5列
    CellRangeAddress cellAddresses0 = new CellRangeAddress(0, 0, 0, 5);
    sheet.addMergedRegion(cellAddresses0);

    // 创建第二行表头
    XSSFRow row1 = sheet.createRow(1);
    // 填充表头数据
    XSSFCell cell10 = row1.createCell(0);
    cell10.setCellValue("编号");
    XSSFCell cell11 = row1.createCell(1);
    cell11.setCellValue("姓名");
    XSSFCell cell12 = row1.createCell(2);
    cell12.setCellValue("年龄");
    XSSFCell cell13 = row1.createCell(3);
    cell13.setCellValue("兴趣");
    // 对第二行表头进行单元格合并
    CellRangeAddress cellAddresses1 = new CellRangeAddress(1, 2, 0, 0);
    sheet.addMergedRegion(cellAddresses1);
    CellRangeAddress cellAddresses2 = new CellRangeAddress(1, 2, 1, 1);
    sheet.addMergedRegion(cellAddresses2);
    CellRangeAddress cellAddresses3 = new CellRangeAddress(1, 2, 2, 2);
    sheet.addMergedRegion(cellAddresses3);
    CellRangeAddress cellAddresses4 = new CellRangeAddress(1, 1, 3, 5);
    sheet.addMergedRegion(cellAddresses4);

    // 创建第三行表头
    XSSFRow row2 = sheet.createRow(2);
    // 填充表头数据
    XSSFCell cell23 = row2.createCell(3);
    cell23.setCellValue("兴趣1");
    XSSFCell cell24 = row2.createCell(4);
    cell24.setCellValue("兴趣2");
    XSSFCell cell25 = row2.createCell(5);
    cell25.setCellValue("兴趣3");

    // 填充数据(根据具体业务)
    for (int i = 0; i < 10; i++) {
        // 创建数据行(数据行是从第四行开始)
        XSSFRow rowTemp = sheet.createRow(i + 3);
        // 按顺序往单元格填充数据
        XSSFCell cell0 = rowTemp.createCell(0);
        cell0.setCellValue(i);
        XSSFCell cell1 = rowTemp.createCell(1);
        cell1.setCellValue("z" + i);
        XSSFCell cell2 = rowTemp.createCell(2);
        cell2.setCellValue(18 + i);
        XSSFCell cell3 = rowTemp.createCell(3);
        cell3.setCellValue("兴趣" + i);
        XSSFCell cell4 = rowTemp.createCell(4);
        cell4.setCellValue("兴趣" + i);
        XSSFCell cell5 = rowTemp.createCell(5);
        cell5.setCellValue("兴趣" + i);
    }

    response.reset();
    try {
        ServletOutputStream outputStream = response.getOutputStream();
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-Type", "application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户信息表.xlsx", "UTF-8"));
        workbook.write(outputStream);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

导出后:

当然这还没有完全结束,实际生产中我们都是需要对表格格式去处理,比如我们需要把标题居中对齐,可以在基础上通过添加下面代码实现:

通过workboot创建样式=》设置当前样式类型(居中还是左对齐之类的)=》哪个单元格需要就设置哪个单元格

比如我们想要添加标题背景颜色,可以添加下面格式:

下面是一些常见的格式,总结给出:

java">    /**
     * 设置单元格样式
     *
     */
    public void setCellStyle(Workbook workbook){
        //设置单元格背景颜色
        Sheet sheet=workbook.getSheetAt(0);
        Row row=sheet.getRow(0);
        Cell cell=row.getCell(0);
        CellStyle style = workbook.createCellStyle();
        style.cloneStyleFrom(cell.getCellStyle());
        //设置背景颜色
        style.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        //设置自动换行
        style.setWrapText(true);
 
        //设置字体样式
        Font font= row.getSheet().getWorkbook().createFont();
        //默认字体为宋体
        font.setFontName("宋体");
        //设置字体大小
        font.setFontHeight((short) 18);
        //设置字体颜色
        font.setColor(IndexedColors.BLUE_GREY.getIndex());
        //设置字体加粗
        font.setBold(true);
        //设置字体斜体
        font.setItalic(true);
        //设置字体下划线
        font.setUnderline(Font.U_SINGLE);
        //设置字体上标下标
        font.setTypeOffset(Font.SS_SUPER);
        //设置字体删除线
        font.setStrikeout(true);
        style.setFont(font);
 
        //边框样式
        //设置上边框线条类型
        style.setBorderTop(BorderStyle.THIN);
        //设置右边框线条类型
        style.setBorderRight(BorderStyle.THIN);
        //设置下边框线条类型
        style.setBorderBottom(BorderStyle.THIN);
        //设置左边框线条类型
        style.setBorderLeft(BorderStyle.THIN);
        //设置上边框线条颜色
        style.setTopBorderColor(IndexedColors.BLUE_GREY.getIndex());
        //设置右边框线条颜色
        style.setRightBorderColor(IndexedColors.BLUE_GREY.getIndex());
        //设置下边框线条颜色
        style.setBottomBorderColor(IndexedColors.BLUE_GREY.getIndex());
        //设置左边框线条颜色
        style.setLeftBorderColor(IndexedColors.BLUE_GREY.getIndex());
 
        //对齐方式
        //设置水平对齐方式
        style.setAlignment(HorizontalAlignment.CENTER);
        //设置垂直对齐方式
        style.setVerticalAlignment(VerticalAlignment.CENTER);
 
        //设置列宽行高
        //设置自适应列宽
        sheet.setDefaultColumnWidth(0);
        //自定义列宽
        sheet.setColumnWidth(0,10);
        //自定义行高
        row.setHeight((short)10);
 
        //冻结行和列
        sheet.createFreezePane(1, 1);
 
        //合并单元格
        CellRangeAddress cellRangeAddress = new CellRangeAddress(1, 1, 1, 2);
        sheet.addMergedRegionUnsafe(cellRangeAddress);
    }

总结,通过核心五步就可以实现创建excel并往对应单元格填充数据,中间通过合并或相应格式实现复杂表格设计。


http://www.niftyadmin.cn/n/5277265.html

相关文章

docker 与 ffmpeg

创建容器 docker run -it -v /mnt/f/ffmpeg:/mnt/f/ffmpeg --name ffmpeg 49a981f2b85f /bin/bash 在 Linux 上编译 FFmpeg&#xff1a; 安装依赖库&#xff1a; sudo apt-get update sudo apt-get install build-essential yasm cmake libtool libc6 libc6-dev unzip wget下…

【第七在线】数据分析与人工智能在商品计划中的应用

随着技术的不断进步&#xff0c;数据分析和人工智能&#xff08;AI&#xff09;已经成为了现代商品计划的关键组成部分。在服装行业&#xff0c;这两项技术正在帮助企业更好地理解市场需求、优化库存管理、提高生产效率和提供更好的客户体验。本文将深入探讨数据分析和人工智能…

基于SSM+Vue的新闻管理系统

基于SSMVue的新闻管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 新闻列表 管理员界面 用户界面 摘要 新闻管理系统基于SSM&#xff08;Spr…

〖大前端 - 基础入门三大核心之JS篇(58)〗- 面向对象案例

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

Postgresql处理JSON类型中替换某个属性值问题

一、问题描述 使用postgresql对json的特性使用sql批量处理json中某个属性的值 结构如下&#xff1a; {"id": 1,"parentId": 123,"globalParameters": [{"value": "date","boardId": 123,"canReName":…

CVE-2022-34625 mealie jinja2 SSTI注入

安装 官方指导&#xff1a;https://docs.mealie.io/documentation/getting-started/install/ docker search mealie docker pull hkotel/mealie docker run -p 9925:80 -v pwd:/app/data/ -d hkotel/mealie:latest记得-d使其在后台运行&#xff0c;否则主机命令行会一直被回显…

xcode上传app store connect后testflight没有可构建版本的原因

查看你的邮箱, 里面有原因提示 一般为使用了某些权限, 但是plist没有声明 xcode 修改display name后名字并没有改变 原因是并没有修改到plist的CFBundleDisplayName的字段 将CFBundleDisplayName的值修改为${INFOPLIST_KEY_CFBundleDisplayName} INFOPLIST_KEY_CFBundleDispla…

51单片机简易出租车计费系统仿真设计

51单片机简易出租车计费系统仿真设计( proteus仿真程序报告讲解视频&#xff09; 仿真图proteus 8.9及以上 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;S0036 1.主要功能&#xff1a; 出租车计费系统设计内容&#xff1a; 1、…