Java在excel中导出动态曲线图DEMO

news2025/4/27 15:24:13

1、环境

JDK8

POI 5.2.3

Springboot2.7

2、DEMO

pom

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.3</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

java

    @GetMapping("/export")
    public ResponseEntity<byte[]> exportExcel() throws IOException {
        // 创建工作簿和工作表
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Chart");

        // 自定义数据源
        List<String> xValues = Arrays.asList("A", "B", "C", "D", "E");
        List<Double> line1Values = Arrays.asList(10.0, 15.0, 20.0, 25.0, 30.0);
        List<Double> line2Values = Arrays.asList(5.0, 7.0, 9.0, 11.0, 13.0);

        XSSFSheet hiddenSheet = workbook.createSheet("Hidden Data");
        workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true);

        Row hiddenRow = hiddenSheet.createRow(0);
        for (int i = 0; i < xValues.size(); i++) {
            Cell cell = hiddenRow.createCell(i);
            cell.setCellValue(xValues.get(i));
        }

        for (int i = 0; i < 10; i++) {
            createChart("title" + i, sheet,hiddenSheet,i,xValues,line1Values,i%2 == 0 ? line2Values: null);
        }








        // 将工作簿写入字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        workbook.close();

        // 设置响应头
        HttpHeaders headersResponse = new HttpHeaders();
        headersResponse.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headersResponse.setContentDispositionFormData("attachment", "chart.xlsx");

        return new ResponseEntity<>(outputStream.toByteArray(), headersResponse, HttpStatus.OK);
    }


    private void createChart(String title, XSSFSheet sheet, XSSFSheet hiddenSheet, int index, List<String> xValues, List<Double> line1Values, List<Double> line2Values) {
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 5, index * 21, 15, index * 21 + 20);

        XSSFChart chart = drawing.createChart(anchor);
        chart.setTitleText(title);
        chart.setTitleOverlay(false);

        XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        xAxis.setTitle(" ");
        XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);
        yAxis.setTitle(" ");


        XDDFDataSource<String> xs = XDDFDataSourcesFactory.fromStringCellRange(
                hiddenSheet,
                new CellRangeAddress(0, 0, 0,  xValues.size() - 1)
        );


        XDDFLineChartData lineChartData = (XDDFLineChartData) chart.createData(ChartTypes.LINE, xAxis, yAxis);

        XDDFNumericalDataSource<Double> line1 = XDDFDataSourcesFactory.fromArray(line1Values.toArray(new Double[0]));
        XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) lineChartData.addSeries(xs, line1);

        if (CollUtil.isNotEmpty(line2Values)) {
            XDDFNumericalDataSource<Double> line2 = XDDFDataSourcesFactory.fromArray(line2Values.toArray(new Double[0]));
            XDDFLineChartData.Series series2 = (XDDFLineChartData.Series) lineChartData.addSeries(xs, line2);
        }

        chart.plot(lineChartData);

    }

说明,封装了一个方法,createChart。

图表位置

XSSFClientAnchor anchor = drawing.createAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2);

参数说明:

  • dx1dy1

    • 表示图表左上角相对于单元格左上角的偏移量(以 EMU 为单位)。
    • 1 EMU = 1/360000 厘米。
    • 如果你不需要精确控制偏移量,可以将这两个值设置为 0
  • dx2dy2

    • 表示图表右下角相对于单元格右下角的偏移量(以 EMU 为单位)。
    • 同样,如果你不需要精确控制偏移量,可以将这两个值设置为 0
  • col1row1

    • 表示图表左上角所在的单元格列号和行号(从 0 开始计数)。
    • 例如,col1 = 5 表示图表左上角位于第 6 列(F 列),row1 = 0 表示图表左上角位于第 1 行。
  • col2row2

    • 表示图表右下角所在的单元格列号和行号(从 0 开始计数)。
    • 例如,col2 = 15 表示图表右下角位于第 16 列(P 列),row2 = 20 表示图表右下角位于第 21 行。

hiddenSheet存在的目的是

1. Apache POI 的图表数据绑定机制

Apache POI 的图表功能是基于 Excel 的底层结构设计的。在 Excel 中,图表的数据源通常是从工作表中的单元格范围(CellRangeAddress)中读取的。也就是说,图表的 X 轴和 Y 轴数据必须绑定到某个单元格范围,即使这些单元格并不直接显示在工作表中。

核心原因:

  • Apache POI 的 XDDFDataSourcesFactory.fromStringCellRange() 方法要求传入一个有效的单元格范围。
  • 如果没有单元格范围,POI 不知道如何为图表提供数据源,因此会导致图表无法正确显示。

所以我采用了还是用了隐藏的方式。对于整个sheet的布局

3、效果

有个小bug

这个系列1这几个字去不掉,图表工具提示中的“系列名称”(如“系列1”)是由 Excel 自动生成的。虽然 Apache POI 不支持直接修改或自定义工具提示的内容

一下方法可以一试。

  // 隐藏图例(可选)
    XDDFChartLegend legend = chart.getOrAddLegend();
    legend.setPosition(LegendPosition.TOP); // 将图例移出可视区域

对于目前项目而言,影响不大。不改动了

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

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

相关文章

Kotlin Multiplatform--02:项目结构进阶

Kotlin Multiplatform--02&#xff1a;项目结构进阶 引言正文 引言 在上一章中&#xff0c;我们对 Kotlin Multiplatform 项目有了基本的了解&#xff0c;已经可以进行开发了。但我们只是使用了系统默认的项目结构。本章介绍了如何进行更复杂的项目结构管理。 正文 在上一章中&…

代码随想录算法训练营第五十八天 | 1.拓扑排序精讲 2.dijkstra(朴素版)精讲 卡码网117.网站构建 卡码网47.参加科学大会

1.拓扑排序精讲 题目链接&#xff1a;117. 软件构建 文章讲解&#xff1a;代码随想录 思路&#xff1a; 把有向无环图进行线性排序的算法都可以叫做拓扑排序。 实现拓扑排序的算法有两种&#xff1a;卡恩算法&#xff08;BFS&#xff09;和DFS&#xff0c;以下BFS的实现思…

linux ptrace 图文详解(七) gdb、strace跟踪系统调用

目录 一、gdb/strace 跟踪程序系统调用 二、实现原理 三、代码实现 四、总结 &#xff08;代码&#xff1a;linux 6.3.1&#xff0c;架构&#xff1a;arm64&#xff09; One look is worth a thousand words. —— Tess Flanders 相关链接&#xff1a; linux ptrace 图…

【前端】ES6 引入的异步编程解决方案Promise 详解

Promise 详解 1. 基本概念 定义&#xff1a;Promise 是 ES6 引入的异步编程解决方案&#xff0c;表示一个异步操作的最终完成&#xff08;或失败&#xff09;及其结果值。核心作用&#xff1a;替代回调函数&#xff0c;解决“回调地狱”问题&#xff0c;提供更清晰的异步流程控…

const(C++)

打印出来的结果是 a是12 *p是200 const修饰指针 const修饰引用

python21-循环小作业

课程&#xff1a;B站大学 记录python学习&#xff0c;直到学会基本的爬虫&#xff0c;使用python搭建接口自动化测试就算学会了&#xff0c;在进阶webui自动化&#xff0c;app自动化 循环语句小作业 for-in作业斐波那契 for 固定数值计算素数字符统计数字序列range 函数 水仙花…

小白电路设计-设计11-恒功率充电电路设计

介绍 作为电子信息工程的我&#xff0c;电路学习是一定要学习的&#xff0c;可惜目前作为EMC测试工程师&#xff0c;无法兼顾太多&#xff0c;索性不如直接将所学的知识进行运用&#xff0c;并且也可以作为契机&#xff0c;进行我本人的个人提升。祝大家与我一起进行提升。1.本…

Spring AI 快速入门:从环境搭建到核心组件集成

Spring AI 快速入门&#xff1a;从环境搭建到核心组件集成 一、前言&#xff1a;Java开发者的AI开发捷径 对于Java生态的开发者来说&#xff0c;将人工智能技术融入企业级应用往往面临技术栈割裂、依赖管理复杂、多模型适配困难等挑战。Spring AI的出现彻底改变了这一局面——…

http://noi.openjudge.cn/——2.5基本算法之搜索——200:Solitaire

文章目录 题目宽搜代码总结 题目 总时间限制: 5000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB 描述 Solitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered from 1 to 8, from the top to the bottom and from left t…

架构师面试(三十六):广播消息

题目 在像 IM、短视频、游戏等实时在线类的业务系统中&#xff0c;一般会有【广播消息】业务&#xff0c;这类业务具有瞬时高流量的特点。 在对【广播消息】业务实现时通常需要同时写 “系统消息库” 和更新用户的 “联系人库” 的操作&#xff0c;用户的联系人表中会有未读数…

TortoiseGit使用图解

前言 记录GitTortoiseGit使用&#xff0c;记录下开发中常用命令&#xff0c;健忘时用到方知好。 TortoiseGit使用 图解 commit-提交代码 pull-拉取远程分支最新代码 push-将本地分支代码推送到远程分支 show log-查看分支提交记录 show log - 切换分支查看 show log - 远程分…

【时时三省】(C语言基础)循环程序举例

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 例题: 用公式4/π≈1-3/1+5/1-7/1+...求π的近似值,直到发现某一项的绝对值小于10的-6次方为止(该项不累加)。 解题思路: 这是求值的近似方法中的一种。求π值可以用不同的近似方法。如下面的表达式都可以…

珍爱网:从降本增效到绿色低碳,数字化新基建价值凸显

2024年12月24日&#xff0c;法大大联合企业绿色发展研究院发布《2024签约减碳与低碳办公白皮书》&#xff0c;深入剖析电子签在推动企业绿色低碳转型中的关键作用&#xff0c;为企业实现环境、社会和治理&#xff08;ESG&#xff09;目标提供新思路。近期&#xff0c;法大大将陆…

电子电子架构 --- 主机厂视角下ECU开发流程

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

PyQt6基础_QTableWidget

目录 描述&#xff1a; 代码 演示 描述&#xff1a; 1 单击选中一行 2 右键菜单 3 填充数据 4 提取行数据 5 删除行数据 代码 from PyQt6.QtCore import (Qt ) from PyQt6.QtGui import ( QAction ) from PyQt6.QtWidgets import (QApplication,QAbstractItemView,QL…

uniapp 上传二进制流图片

文章目录 场景&#x1f7e2;一、步骤1.1、选择图片1.2、 读取图片为二进制数据1.3、上传二进制数据到服务器 &#x1f7e2;二、项目案例2.1、替换头像案例2.1、uView u-upload 上传封面 &#x1f7e2; 三、关键注意事项3.1 二进制流与 FormData 区别3.2 性能优化3.3 跨平台适配…

赛灵思 XCKU115-2FLVB2104I Xilinx Kintex UltraScale FPGA

XCKU115-2FLVB2104I 是 AMD Xilinx Kintex UltraScale FPGA&#xff0c;基于 20 nm 先进工艺&#xff0c;提供高达 1 451 100 个逻辑单元&#xff08;Logic Cells&#xff09;&#xff0c;77 721 600 bit 的片上 RAM 资源&#xff0c;以及 5 520 个 DSP 切片&#xff08;DSP48E…

Unreal Niagara制作SubUV贴图翻页动画

SubUV翻页动画是游戏中的常见功能&#xff0c;通过对每一小块UV进行移动可以模拟动画效果&#xff0c;接下来对下图进行SubUV动画的制作。 (金币测试图下载地址&#xff1a;https://download.csdn.net/download/grayrail/90684422&#xff09; 最终效果如下&#xff1a; 1.…

「零配置陷阱」:现代全栈工具链的复杂度管控实践

一、工具链膨胀的「死亡螺旋」 2024年典型全栈项目的初始化噩梦&#xff1a; $ npm create vitelatest ✔ Project name: … demo ✔ Select a framework: › React ✔ Select a variant: › TypeScript SWC ✔ Install shadcn/ui? … Yes ✔ Add Storybook? … Yes ✔ Co…

金仓数据库KingbaseES技术实践类深度剖析与实战指南

一、语法兼容及迁移实战 &#xff08;一&#xff09;语法兼容的多元魅力 在当今多元化的数据库应用环境中&#xff0c;金仓数据库管理系统KingbaseES凭借其卓越的语法兼容能力脱颖而出。它采用的融合数据库架构&#xff0c;通过多语法体系一体化架构&#xff0c;实现了对Orac…