☰
声明式编程,图表即代码——JQuick-Excel 图表导出规范解读
2026/10/18 1:57:42 网站建设 项目流程

JQuick-Excel 导出图表使用规范

面向 Java 开发者的 JQuick-Excel 图表导出规范说明。
本文聚焦EXPORT WITH GRAPH = {...}的 DSL 配置、适用边界、代码约束与最佳实践。


更多示例: JQuick-Excel 官网示例 https://www.jquick.org/jquick-excel/#demo-formulas0005

1. 适用范围

JQuick-Excel 当前支持通过 DSL 方式直接导出 Excel 图表,底层基于 Apache POI XSSF / XDDF 实现。

当前支持的图表类型

类型编码图表名称典型场景
COLUMN柱状图分类对比、销售额对比
BAR条形图排名展示、横向比较
BAR3D3D 条形图强展示场景
LINE折线图趋势分析
PIE饼图占比分析
AREA面积图累积趋势
AREA3D3D 面积图强展示场景
SCATTER散点图相关性分析
RADAR雷达图多维能力评估
SURFACE曲面图三维矩阵数据

2. 基本设计原则

图表导出和普通表格导出不同,GRAPH 是“图表驱动”而不是“数据表驱动”。

也就是说:

  • MAPPING/FORMAT/TRANSFORM主要作用于表格单元格导出
  • GRAPH使用的是独立图表数据模型:TYPE、TITLE、CATEGORIES、SERIES
  • 图表数据不会自动从List<Map<String,Object>>中推导,必须在 DSL 中显式声明

建议把 GRAPH 理解为:

一段声明式图表配置 + 一组内嵌类别/序列数据 -> 生成 Excel 图表 Sheet

3. DSL 规范

3.1 标准结构

EXPORT WITH GRAPH = { TYPE = COLUMN, TITLE = "销售数据统计", CATEGORY_AXIS = "产品", VALUE_AXIS = "销量", CATEGORIES = ["产品A", "产品B", "产品C", "产品D"], SERIES = [ { NAME = "第一季度", DATA = [120, 200, 150, 180] }, { NAME = "第二季度", DATA = [180, 210, 190, 220] } ] }

3.2 字段说明

字段是否必填类型说明
TYPE是枚举图表类型
TITLE是String图表标题
CATEGORY_AXIS否String分类轴标题,常用于 X 轴
VALUE_AXIS否String数值轴标题,常用于 Y 轴
CATEGORIES是Array分类集合
SERIES是Array数据系列集合
SERIES[].NAME是String/Identifier系列名称
SERIES[].DATA是Array系列数值集合

4. 数据约束

这是程序员最需要关注的部分。

4.1CATEGORIES.size()必须与每个SERIES.DATA.size()一致

图表工厂内部使用:

  • 第一列写CATEGORIES
  • 后续列逐个写每个SERIES
  • 然后根据单元格区域创建图表数据源

因此必须满足:

每个系列的数据点数量 == 分类数量

正确示例

CATEGORIES = ["Q1", "Q2", "Q3", "Q4"], SERIES = [{ NAME = "产品A", DATA = [100, 120, 130, 150] }]

错误示例

CATEGORIES = ["Q1", "Q2", "Q3", "Q4"], SERIES = [{ NAME = "产品A", DATA = [100, 120] }]

后者会导致图表数据区域不匹配,表现为:

  • 图表数据缺失
  • 图表显示异常
  • 某些类型下直接生成错误图表

4.2SERIES至少要有一组

SERIES = []

这种配置没有业务意义,也不应该用于生产环境。

建议规范:

  • SERIES.size() >= 1
  • 每个SERIES.DATA.size() >= 1

4.3DATA中应全部为数值

推荐使用:

  • int
  • long
  • double
  • BigDecimal对应的数值字面量

不推荐:

  • 文本数字,如"120"
  • 带单位字符串,如"120万"
  • 空字符串 / null

4.4PIE图建议只放一组系列

虽然底层接口允许按统一模型传入多组SERIES,但从业务语义上:

  • 饼图通常应只有1 个系列
  • CATEGORIES表示扇区名称
  • DATA表示每个扇区值

推荐写法:

TYPE = PIE, CATEGORIES = ["Apple", "Samsung", "Xiaomi", "Other"], SERIES = [{ NAME = "市场份额", DATA = [38.5, 22.3, 15.7, 23.5] }]

5. 各图表类型使用建议

5.1COLUMN

适用于同维度多系列对比。

TYPE = COLUMN, TITLE = "销售数据统计", CATEGORY_AXIS = "产品", VALUE_AXIS = "销量"

推荐场景:

  • 产品销量对比
  • 班级成绩对比
  • 部门人力规模对比

5.2BAR

适用于排名型数据,尤其分类名较长时优于COLUMN。

推荐场景:

  • 季度销售排行
  • 城市 GDP 排名
  • TopN 指标横向比较

5.3LINE

适用于时间序列 / 趋势分析。

推荐场景:

  • 月度温度变化
  • 订单趋势
  • 活跃用户增长曲线

5.4PIE

适用于单组占比。

不适合:

  • 类别过多
  • 多系列并列比较
  • 时间趋势分析

5.5AREA/AREA3D

适用于累积型趋势展示,强调面积感。

5.6SCATTER

适用于二维相关性分析。

例如:

  • 身高 / 体重
  • 价格 / 销量
  • CPU 使用率 / 响应时间

5.7RADAR

适用于多维能力评估,每组对象在多个维度下对比。

5.8SURFACE

适用于三维矩阵型数据。这是当前最不适合普通业务报表的图表类型,建议仅在明确有三维展示诉求时使用。


6. Java 调用方式

6.1 最小可用示例

Stringrule=""" EXPORT WITH GRAPH = { TYPE = COLUMN, TITLE = "销售数据统计", CATEGORY_AXIS = "产品", VALUE_AXIS = "销量", CATEGORIES = ["产品A", "产品B", "产品C", "产品D"], SERIES = [{ NAME = "第一季度", DATA = [120, 200, 150, 180] }, { NAME = "第二季度", DATA = [180, 210, 190, 220] }] } """;JQuickExcelCommonExportExecutorexecutor=newJQuickExcelCommonExportExecutor();JExcelExportModelconfig=(JExcelExportModel)executor.execute(rule);JExcelExportHandlerhandler=newJExcelExportHandler(config,newArrayList<>());try(FileOutputStreamout=newFileOutputStream("D://test//column.xlsx")){handler.getWorkBook().write(out);}

6.2 推荐调用姿势

如果只是导出图表:

  • 数据行可传空集合new ArrayList<>()
  • 只通过GRAPH生成独立图表工作表

如果要同时导出表格和图表:

  • 当前更适合拆成两份导出逻辑
  • 一份专门生成表格
  • 一份专门生成图表

原因见第 8 节。


7. 底层行为说明

7.1 图表实际写入的是一个新 Sheet

当前实现里,图表工厂会:

  1. workbook.createSheet(sheetName)
  2. 把CATEGORIES + SERIES先写到这个 sheet
  3. 在这个 sheet 上创建 drawing / anchor / chart

所以:

  • 图表不是附着在已有业务表格的指定区域上
  • TITLE同时也会被用作 sheetName 传入图表工厂
  • 若标题重复,可能引发工作表重名问题

7.2 GRAPH 会触发“禁用流式导出”

图表导出需要回头访问 workbook 中已写入内容并创建图表锚点,因此会触发needsRandomRowAccess(config),从而禁用 SXSSF 流式导出。

这意味着:

  • 即使全局开启了流式导出
  • 只要配置了GRAPH
  • 当前导出也会降级为XSSFWorkbook

对程序员的含义是:

GRAPH 不适合超大数据量导出主链路。

建议:

  • 图表导出用于汇总结果页、统计页
  • 大批量明细数据导出与图表导出分离

8. 使用边界与限制

8.1 当前图表数据来源不是业务表格区域引用

当前实现是:

  • 先把 DSL 中的CATEGORIES、SERIES.DATA写到图表 sheet 中
  • 再基于写入后的区域创建图表

这意味着当前不支持:

  • 从已有 Excel 数据区域自动绑定图表
  • 直接引用业务 sheet 某一列作为图表数据源
  • 在同一个业务 sheet 指定任意位置插图表

8.2 不适合复杂图表布局

当前没有 DSL 字段可以控制:

  • 图表显示位置
  • 图表大小
  • 多图排版
  • 图例位置
  • 数据标签
  • 颜色主题
  • 次坐标轴
  • 组合图(柱线混合图)

所以这套 GRAPH 更适合:

  • 快速生成标准报表图
  • 自动化导出中的基础统计展示

而不适合:

  • 高定制 BI 报表
  • PPT 级视觉排版
  • 复杂 dashboard

8.3TITLE建议唯一

由于当前会把标题作为 sheetName 传入图表创建逻辑,因此建议:

  • 同一个 workbook 中每个图表标题保持唯一
  • 避免同名图表导致 sheetName 冲突

不推荐:

TITLE = "统计图"

推荐:

TITLE = "2025年第一季度销售统计图"

9. 推荐规范

9.1 DSL 编写规范

建议统一风格:

EXPORT WITH GRAPH = { TYPE = COLUMN, TITLE = "销售数据统计", CATEGORY_AXIS = "产品", VALUE_AXIS = "销量", CATEGORIES = ["产品A", "产品B", "产品C"], SERIES = [{ NAME = "第一季度", DATA = [120, 200, 150] }] }

规范要求:

  • TYPE使用大写枚举值
  • TITLE、CATEGORY_AXIS、VALUE_AXIS使用引号包裹
  • CATEGORIES明确按展示顺序写入
  • SERIES中DATA长度必须与CATEGORIES保持一致
  • 业务上没有意义时不要使用 3D 图

9.2 业务建模规范

在程序层建议先做图表 DTO,再拼 DSL,不要直接在 Controller 层硬编码字符串。

推荐模型:

classChartRequest{Stringtype;Stringtitle;StringcategoryAxis;StringvalueAxis;List<String>categories;List<SeriesRequest>series;}classSeriesRequest{Stringname;List<Number>data;}

这样好处是:

  • 便于参数校验
  • 便于单元测试
  • 便于后续扩展图表模板

9.3 导出前校验规范

在执行executor.execute(rule)前,建议先做以下校验:

  • type非空且属于支持列表
  • title非空
  • categories非空
  • series非空
  • 每个series.name非空
  • 每个series.data非空
  • 所有series.data.size()与categories.size()相同

10. 常见错误清单

错误 1:分类数量和数据点数量不一致

CATEGORIES = ["Q1", "Q2", "Q3"], SERIES = [{ NAME = "产品A", DATA = [120, 130] }]

错误 2:饼图传多组系列

TYPE = PIE, SERIES = [{...}, {...}]

虽然 DSL 可能可解析,但业务上通常不合理。

错误 3:把 GRAPH 当成表格图表绑定器

错误理解:

先导出表格,再让 GRAPH 自动引用表格列生成图表。

当前不是这个模式。

错误 4:大数据量场景仍强依赖 GRAPH

图表会禁用流式导出,不适合海量明细导出主流程。

错误 5:图表标题过于泛化

TITLE = "图表"

可能带来 sheetName 冲突,也不利于后续维护。


11. 推荐模板

11.1 柱状图模板

EXPORT WITH GRAPH = { TYPE = COLUMN, TITLE = "年度销售统计", CATEGORY_AXIS = "产品", VALUE_AXIS = "销量", CATEGORIES = ["产品A", "产品B", "产品C", "产品D"], SERIES = [{ NAME = "2025", DATA = [120, 200, 150, 180] }] }

11.2 折线图模板

EXPORT WITH GRAPH = { TYPE = LINE, TITLE = "月度访问趋势", CATEGORY_AXIS = "月份", VALUE_AXIS = "访问量", CATEGORIES = ["1月", "2月", "3月", "4月"], SERIES = [{ NAME = "官网", DATA = [1000, 1200, 1150, 1500] }, { NAME = "小程序", DATA = [800, 900, 980, 1300] }] }

11.3 饼图模板

EXPORT WITH GRAPH = { TYPE = PIE, TITLE = "渠道占比", CATEGORIES = ["官网", "小程序", "App", "线下"], SERIES = [{ NAME = "占比", DATA = [35, 25, 20, 20] }] }

11.4 雷达图模板

EXPORT WITH GRAPH = { TYPE = RADAR, TITLE = "工程师能力评估", CATEGORIES = ["编码", "设计", "沟通", "测试", "学习"], SERIES = [{ NAME = "张三", DATA = [90, 85, 75, 80, 95] }, { NAME = "李四", DATA = [80, 88, 82, 78, 85] }] }

12. 最佳实践总结

推荐

  • 用COLUMN / BAR / LINE / PIE解决 80% 报表图需求
  • 导出前先做数据长度一致性校验
  • 图表导出和大批量明细导出分离
  • 保持TITLE唯一且可读
  • 在服务层先构建图表 DTO,再拼 DSL

不推荐

  • 在 Controller 直接手写复杂 GRAPH DSL
  • 在一个超大导出任务里混用 GRAPH
  • 依赖 GRAPH 自动绑定已有表格区域
  • 给PIE、RADAR配置不合理的多系列结构
  • 使用含义不明确的标题和类别值

13. 一句话结论

如果你站在程序员角度使用 JQuick-Excel 的图表能力,最重要的认知是:

GRAPH 是一套“声明式图表数据模型”,适合生成标准化统计图;它不是 BI 画布,也不是对已有表格区域的自动绑定器。

因此最佳用法是:

先在业务层整理好 categories + series,再用 DSL 生成标准图表导出。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询