🚀 jquick-excel: 轻量级、高性能的 Java Excel 操作框架

August 10, 2026 · View on GitHub

简体中文 | English

Awesome Java

已被收录至 Awesome JavaDocument Processing 精选章节

⚡ JQuickExcel 是一款轻量级、高扩展性的 Java Excel 处理框架,支持 .xls 和 .xlsx 格式,无需复杂依赖。它提供基于 XML 配置的声明式导入/导出能力,适用于快速开发与复杂数据转换场景。

📦 项目简介

jquick-excel 是一个专为 Java 开发者设计的轻量级 Excel 操作框架。它结合了 易用性灵活性高性能,支持主流 Excel 格式(xls/xlsx),并提供丰富的 API 帮助开发者快速实现复杂的 Excel 导入导出功能。

🎨 主题模板 / Theme Templates

JQuickExcel 内置 42 套精美主题模板,涵盖经典商务、蓝/绿/青/红橙/粉紫/金棕色系及特殊风格,开箱即用。

主题编码汇总 / Theme Code Summary

序号 / No.Code中文名称 / Chinese Name
1default经典皇家蓝
2minimalistGrey极简灰
3slate板岩灰
4charcoal炭灰
5navyBlue海军蓝
6oceanBlue海洋蓝
7skyBlue天空蓝
8azure蔚蓝
9steelBlue钢蓝
10denim牛仔蓝
11indigo靛蓝
12periwinkle长春花蓝
13forestGreen森林绿
14emerald祖母绿
15jade翡翠绿
16mintFresh清新薄荷
17sage鼠尾草绿
18oliveGreen橄榄绿
19tropicalTeal热带青
20turquoise绿松石
21cyan青色
22sunsetOrange落日橙
23coral珊瑚
24peach蜜桃
25crimsonRed深红
26wineRed酒红
27sakuraPink樱花粉
28roseQuartz粉晶
29lavenderPurple薰衣草紫
30amethyst紫水晶
31plum紫梅
32royalGold皇家金
33champagne香槟金
34amber琥珀
35mustard芥末黄
36bronze青铜
37vintageSepia复古棕
38espresso浓缩咖啡
39mahogany红木
40terracotta陶土
41midnightDark午夜深色
42pearl珍珠

👉 查看全部主题模板预览 / View all theme template previews

方式一:DSL 模板中指定

JQuickParseHandler parser = new JQuickExcelExportXmlParseFactory(template_code, rows, fileOutputStream);

方式二:通过 JExcelExportModel 配置主题

JExcelExportModel config = (JExcelExportModel) executor.execute(rule);
config.setTheme("oceanBlue");  // 海洋蓝主题,参见上方编码表
JExcelExportHandler handler = new JExcelExportHandler(config, data);
handler.exportData();

✨ 核心特性

✅ 双格式支持 - 完美兼容 .xls 和 .xlsx 格式
✅ 声明式配置 - 使用简洁的 DSL 语法定义导入导出规则
✅ 高性能处理 - 优化大数据量读写,内存占用低
✅ 丰富验证规则 - 内置 20+ 种数据验证规则
✅ 强大公式支持 - 支持 50+ 种 Excel 公式
✅ 图表生成 - 支持 10 种图表类型一键生成
✅ 样式自定义 - 完整的单元格样式控制
✅ 单元格合并 - 灵活的多维数据合并策略
✅ 上下文转换 - 支持动态数据转换和映射
✅ 🎨 42 套精美主题 - 内置多色系主题模板,一键切换导出风格
✅ ⚙️ 全局配置中心 - 统一控制流式导出、OPCPackage 导入、样式缓存等性能参数
✅ 📦 分批导入 API - 支持回调式分页消费,避免大文件一次性加载
✅ 🔥 Transform AST 缓存 - 导入/导出时自动缓存解析结果,万级单元格零重复解析
✅ 📐 列数行数懒缓存 - 同 Sheet 内多次读取只做一次全表扫描

📊 性能基准测试

JQuick-Excel 提供完善的性能基准测试,覆盖导出/导入全链路,支持对比 XSSF 与 SXSSF 流式、OPCPackage ON/OFF 等关键模式。

核心指标 / Key Metrics: 耗时、峰值内存、文件大小、吞吐量、内存效率

亮点 / Highlights:

  • 🚀 SXSSF 流式导出 / SXSSF Streaming Export:10 万行数据内存降低 ~75%,速度提升 10-15% / ~75% memory reduction at 100K rows, 10-15% speed improvement
  • 💾 OPCPackage 导入 / OPCPackage Import:导入内存稳定降低 50%+,速度提升 15-20% / 50%+ consistent memory reduction, 15-20% speed improvement
  • 🎨 样式缓存优化 / Style Cache Optimization:样式数量从 ~90 万降至 ~10 份,彻底解决 64000 上限问题 / Style count reduced from ~900K to ~10, completely solving the 64000 limit issue
数据量 / Rows导出模式 / Export耗时 / Time(ms)峰值内存 / Peak Mem(MB)内存降幅 / Memory Reduction
10,000XSSF3,200512.3
10,000SXSSF Streaming2,800128.5-74.9%
100,000OPCPackage ON (导入)15,200389.1-50%+ vs OFF

以上为示例数据,实际结果取决于硬件与 JVM 配置。

The above are example values. Actual results depend on hardware and JVM configuration.

👉 查看完整性能基准测试报告 / View full benchmark report

大数据量导入优化

JQuickExcel 在大数据量导入场景下实施了多项无损性能优化,无 API 侵入、零配置即可享受

优化项说明收益
Transform AST 缓存相同 transform 表达式仅做一次 ANTLR 词法/语法解析,ParseTree 跨调用复用10 万行带 transform:20 万次解析 → 2 次
列数/行数懒缓存getUsedColumnCount / getLastRowNum 首次计算后缓存,同 Sheet 内多次读取仅做一次全表扫描省掉一次完整 O(行×列) 遍历
DataFormatter 复用验证范围内不再为每个单元格 new DataFormatter(),复用静态共享实例消除万级临时对象与 GC 压力
循环常数优化getTransforms 等调用提到外层循环,headers.size() 提取为局部变量每单元格省 1~2 次方法调用
MissingCellPolicy改用 RETURN_NULL_AND_BLANK,稀疏表不再生成无意义空 Cell 对象稀疏表百万级对象消除

如需手动控制,可通过 JQuickExcelConfig 切换全局参数(参见下方「全局配置中心」章节)。

⚙️ 全局配置中心

JQuickExcelConfig 是 JQuick-Excel 的全局单例配置中心,用于统一控制导入导出性能参数,无需在每次调用时重复设置。

JQuickExcelConfig cfg = JQuickExcelConfig.getInstance();

// 导出:超过 5000 行自动切 SXSSF 流式写入
cfg.setStreamingExportEnabled(true)
   .setStreamingRowAccessWindowSize(100)    // 内存保留 100 行
   .setStreamingExportThreshold(5000);

// 导入:启用 OPCPackage 共享解析降低峰值内存
cfg.setBigFileImportEnabled(true)
   .setImportBatchThreshold(20000);        // 建议分批的行数阈值

// 样式缓存:避免 CellStyle 超 64000 上限
cfg.setCellStyleCacheEnabled(true);

配置项说明

配置项类型默认值说明
streamingExportEnabledbooleantrue超过阈值时自动切换 SXSSF 流式写入
streamingRowAccessWindowSizeint100SXSSF 内存中保留的行数窗口
streamingExportThresholdint5000触发流式导出的行数阈值(≤0 关闭自动切换)
streamingCompressTempFilesbooleantrue流式写入时是否压缩临时文件
bigFileImportEnabledbooleantrue导入时采用 OPCPackage 共享解析降低峰值内存
importBatchThresholdint20000建议使用分批导入的行数阈值(仅供参考)
cellStyleCacheEnabledbooleantrueCellStyle 缓存开关,避免 64000 样式上限

提示resetDefault() 可在测试场景下将配置还原为默认值。

🛠️ 技术栈

Java Apache POI Lombok License Last Commit Stars Forks

📥 快速开始

Maven 依赖

<dependency>
  <groupId>io.github.paohaijiao</groupId>
  <artifactId>jquick-excel</artifactId>
  <version>最新版本</version>
</dependency>

gradle 依赖

implementation 'io.github.paohaijiao:jquick-excel:最新版本'

🚀 快速集成

在项目的 resources 目录下创建 jquick-excel.xml 配置文件,这是整个 Excel 导入导出功能的“指挥中心”。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE excels PUBLIC "-//PAOHAIJIAO//DTD API EXCEL 1.0//EN"
        "classpath:paohaijiao/dtd/Jquick-excel.dtd">
<excels namespace="com.github.paohaijiao.xml.service.JQuickExcelExportService">

    <excel name="exportExcel" returnClass="void">
        EXPORT  WITH
            SHEET="学生表",
            HEADER=true,
            MAPPING={
                "id":"主键",
                "name":"姓名",
                "gender":"性别",
                "age":"年龄",
                "enrollmentDate":"入学时间",
                "className":"班级",
                "ignoreField":"是否忽略"
            },
            FORMULAS={
                D5:'ABS(D2)'
            },
            STYLE={
                ROW 1: {
                    fontName: Arial,
                    fontHeightInPoints: 12,
                    italic: true,
                    color: yellow,
                    bold: true
                }
            }
    </excel>
    <excel name="importExcel" returnClass="jva.util.List">
        IMPORT WITH
        HEADER=true,
        SHEET='Sheet1',
        MAPPING = {
            "学号": "no",
            "姓名": "name",
            "性别": "sex",
            "年龄": "age",
            "出生日期": "birthday"
        },
        TRANSFORM={
            "sex":trans(${dict},${sex}),
            "birthday":dateFormat(${birthday},'yyyy-MM-dd')
        }
    </excel>
</excels>

服务接口是连接 XML 配置与实际业务逻辑的桥梁,通过接口方法声明,框架能够自动解析 XML 配置并生成对应的代理实现。接口方法使用 @Param 注解标注参数,这些参数可以在 XML 配置的动态 SQL 或条件查询中使用。

import com.github.paohaijiao.statement.JQuickRow;
import com.github.paohaijiao.xml.param.Param;

import java.util.List;

public interface JQuickExcelExportService {

    public void exportExcel(@Param("field")String field, @Param("value")String value);

    public List<JQuickRow> importExcel(@Param("field")String field, @Param("value")String value);
}

一切准备就绪,现在只需几行代码,就能让 Excel 导入导出功能“活”起来! 框架会自动完成数据转换、样式渲染、文件生成等复杂操作

 public static List<JStudentModel> getData() {
        List<JStudentModel> students = new ArrayList<>();
        students.add(new JStudentModel("1001", "张三", 1, 20, new Date(), "计算机1班", "true"));
        students.add(new JStudentModel("1002", "李四", 0, 21, new Date(), "计算机2班", "true"));
        students.add(new JStudentModel("1003", "王五", 1, 22, new Date(), "计算机3班", "true"));
        return students;
    }
    @Test
    public void exportExcel() throws FileNotFoundException {
        List<JQuickRow> rows= JQuickRow.toRows( JObjectConverter.convert(getData()));
        OutputStream fileOutputStream=new FileOutputStream("d://test//style.xlsx");
        JQuickParseHandler parser = new JQuickExcelExportXmlParseFactory(rows,fileOutputStream);
        JQuickFactory factory = new JQuickXmlFactory(parser,"jquick-excel.xml");
        System.out.println(factory);
        JQuickExcelExportService excelExportService = factory.createApi(JQuickExcelExportService.class);
        excelExportService.exportExcel("1","2");
        System.out.println("导出成功");
    }
    @Test
    public void importExcel() throws FileNotFoundException {
        InputStream is = JMappingTest.class.getClassLoader().getResourceAsStream("templates/student.xlsx");
        Map<String,Object> sex=new HashMap<>();
        sex.put("男","1");
        sex.put("女","2");
        JContext context = new JContext();
        context.put("dict",sex);
        JQuickParseHandler parser = new JQuickExcelImportXmlParseFactory(context,is);
        JQuickFactory factory = new JQuickXmlFactory(parser,"jquick-excel.xml");
        System.out.println(factory);
        JQuickExcelExportService excelExportService = factory.createApi(JQuickExcelExportService.class);
        List<JQuickRow> list=excelExportService.importExcel("1","2");
        System.out.println("导入成功:"+list.size());
    }

📚 功能总览

🔄 导入功能

  • 智能映射 - 字段自动映射与转换
  • 数据验证 - 20+ 种验证规则(邮箱、手机、正则等)
  • 格式转换 - 日期、数字、字符串格式化
  • 批量处理 - 支持大数据量分批次导入

📤 导出功能

  • 模板导出 - 基于配置模板快速导出
  • 公式计算 - 支持 50+ 种 Excel 公式
  • 图表生成 - 10 种图表类型
  • 样式定制 - 完整的单元格样式控制
  • 数据合并 - 多种合并策略(最大、最小、平均等)

🎯 使用示例

基础语法

IMPORT [WITH option1, option2, ...]

配置项说明

语法描述
SHEETSHEET = (字符串 | 数字)指定工作表(名称/索引)
HEADERHEADER = 布尔值是否包含表头 (true/false)
MAPPINGMAPPING = { 映射关系 }源字段 ↔ 目标字段映射
TRANSFORMTRANSFORM = { 转换规则 }数据转换规则
VALIDATIONVALIDATION = { 验证规则 }数据验证规则

SHEET 语法

IMPORT WITH SHEET="Sheet1"
IMPORT WITH HEADER=true

字段映射语法

IMPORT WITH MAPPING = {
"学号": "no",
"姓名": "name",
"性别": "sex",
"年龄": "age",
"出生日期": "birthday"
}

转换规则语法(支持 JEvaluator 所有方法)

IMPORT WITH TRANSFORM={
"sex": trans(${dict},${sex}),
"birthday": dateFormat(${birthday},'yyyy-MM-dd')
}

导入验证

📊 支持的验证规则

规则类型示例说明
布尔验证boolean{required:true}验证布尔值
日期格式date_format{format:'yyyy-MM-dd'}日期格式验证
数值范围range{min:1, max:100}数值范围验证
字典验证dict{map:{'1':'男','2':'女'}}值必须在字典中
正则表达式regex{pattern:'^\d+$'}正则匹配验证
长度验证max_length{maxLength:10}字符串长度验证
邮箱验证email{}邮箱格式验证
手机验证mobile{}手机号格式验证

验证规则语法

// 行验证
ROW 5 - 验证第5行
ROW 1..10 - 验证第1行到第10行
// 列验证
COL A - 验证A列
COL A..D - 验证A列到D列
// 单元格验证
C1 - 验证第1行C列单元格
// 范围验证
A1:B5 - 验证A1到B5的矩形区域

验证规则配置示例

IMPORT WITH VALIDATION={
ROW 1..10 {
required {required: true, msg: "不能为空"},
range {required: true, msg: "数值超出范围", map: {min: 1, max: 100}}
},
COL A {
required {required: true, msg: "A列不能为空"}
},
B1:C5 {
regex {required: true, msg: "格式错误", map: {pattern: "^\\d+$"}}
}
}

验证规则类型

验证规则列表

规则名称参数键参数类型描述
boolean--验证值是否为布尔值
date_formatformatString验证字符串是否符合指定的日期格式
max_datemaxDate, formatDate, String验证日期是否不超过指定的最大日期
min_dateminDate, formatDate, String验证日期是否不小于指定的最小日期
integer--验证值是否为整数
decimal--验证值是否为小数
max_valuemaxValueBigDecimal验证数值是否不大于指定的最大值
min_valueminValueBigDecimal验证数值是否不小于指定的最小值
dictkey-value pairsMap验证值是否存在于提供的字典中
email--验证字符串是否为有效的电子邮件格式
mobile--验证字符串是否为有效的手机号码格式(中国标准)
max_lengthmaxLengthBigDecimal验证字符串长度是否不超过指定的最大长度
min_lengthminLengthBigDecimal验证字符串长度是否不小于指定的最小长度
regexpatternString验证字符串是否匹配指定的正则表达式
start_withstartWithString验证字符串是否以指定的子字符串开头
not_start_withnotStartWithString验证字符串是否不以指定的子字符串开头
end_withendWithString验证字符串是否以指定的子字符串结尾
not_end_withnotEndWithString验证字符串是否不以指定的子字符串结尾
containcontainsString验证字符串是否包含指定的子字符串
not_containnotContainString验证字符串是否不包含指定的子字符串
布尔验证
IMPORT WITH VALIDATION={   
    C2:C4:{
        boolean{required:true,msg:'性别非法',map:{'1':'男','2':'女'}}
    }
}
日期格式验证
IMPORT WITH VALIDATION={   E2:E4:{
date_format{required:true,msg:'不符合日期格式',map:{'format':'yyyy-MM-dd'}   }
}
最大日期验证
IMPORT WITH VALIDATION={   E2:E4:{
    max_date{required:true,msg:'超过最大日期',map:{'format':'yyyy-MM-dd',maxDate:2025-01-01}   }
}
最小日期验证
IMPORT WITH VALIDATION={   E2:E4:{
    min_date{required:true,msg:'不能小于最小日期',map:{'format':'yyyy-MM-dd',minDate:2022-01-01}   }
}
整数验证
IMPORT WITH VALIDATION={   D2:D4:{
    integer{required:true,msg:'要求该字段是整形'   }
}
小数验证
IMPORT WITH VALIDATION={   D2:D4:{
    decimal{required:true,msg:'要求该字段是整形'   }
}
最大值验证
IMPORT WITH VALIDATION={   D2:D4:{
    max_value{required:true,msg:'年龄不能超过最大值',map:{'maxValue':50}   }
}
最小值验证
IMPORT WITH VALIDATION={   D2:D4:{
    min_value{required:true,msg:'年龄不能小于xx',map:{'minValue':2}   }
}
字典验证
IMPORT WITH VALIDATION={   C2:C4:{
    dict{required:true,msg:'性别非法',map:{'1':'男','2':'女'}   }
}
邮箱验证
IMPORT WITH VALIDATION={   C2:C4:{
    email{required:true,msg:'邮箱格式不正确'   }
}
手机号验证
IMPORT WITH VALIDATION={   C2:C4:{
    mobile{required:true,msg:'手机格式不正确'   }
}
最大长度验证
IMPORT WITH VALIDATION={   B2:B4:{
    max_length{required:true,msg:'最大长度有误',map:{'maxLength':7}   }
}
最小长度验证
IMPORT WITH VALIDATION={   B2:B4:{
    min_length{required:true,msg:'最小长度有误',map:{'minLength':1}   }
}
正则表达式验证
IMPORT WITH VALIDATION={   D2:D4:{
    regex{required:true,msg:'不符合正则表达式',map:{pattern:'^\d+$'}   }
}
开头字符串验证
IMPORT WITH VALIDATION={   B2:B4:{
   start_with{required:true,msg:'开始字符串有误',map:{startWith:'张三'}   }
}
非开头字符串验证
IMPORT WITH VALIDATION={   B2:B4:{
   not_start_with{required:true,msg:'不能以该字符串开始',map:{notStartWith:'张三'}   }
}
结尾字符串验证
IMPORT WITH VALIDATION={   B2:B4:{
   end_with{required:true,msg:'不符合以张三结束的字符',map:{endWith:'张三'}   }
}
非结尾字符串验证
IMPORT WITH VALIDATION={   B2:B4:{
   not_end_with{required:true,msg:'不符合表达式',map:{notEndWith:'张三'}   }
}
包含字符串验证
IMPORT WITH VALIDATION={   B2:B4:{
   not_end_with{required:true,msg:'不符合表达式',map:{notEndWith:'张三'}   }
}
不包含字符串验证
IMPORT WITH VALIDATION={   B2:B4:{
   not_contain{required:true,msg:'不应该包含该关键字',map:{notContain:'张三'}   }
}

基础导入示例

🔧 导入配置

String rule = """
    IMPORT WITH 
    SHEET="Sheet1",
    HEADER=true,
    MAPPING={
        "学号": "no",
        "姓名": "name",
        "性别": "sex",
        "年龄": "age",
        "出生日期": "birthday"
    }  """
JQuickExcelCommonImportExecutor executor = new JQuickExcelCommonImportExecutor();
JExcelImportModel model = (JExcelImportModel) executor.execute(rule);
InputStream is = getClass().getClassLoader().getResourceAsStream("templates/student.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(is);
JExcelImportHandler handler = new JExcelImportHandler(workbook);
List<Map<String, Object>> data = handler.importData(model);

分批导入示例(大数据量推荐)

当数据量超过 importBatchThreshold(默认 20000 行)时,推荐使用 importDataInBatch 以回调方式消费数据,避免一次性堆积大量对象导致 OOM:

JExcelImportHandler handler = new JExcelImportHandler(inputStream);
JExcelImportModel model = executor.execute(rule);

int total = handler.importDataInBatch(model, 5000, batch -> {
    // 每 5000 行回调一次,batch 为当前批次数据
    // 在此处理入库、校验等逻辑,返回 false 可提前终止
    System.out.println("本批次: " + batch.size() + " 行");
    return true;
});
System.out.println("总共读取: " + total + " 行");

主题配置导出示例

通过 JExcelExportModel#setTheme 方法指定主题编码(42 种可选,详见主题编码汇总):

JExcelExportModel config = (JExcelExportModel) executor.execute(rule);
config.setTheme("jade");  // 设置翡翠绿主题

JExcelExportHandler handler = new JExcelExportHandler(config, data);
Workbook workbook = handler.getWorkBook();
workbook.write(outputStream);

基础导出示例

String rule = """
EXPORT WITH
SHEET="学生表",
HEADER=true,
MAPPING={
"id": "主键",
"name": "姓名",
"gender": "性别",
"age": "年龄",
"enrollmentDate": "入学时间",
"className": "班级"
}
""";

List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fos = new FileOutputStream("导出结果.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(rule);
JExcelExportHandler handler = new JExcelExportHandler(config, data);
Workbook workbook = handler.getWorkBook();
workbook.write(fos);
fos.close();

📤 导出配置

基础语法

EXPORT [WITH option1, option2, ...]

导出选项说明

配置项语法格式描述说明
📑 SHEETSHEET '=' (STRING | NUMBER)按名称或索引指定目标工作表
📋 HEADERHEADER '=' BOOLEAN控制是否包含表头 (true/false)
🎨 FORMATFORMAT '=' '{' cellFormat (',' cellFormat)* '}'定义单元格格式化规则
🗺️ MAPPINGMAPPING '=' '{' fieldMapping (',' fieldMapping)* '}'源数据与导出数据之间的字段映射
🔄 TRANSFORMTRANSFORM '=' '{' transformRule (',' transformRule)* '}'导出前的数据转换规则
🧮 FORMULASFORMULAS '=' '{' formulaTarget (',' formulaTarget)* '}'导出时应用的公式
STYLESTYLE '=' '{' styleTarget (',' styleTarget)* '}'单元格样式规则
🧩 MERGEMERGE '=' '{' mergeSpec (',' mergeSpec)* '}'单元格合并规则
📊 GRAPHGRAPH '=' '{' graphSpec (',' graphSpec)* '}'图表 / 图形配置
📝 FOOTERFOOTER '=' (STRING | IDENTIFIER)页脚文本或变量引用

SHEET 选项

EXPORT WITH SHEET="Report"

表头选项

EXPORT WITH HEADER=true

映射选项

EXPORT  WITH MAPPING={
	"id":"主键",
	"name":"姓名",
	"gender":"性别",
	"age":"年龄",
	"enrollmentDate":"入学时间",
	"className":"班级",
	"ignoreField":"是否忽略"
}
public static List<JStudentModel> getData() {
  List<JStudentModel> students = new ArrayList<>();
  students.add(new JStudentModel("1001", "张三", 1, 20, new Date(), "计算机1班", "true"));
  students.add(new JStudentModel("1002", "李四", 0, 21, new Date(), "计算机2班", "true"));
  students.add(new JStudentModel("1003", "王五", 1, 22, new Date(), "计算机3班", "true"));
  return students;
}
List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fileOutputStream=new FileOutputStream("d://test//format.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(input);
JExcelExportHandler handler = new JExcelExportHandler(config,data);
Workbook workbook=handler.getWorkBook();
workbook.write(fileOutputStream);

格式化选项

EXPORT  WITH MAPPING={
	"id":"主键",
	"name":"姓名",
	"gender":"性别",
	"age":"年龄",
	"enrollmentDate":"入学时间",
	"className":"班级",
	"ignoreField":"是否忽略"
},FORMAT={"enrollmentDate":"yyyy-MM-dd"}

转换选项

EXPORT  WITH MAPPING={
	"id":"主键",
	"name":"姓名",
	"gender":"性别",
	"age":"年龄",
	"enrollmentDate":"入学时间",
	"className":"班级",
	"ignoreField":"是否忽略"
},
FORMAT={	
  "enrollmentDate":"yyyy-MM-dd"
},
TRANSFORM={
  "name": toUpper(${name}),
  "enrollmentDate": dateFormat(${enrollmentDate},'yyyy-MM-dd'),
  "gender": trans(${dict},${gender})
}
List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fileOutputStream=new FileOutputStream("d://test//transform.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(input);
HashMap<String,Object> map = new HashMap<>();
  map.put("1","男");
  map.put("0","女");
JContext context = new JContext();
context.put("dict",map);
JExcelExportHandler handler = new JExcelExportHandler(config,context,JQuickRow.toRows(data));
Workbook workbook=handler.getWorkBook();
workbook.write(fileOutputStream);

公式选项

应用范围支持

支持单元格区域四种类型:

  1. ROW 5 - 应用第 5 行 ROW 1..10 - 应用第 1 行至第 10 行
  2. COL A: - 应用 A 列 COL A..D: - 应用 A 列至 D 列
  3. 单元格 C1: - 应用第 1 行 C 列的单元格
  4. 区域 A1:B5 - 代表从 A1 单元格到 B5 单元格的矩形区域

🔢 支持的公式类型

📈 数学公式(16个)

公式名语法示例参数数量描述说明对应类名
📏 ABSABS(D2)1绝对值JABSFormula
📊 AVERAGEAVERAGE(D2:D4)≥1算术平均值JAverageFormula
🔢 COUNTCOUNT(D2:D4)≥1计数JCountFormula
⬆️ MAXMAX(D2:D4)≥1最大值JMaxFormula
⬇️ MINMIN(D2:D4)≥1最小值JMinFormula
POWERPOWER(2,3)2幂运算JPowerFormula
🎲 RANDRAND()0随机数 [0,1)JRandFormula
🏆 RANKRANK(20,D2:D4)2列表中排名JRankFormula
🎯 ROUNDROUND(3.1415926,3)2四舍五入指定位数JRoundFormula
√️ SQRTSQRT(4)1平方根JSQRTFormula
📈 STDEVSTDEV(D2:D4)≥1标准差JSTDEVFormula
SUMSUM(D2:D4)≥1求和JSumFormula
# 数学公式配置示例(整合版)
# 格式说明:FORMULAS = { 目标单元格: '公式表达式' }
# 所有公式均配置在 D5 单元格,可根据实际需求修改目标单元格
FORMULAS={
# 1. 绝对值计算:取 D2 单元格的绝对值
D5:'ABS(D2)',
# 2. 算术平均值:计算 D2 至 D4 单元格的平均值
D5:'AVERAGE(D2:D4)',
# 3. 计数:统计 D2 至 D4 单元格的有效数值个数
D5:'COUNT(D2:D4)',
# 4. 最大值:取 D2 至 D4 单元格中的最大值
D5:'MAX(D2:D4)',
# 5. 最小值:取 D2 至 D4 单元格中的最小值
D5:'MIN(D2:D4)',
# 6. 幂运算:计算 2 的 3 次方($2^{3}$)
D5:'POWER(2,3)',
# 7. 随机数:生成 0(包含)到 1(不包含)之间的随机数
D5:'RAND()',
# 8. 排名:计算数值 20 在 D2 至 D4 区域中的排名
D5:'RANK(20,D2:D4)',
# 9. 四舍五入:将 3.1415926 保留 3 位小数
D5:'ROUND(3.1415926,3)',
# 10. 平方根:计算 4 的平方根
D5:'SQRT(4)',
# 11. 标准差:计算 D2 至 D4 单元格数据的标准差(反映数据离散程度)
D5:'STDEV(D2:D4)',
# 12. 求和:计算 D2 至 D4 单元格的数值总和
D5:'SUM(D2:D4)'
}

📅 日期公式(15个)

公式名语法示例特殊规则对应类名
🕒 DATETIMEDATETIME(2023,5,15,14,30,0)返回当前日期时间JDateTimeFormula
📆 DAYDAY("2025-01-23")提取日期中的日(1-31)JDayFormula
📊 DAYSDAYS("2025-01-23","2025-01-28")计算两个日期之间的天数JDaysFormula
📈 EDATEEDATE(start,months)给日期添加指定月份JEDATEFormula
🗓️ EOMONTHEOMONTH("2025-01-23",3)返回指定月份的月末日期JEOMONTHFormula
HOURHOUR('2025-01-23')提取时间中的小时(0-23)JHourFormula
💼 NETWORKDAYSNETWORKDAYS(s,e,[h])参数数量 2-3 个(计算工作日)JNetworkDayFormula
�实时 NOWNOW()需精确匹配语法,返回当前时间戳JNowFormula
📅 TODAYTODAY()需精确匹配语法,返回当前日期JTodayFormula
🛠️ WORKDAYWORKDAY(s,days,[h])参数数量 2-3 个(计算工作日偏移)JWorkDayFormula
⏱️ MINUTEMINUTE(time_value)1 个时间序列参数,提取分钟(0-59)-
📍 MONTHMONTH(date_value)1 个日期序列参数,提取月份(1-12)-
🎯 SECONDSECOND(time_value)1 个时间序列参数,提取秒(0-59)-
⏲️ TIMETIME(hour,min,sec)3 个参数(时/分/秒),返回Excel时间序列(0-0.999)-
📆 TODAYTODAY()精确匹配语法,返回当前日期序列-
📝 WEEKDAYWEEKDAY(date,[type])参数数量 1-2 个,返回星期几(可配置)-
📊 WEEKNUMWEEKNUM(date,[type])参数数量 1-2 个,返回周数-
📅 YEARYEAR(date_value)1 个日期序列参数,提取年份(1900-9999)-

📅 日期公式配置 & 等效 Java 代码(整合版)

1. 基础日期时间公式

# -------------------------- 1. DATETIME - 构造日期时间 --------------------------
# 配置格式:FORMULAS = { 目标单元格: '公式表达式' }
FORMULAS={
    D5:'DATETIME(2023,5,15,14,30,0)'  # 构造 2023-05-15 14:30:00 日期时间
}
# 等效 Java 代码
/*
 * 直接创建 DATETIME 公式实例
 */
JAbstractExcelFormula formula = factory.createFormulaInstance("DATETIME(2023,5,15,14,30,0)");

# -------------------------- 2. DAY - 提取日期中的“日” --------------------------
FORMULAS={
    D5:'DAY("2025-01-23")'  # 提取 2025-01-23 的“日”(结果:23)
}
# 等效 Java 代码
/*
 * 1. 先在 A1 单元格写入日期值
 * 2. 基于 A1 单元格创建 DAY 公式
 */
sheet.createRow(0).createCell(0).setCellValue("2023-05-15");
JAbstractExcelFormula formula = factory.createFormulaInstance("DAY(A1)");

# -------------------------- 3. DAYS - 计算两个日期的天数差 --------------------------
FORMULAS={
    D5:'DAYS("2025-01-23","2025-01-28")'  # 计算 2025-01-28 与 2025-01-23 的天数差
}
# 等效 Java 代码
/*
 * 1. A1 写入起始日期,A2 写入结束日期
 * 2. 计算 A2 - A1 的天数差
 */
sheet.createRow(0).createCell(0).setCellValue("2023-01-01");
sheet.createRow(1).createCell(0).setCellValue("2023-12-31");
JAbstractExcelFormula formula = factory.createFormulaInstance("DAYS(A2,A1)");

# -------------------------- 4. EDATE - 日期添加指定月份 --------------------------
FORMULAS={
    D5:'EDATE("2025-01-23",3)'  # 2025-01-23 加 3 个月
}
# 等效 Java 代码
/*
 * 1. A1 写入基础日期
 * 2. 给 A1 日期添加 3 个月
 */
sheet.createRow(0).createCell(0).setCellValue("2023-01-31");
JAbstractExcelFormula formula = factory.createFormulaInstance("EDATE(A1,3)");

# -------------------------- 5. EOMONTH - 获取月末日期 --------------------------
FORMULAS={
    D5:'EOMONTH("2025-01-23",3)'  # 2025-01-23 加 3 个月后的月末日期
}
# 等效 Java 代码
/*
 * 1. A1 写入基础日期
 * 2. 获取 A1 日期当月的月末日期(参数 0 表示当前月)
 */
sheet.createRow(0).createCell(0).setCellValue("2023-02-15");
JAbstractExcelFormula formula = factory.createFormulaInstance("EOMONTH(A1,0)");
# -------------------------- 6. HOUR - 提取小时 --------------------------
# 前提:A1 单元格值为 14:30:00
FORMULAS={
    D5:'HOUR("A1")'  # 提取 A1 单元格时间的小时部分(结果:14)
}
# 等效 Java 代码
/*
 * 1. A1 写入时间值
 * 2. 提取 A1 时间的小时
 */
sheet.createRow(0).createCell(0).setCellValue("14:30:00");
JAbstractExcelFormula formula = factory.createFormulaInstance("HOUR(A1)");

# -------------------------- 11. MINUTE - 提取分钟 --------------------------
# 等效 Java 代码
/*
 * 1. A1 写入时间值 14:30:45
 * 2. 提取 A1 时间的分钟部分(结果:30)
 */
sheet.createRow(0).createCell(0).setCellValue("14:30:45");
JAbstractExcelFormula formula = factory.createFormulaInstance("MINUTE(A1)");

# -------------------------- 14. SECOND - 提取秒 --------------------------
# 等效 Java 代码
/*
 * 1. A1 写入时间值 14:30:45
 * 2. 提取 A1 时间的秒部分(结果:45)
 */
sheet.createRow(0).createCell(0).setCellValue("14:30:45");
JAbstractExcelFormula formula = factory.createFormulaInstance("SECOND(A1)");
# -------------------------- 7. NETWORKDAYS - 计算工作日数 --------------------------
# 前提:A1=2023-05-01,A2=2023-05-07
FORMULAS={
    D5:'NETWORKDAYS(A1,A2)'  # 计算 A1 到 A2 之间的工作日数(排除周末)
}
# 等效 Java 代码
/*
 * 1. A1 写入起始日期,A2 写入结束日期
 * 2. 计算两个日期之间的工作日数
 */
sheet.createRow(0).createCell(0).setCellValue("2023-05-01");
sheet.createRow(1).createCell(0).setCellValue("2023-05-07");
JAbstractExcelFormula formula = factory.createFormulaInstance("NETWORKDAYS(A1,A2)");

# -------------------------- 10. WORKDAY - 计算偏移工作日 --------------------------
# 等效 Java 代码
/*
 * 1. A1 写入起始日期,A2 写入节假日(可选)
 * 2. 从 A1 开始偏移 3 个工作日(排除 A2 节假日)
 */
sheet.createRow(0).createCell(0).setCellValue("2023-05-15");
sheet.createRow(1).createCell(0).setCellValue("2023-05-17");
JAbstractExcelFormula formula = factory.createFormulaInstance("WORKDAY(A1,3,A2)");
# -------------------------- 8. NOW - 获取当前日期时间 --------------------------
FORMULAS={
    D5:'NOW()'  # 获取当前系统日期+时间
}
# 等效 Java 代码
JAbstractExcelFormula formula = factory.createFormulaInstance("NOW()");

# -------------------------- 9. TODAY - 获取当前日期 --------------------------
FORMULAS={
    D5:'TODAY()'  # 获取当前系统日期(不含时间)
}
# 等效 Java 代码
JAbstractExcelFormula formula = factory.createFormulaInstance("TODAY()");

# -------------------------- 15. TIME - 构造时间 --------------------------
# 等效 Java 代码
/*
 * 构造 14:30:00 时间(Excel 时间序列:0-0.999)
 */
JAbstractExcelFormula formula = factory.createFormulaInstance("TIME(14,30,0)");
# -------------------------- 12. MONTH - 提取月份 --------------------------
# 等效 Java 代码
/*
 * 1. A1 写入日期值 2023-05-15
 * 2. 提取 A1 日期的月份(结果:5)
 */
sheet.createRow(0).createCell(0).setCellValue("2023-05-15");
JAbstractExcelFormula formula = factory.createFormulaInstance("MONTH(A1)");

# -------------------------- 16. WEEKDAY - 提取星期几 --------------------------
# 等效 Java 代码
/*
 * 1. A1 写入日期值 2023-05-15
 * 2. 提取星期几(参数 2 表示:周一=1,周日=7)
 */
sheet.createRow(0).createCell(0).setCellValue("2023-05-15");
JAbstractExcelFormula formula = factory.createFormulaInstance("WEEKDAY(A1,2)");

# -------------------------- 18. WEEKNUM - 提取周数 --------------------------
# 等效 Java 代码
/*
 * 1. A1 写入日期值 2023-01-01
 * 2. 提取周数(参数 1 表示:周日为一周起始)
 */
sheet.createRow(0).createCell(0).setCellValue("2023-01-01");
JAbstractExcelFormula formula = factory.createFormulaInstance("WEEKNUM(A1,1)");

# -------------------------- 19. YEAR - 提取年份 --------------------------
# 等效 Java 代码
/*
 * 1. A1 写入日期值 2023-05-15
 * 2. 提取 A1 日期的年份(结果:2023)
 */
sheet.createRow(0).createCell(0).setCellValue("2023-05-15");
JAbstractExcelFormula formula = factory.createFormulaInstance("YEAR(A1)");

🔤 字符串公式(17个)

公式名语法格式参数规则示例 & 结果对应类名
🧩 CONCATCONCAT(s1,s2...)≥1 个参数CONCAT("A","B") → "AB"JConcatFormula
🆚 EXACTEXACT(s1,s2)2 个参数(区分大小写)EXACT("a","A") → FALSEJExactFormula
🔍 FINDFIND(sub,str,[pos])2-3 个参数FIND("n","apple") → 0JFindFormula
LEFT/→ RIGHTLEFT(text,len)/RIGHT(text,len)2 个参数LEFT("hello",2) → "he"JLeftFormula/JRightFormula
📏 LENLEN(text)1 个参数LEN("text") → 4JLenFormula
🔪 MIDMID(text,start,len)3 个参数MID("apple",2,3) → "ppl"JMIDFormula
🔄 SUBSTITUTESUBSTITUTE(s,o,n,[i])3-4 个参数SUBSTITUTE("a-a","a","b") → "b-b"JSubstituteFormula
🧹 TRIMTRIM(text)1 个参数TRIM(" a ") → "a"JTrimFormula
📝 CONCATENATECONCATENATE(text1, [text2]...)≥1 个参数CONCATENATE("A",1,TRUE) → "A1TRUE"JConcatenateFormula
📉 LOWERLOWER(text)1 个参数LOWER("ExCeL") → "excel"JLowerFormula
🎩 PROPERPROPER(text)1 个参数PROPER("john o'reilly") → "John O'Reilly"JProperFormula
✏️ REPLACEREPLACE(old,start,num,new)4 个参数REPLACE("ABCD",2,2,"XY") → "AXYD"JReplaceFormula
🔎 SEARCHSEARCH(find,within,[start])2-3 个参数SEARCH("n","Banana",3) → 5JSearchFormula
🔁 SUBSTITUTESUBSTITUTE(text,old,new,[nth])3-4 个参数SUBSTITUTE("A-A-A","A","B",2) → "A-B-A"JSubstituteFormula
🎨 TEXTTEXT(value,format)2 个参数TEXT(0.25,"0.0%") → "25.0%"JTextFormula
📈 UPPERUPPER(text)1 个参数UPPER("email") → "EMAIL"JUpperFormula
🔢 VALUEVALUE(text)1 个参数VALUE("¥1,000") → 1000.0JValueFormula

🔤 字符串公式配置示例(整合版)

# 字符串公式配置说明:FORMULAS = { 目标单元格: '公式表达式' }
# 所有公式均映射到 D5 单元格,可根据实际需求修改目标单元格
FORMULAS={
    # ====================== 字符串拼接类 ======================
    # 1. CONCATENATE - 拼接多个单元格/字符串(兼容旧版Excel)
    D5:'CONCATENATE(A1, B1)',  # 拼接 A1 和 B1 单元格内容
    # 2. CONCAT - 拼接多个字符串(新版推荐)
    D5:'CONCAT(A1, B1)',       # 拼接 A1 和 B1 单元格内容(效果同 CONCATENATE)

    # ====================== 字符串对比/查找类 ======================
    # 3. EXACT - 精确对比两个字符串(区分大小写)
    D5:'EXACT("A1", "B1")',    # 对比字符串 "A1" 和 "B1" 是否完全一致
    # 4. FIND - 精准查找子串位置(区分大小写,找不到返回0)
    D5:'FIND("o", "Microsoft")',# 在 "Microsoft" 中查找 "o" 的位置
    # 16. SEARCH - 模糊查找子串位置(不区分大小写)
    D5:'SEARCH("e","Excel")',  # 在 "Excel" 中查找 "e" 的位置(不区分大小写)

    # ====================== 字符串截取类 ======================
    # 5. LEFT - 从左侧截取指定长度字符串
    D5:'LEFT("hello world", 3)',# 截取 "hello world" 左侧3个字符 → "hel"
    # 6. RIGHT - 从右侧截取指定长度字符串
    D5:'RIGHT("hello world", 3)',# 截取 "hello world" 右侧3个字符 → "rld"
    # 7. LEN - 计算字符串长度(含空格)
    D5:'LEN("hello world")',   # 计算 "hello world" 的长度 → 11
    # 8. MID - 从指定位置截取指定长度字符串(起始位置从1开始)
    D5:'MID("hello world",1,2)',# 从第1位开始截取2个字符 → "he"

    # ====================== 字符串替换/清理类 ======================
    # 9. SUBSTITUTE - 替换指定子串(全量替换)
    D5:'SUBSTITUTE("hello world","hello","new")',# 将 "hello" 替换为 "new" → "new world"
    # 10. TRIM - 去除字符串首尾空格(保留中间空格)
    D5:'TRIM("hello world")',  # 清理首尾空格(示例无空格,结果仍为 "hello world")
    # 12. REPLACE - 按位置替换指定长度子串
    D5:'REPLACE("ABCD",2,2,"XY")',# 从第2位开始替换2个字符 → "AXYD"

    # ====================== 字符串格式转换类 ======================
    # 10. LOWER - 转换为全小写
    D5:'LOWER("hello world")', # 转换为小写(示例无大写,结果仍为 "hello world")
    # 11. PROPER - 首字母大写(其余小写)
    D5:'PROPER("hello world")',# 转换为首字母大写 → "Hello World"
    # 13. TEXT - 将数值格式化为指定字符串
    D5:'TEXT(0.25,"0.0%")',    # 将 0.25 格式化为百分比 → "25.0%"
    # 14. UPPER - 转换为全大写
    D5:'UPPER("email")',       # 转换为大写 → "EMAIL"
    # 15. VALUE - 将字符串转换为数值(自动识别金额/千分位)
    D5:'VALUE("¥1,000")'       # 将金额字符串转为数值 → 1000.0
}

🔍 逻辑公式(3个:IF、AND、OR)

公式名语法格式参数规则示例 & 结果对应类名
🎯 IFIF(cond,t,f)3 个参数IF(A1>0,"Yes","No") → 若A1>0返回"Yes",否则返回"No"JIfFormula
ANDAND(b1,b2...)≥1 个参数AND(TRUE,FALSE) → FALSEJAndFormula
🟡 OROR(b1,b2...)≥1 个参数OR(TRUE,FALSE) → TRUEJORFormula

🧠 逻辑&查找公式配置示例(整合版)

# 公式配置说明:FORMULAS = { 目标单元格: '公式表达式' }
# 所有公式均映射到 D5 单元格,可根据实际需求修改目标单元格
FORMULAS={
    # ====================== 逻辑判断类 ======================
    # 1. IF - 条件判断(满足条件返回t,否则返回f)
    D5:'IF(D2>0,"Yes","No")',  # 若 D2 单元格值>0,返回"Yes";否则返回"No"
    
    # 2. AND - 多条件与判断(所有条件为TRUE时,结果才为TRUE)
    D5:'AND(TRUE,FALSE)',      # 同时满足TRUE和FALSE → 结果为FALSE
    
    # 3. OR - 多条件或判断(任一条件为TRUE时,结果即为TRUE)
    D5:'OR(TRUE,FALSE)',       # 满足TRUE或FALSE → 结果为TRUE

    # ====================== 数据查找类 ======================
    # 4. LOOKUP - 向量查找(在指定区域查找值,返回对应区域结果)
    D5:'LOOKUP(22, D2:D4, C2:C4)'  # 在 D2:D4 区域查找22,返回 C2:C4 对应位置的值
}

📊 图表类型支持

图表类型示例用途
柱状图销售数据对比数据比较
条形图季度销售排行排名展示
折线图温度变化趋势趋势分析
饼图市场份额分布占比展示
面积图销售趋势分析累积趋势
散点图身高体重分布相关性分析
雷达图能力评估多维评估
3D图表地形高度示例三维数据

基础结构

图表配置采用类 JSON 格式的领域特定语言 (DSL),基础结构如下

图表配置关键字说明

1. TYPE(必填)

  • 说明:指定图表类型
  • 支持类型
    • LINE(折线图)
    • COLUMN(柱状图)
    • BAR(条形图)
    • BAR3D(3D 条形图)
    • PIE(饼图)
    • AREA(面积图)
    • AREA3D(3D 面积图)
    • SCATTER(散点图)
    • RADAR(雷达图)
    • SURFACE(曲面图)

2. TITLE(必填)

  • 说明:图表的标题文本
  • 类型:字符串
  • 格式要求:需用双引号"或单引号'包裹
  • 示例TITLE = "2023年销售数据统计"

3. CATEGORY_AXIS(可选)

  • 说明:分类轴(通常为X轴)的标题文本
  • 适用范围:除饼图外的大多数图表类型
  • 类型:字符串
  • 格式要求:需用双引号"或单引号'包裹
  • 示例CATEGORY_AXIS = "产品类别"

4. VALUE_AXIS(可选)

  • 说明:数值轴(通常为Y轴)的标题文本
  • 适用范围:除饼图、雷达图外的图表类型
  • 类型:字符串
  • 格式要求:需用双引号"或单引号'包裹
  • 示例VALUE_AXIS = "销售额(万元)"

5. CATEGORIES(必填)

  • 说明:图表的分类维度数据(X轴数据或分组依据)
  • 类型:数组
  • 内容:包含字符串或数值类型的分类值集合
  • 示例
    • CATEGORIES = ["1月", "2月", "3月", "4月"]
    • CATEGORIES = ["Apple", "Samsung", "Xiaomi"]

6. SERIES(必填)

  • 说明:图表的数据系列集合,每个系列代表一组相关数据
  • 类型:数组,包含一个或多个数据系列对象
  • 每个系列对象包含
    • NAME:系列名称(字符串类型,需用引号包裹)
    • DATA:系列数据(数组类型,包含数值集合)
// ============================================================================
#  柱状图 column chart
// ============================================================================
柱状图
          
        JChartData chartData = new JChartData();
        chartData.setTitle("销售数据统计");
        chartData.setCategoryAxisTitle("产品");
        chartData.setValueAxisTitle("销量");
        chartData.setCategories(Arrays.asList(
        "产品A", "产品B", "产品C", "产品D"));
        JSeriesData series1 = new JSeriesData();
        series1.setName("第一季度");
        series1.setData(Arrays.asList(120, 200, 150, 180));
        JSeriesData series2 = new JSeriesData();
        series2.setName("第二季度");
        series2.setData(Arrays.asList(180, 210, 190, 220));
        chartData.setSeries(Arrays.asList(series1, series2));
        XSSFWorkbook workbook = JExcelChartFactory.
        createWorkbookWithChart(chartData, JExcelChartType
        .COLUMN, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
           "D://test//SalesReport.xlsx")
        ) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
        } catch (IOException e) {
            e.printStackTrace();
        }
          
      
column
column
// ============================================================================
#  条形图 bar chart
// ============================================================================
条形图
          
       JChartData salesData = new JChartData();
        salesData.setTitle("2023年季度销售数据");
        salesData.setCategoryAxisTitle("季度");
        salesData.setValueAxisTitle("销售额(万元)");
        salesData.setCategories(Arrays.asList("第一季度",
        "第二季度", "第三季度", "第四季度"));
        JSeriesData productA = new JSeriesData();
        productA.setName("产品A");
        productA.setData(Arrays.asList(450, 520, 480, 600));
        JSeriesData productB = new JSeriesData();
        productB.setName("产品B");
        productB.setData(Arrays.asList(320, 380, 420, 500));
        JSeriesData productC = new JSeriesData();
        productC.setName("产品C");
        productC.setData(Arrays.asList(280, 310, 350, 400));
        salesData.setSeries(Arrays.asList(productA, productB,
        productC));
        salesData.setSeries(Arrays.asList(productA, productB,
         productC));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                salesData, JExcelChartType.BAR, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
         "D://test//bar.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook,
           out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
bar
bar
// ============================================================================
#  条形图 bar3d chart
// ============================================================================
条形图
          
        JChartData chartData = new JChartData();
        chartData.setTitle("产品季度销售(3D)");
        chartData.setCategoryAxisTitle("产品");
        chartData.setValueAxisTitle("销售额(万元)");
        chartData.setCategories(Arrays.asList("笔记本"
        , "手机", "平板", "显示器", "配件"));
        JSeriesData q1 = new JSeriesData();
        q1.setName("第一季度");
        q1.setData(Arrays.asList(450, 680, 320, 280, 190));
        JSeriesData q2 = new JSeriesData();
        q2.setName("第二季度");
        q2.setData(Arrays.asList(520, 720, 380, 310, 210));
        JSeriesData q3 = new JSeriesData();
        q3.setName("第三季度");
        q3.setData(Arrays.asList(480, 750, 350, 330, 230));
        chartData.setSeries(Arrays.asList(q1, q2, q3));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                chartData, JExcelChartType.BAR3D, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
          "D://test//bar3D.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
bar3d
bar3d
// ============================================================================
#  折线图 line chart
// ============================================================================
折线图
          
        JChartData chartData = new JChartData();
        chartData.setTitle("2023年北京月平均温度变化");
        chartData.setCategoryAxisTitle("月份");
        chartData.setValueAxisTitle("温度(℃)");
        chartData.setCategories(Arrays.asList(
                "1月", "2月", "3月", "4月", "5月", "6月",
                "7月", "8月", "9月", "10月", "11月", "12月"
        ));
        JSeriesData avgTemp = new JSeriesData();
        avgTemp.setName("平均温度");
        avgTemp.setData(Arrays.asList(
                -3.2, 0.5, 7.8, 15.2, 21.3, 25.7,
                27.9, 26.8, 21.5, 14.6, 6.3, -1.0
        ));
        JSeriesData maxTemp = new JSeriesData();
        maxTemp.setName("最高温度");
        maxTemp.setData(Arrays.asList(
                2.1, 5.3, 12.7, 20.5, 26.8, 30.4,
                32.6, 31.5, 27.2, 20.8, 12.5, 4.2
        ));
        JSeriesData minTemp = new JSeriesData();
        minTemp.setName("最低温度");
        minTemp.setData(Arrays.asList(
                -8.5, -4.2, 2.9, 9.9, 15.8, 21.0,
                23.2, 22.1, 15.8, 8.4, 0.1, -6.2
        ));
        chartData.setSeries(Arrays.asList(avgTemp,
        maxTemp, minTemp));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                chartData, JExcelChartType.LINE, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
           "D://test//line.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
line
line
// ============================================================================
#  饼状图 pie chart
// ============================================================================
饼状图
          
           JChartData chartData = new JChartData();
        chartData.setTitle("2023年智能手机市场份额");
        JSeriesData marketShare = new JSeriesData();
        marketShare.setName("市场份额");
        marketShare.setData(Arrays.asList(38.5, 22.3,
    15.7, 10.2, 8.5, 4.8));
        chartData.setCategories(Arrays.asList(
                "Apple", "Samsung", "Xiaomi", "OPPO", "vivo", "其他"
        ));
        chartData.setSeries(Collections.singletonList(marketShare));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                chartData, JExcelChartType.PIE, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
        "D://test//pie.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
line
pie
// ============================================================================
#  面积图 area chart
// ============================================================================
面积图
          
          JChartData chartData = new JChartData();
        chartData.setTitle("季度销售趋势分析");
        chartData.setCategoryAxisTitle("季度");
        chartData.setValueAxisTitle("销售额(万元)");
        chartData.setCategories(Arrays.asList("Q1", 
        "Q2", "Q3", "Q4"));
        JSeriesData productA = new JSeriesData();
        productA.setName("产品线A");
        productA.setData(Arrays.asList(120, 150, 180, 210));
        JSeriesData productB = new JSeriesData();
        productB.setName("产品线B");
        productB.setData(Arrays.asList(80, 110, 130, 170));
        JSeriesData productC = new JSeriesData();
        productC.setName("产品线C");
        productC.setData(Arrays.asList(60, 75, 90, 120));
        chartData.setSeries(Arrays.asList(productA, 
        productB, productC));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                chartData, JExcelChartType.AREA, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
        "D://test//area.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
line
area
// ============================================================================
#  面积图 area3d chart
// ============================================================================
面积图
          
          JChartData chartData = new JChartData();
        chartData.setTitle("季度销售趋势(3D)");
        chartData.setCategoryAxisTitle("季度");
        chartData.setValueAxisTitle("销售额(万元)");
        chartData.setCategories(Arrays.asList("Q1", 
        "Q2", "Q3", "Q4"));
        JSeriesData productA = new JSeriesData();
        productA.setName("产品线A");
        productA.setData(Arrays.asList(120, 150, 180, 210));
        JSeriesData productB = new JSeriesData();
        productB.setName("产品线B");
        productB.setData(Arrays.asList(80, 110, 130, 170));
        JSeriesData productC = new JSeriesData();
        productC.setName("产品线C");
        productC.setData(Arrays.asList(60, 75, 90, 120));
        chartData.setSeries(Arrays.asList(productA, productB,
        productC));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                chartData, JExcelChartType.AREA3D, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
            "D://test//area3D.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
line
area3d
// ============================================================================
#  散点图 scatter chart
// ============================================================================
散点图
          
        JChartData chartData = new JChartData();
        chartData.setTitle("身高体重分布");
        chartData.setCategoryAxisTitle("身高(cm)");
        chartData.setValueAxisTitle("体重(kg)");
        chartData.setCategories(Arrays.asList(
   "160", "165", "170", "175", "180", "185", "190"
        ));
        JSeriesData male = new JSeriesData();
        male.setName("男性");
        male.setData(Arrays.asList(55, 60, 65, 70, 
        75, 80, 85));
        JSeriesData female = new JSeriesData();
        female.setName("女性");
        female.setData(Arrays.asList(50, 55, 58, 
        62, 65, 68, 70));
        chartData.setSeries(Arrays.asList(male, female));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                chartData, JExcelChartType.SCATTER, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
        "D://test//scatter.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
line
scatter
// ============================================================================
#  雷达图 radar chart
// ============================================================================
雷达图
          
       JChartData chartData = new JChartData();
        chartData.setTitle("员工能力评估");
        chartData.setCategories(Arrays.asList(
                "编程能力", "沟通能力", "设计能力",
                "解决问题", "团队合作", "学习能力"
        ));
        JSeriesData employeeA = new JSeriesData();
        employeeA.setName("员工A");
        employeeA.setData(Arrays.asList(90, 70,
        85, 80, 75, 88));
        JSeriesData employeeB = new JSeriesData();
        employeeB.setName("员工B");
        employeeB.setData(Arrays.asList(75, 85, 70,
        90, 80, 75));
        chartData.setSeries(Arrays.asList(employeeA, 
        employeeB));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                chartData, JExcelChartType.RADAR, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
        "D://test//radar.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
line
radar
// ============================================================================
#  surface surface chart
// ============================================================================
surface
          
        JChartData chartData = new JChartData();
        chartData.setTitle("地形高度示例");
        chartData.setCategoryAxisTitle("X坐标");
        chartData.setValueAxisTitle("Y坐标");
        chartData.setCategories(Arrays.asList(
        "1", "2", "3", "4", "5"));
        JSeriesData row1 = new JSeriesData();
        row1.setName("Y=1");
        row1.setData(Arrays.asList(10, 15, 25, 
        30, 25));
        JSeriesData row2 = new JSeriesData();
        row2.setName("Y=2");
        row2.setData(Arrays.asList(15, 20, 35, 
        40, 35));
        JSeriesData row3 = new JSeriesData();
        row3.setName("Y=3");
        row3.setData(Arrays.asList(25, 35, 50, 
        55, 50));
        JSeriesData row4 = new JSeriesData();
        row4.setName("Y=4");
        row4.setData(Arrays.asList(20, 30, 45, 
        50, 45));
        JSeriesData row5 = new JSeriesData();
        row5.setName("Y=5");
        row5.setData(Arrays.asList(15, 25, 35, 
        40, 35));
        chartData.setSeries(Arrays.asList(row1, row2, 
        row3, row4, row5));
        XSSFWorkbook workbook = JExcelChartFactory
        .createWorkbookWithChart(
                chartData, JExcelChartType.SURFACE, "销售报表");
        try (FileOutputStream out = new FileOutputStream(
        "D://test//surface.xlsx")) {
            JExcelChartFactory.writeWorkbookToStream(workbook, out);
            System.out.println("Excel文件生成成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
         
      
line
surface

🎨 样式配置

🎨 行 & 字体样式配置参数

元素名称描述取值/格式
📏 height行高像素值(整数)
🔢 rowNum行号整数(0 起始)
🎨 rowStyle关联单元格样式JCellStyle 对象
📐 heightInPoints行高(点数)高精度小数(1点=1/72英寸)
🙈 zeroHeight行是否隐藏true/false
🔤 fontHeightInPoints字体大小(点数)高精度小数(如 12.0)/整数(如 3)
✍️ fontName字体名称字符串(如 "Arial")
📏 fontHeight字体高度整数(如 3)
📝 underLine下划线参考 JFont 枚举
𝗕 bold粗体true/false
italic斜体true/false
🌈 color字体颜色参考 JColorEnum 枚举
🚫 strikeout删除线true/false

📋 表格元素配置参数

常量名称描述取值/格式
🔢 index样式索引标识高精度小数
📊 dataFormat数据格式编码高精度小数格式码
📝 dataFormatString数据格式字符串格式字符串(如 "yyyy-MM-dd")
✍️ font字体对象引用Font 对象
🔖 fontIndex字体索引引用高精度小数索引值
🙈 hidden单元格可见性true/false
🔒 locked单元格保护true/false
📜 quotePrefixed引号前缀显示true/false
🧭 alignment水平对齐方式left/right/center/center-section/general/fill/justify/distributed
📥 wrapText文本自动换行true/false
🧱 verticalAlignment垂直对齐方式top/bottom/center/justify/distributed
🔄 rotation文本旋转角度高精度小数(0-180 度)
📏 indention文本缩进级别高精度小数(缩进层级)
📐 borderLeft左侧边框样式边框样式常量
📐 borderRight右侧边框样式边框样式常量
📐 borderTop顶部边框样式边框样式常量
📐 borderBottom底部边框样式边框样式常量
🌈 leftBorderColor左侧边框颜色颜色编码/十六进制值
🌈 rightBorderColor右侧边框颜色颜色编码/十六进制值
🌈 topBorderColor顶部边框颜色颜色编码/十六进制值
🌈 bottomBorderColor底部边框颜色颜色编码/十六进制值
🎨 fillPattern单元格填充样式填充样式常量
🎨 fillBackgroundColor背景填充颜色颜色编码/十六进制值
🎨 fillForegroundColor前景填充颜色颜色编码/十六进制值
🪄 shrinkToFit文本自适应单元格true/false
𝗕 bold字体粗体样式Boolean (true/false)
📛 fontName字体系列名称字符串(如 "Arial", "Times New Roman")
📏 fontHeightInPoints字体大小(点数)高精度小数(如 12.0, 14.5)
📏 fontHeight字体高度(缇)高精度小数(如 240, 280)
italic字体斜体样式Boolean (true/false)
📝 underLine下划线类型字符串(通过 JFont.nameOf() 映射)
🌈 color字体颜色字符串(通过 JColorEnum.codeOf() 映射)
🚫 strikeout删除线文本Boolean (true/false)

📐 边框样式取值说明

输入字符串值边框样式常量描述
"none"NONE无边框
"thin"THIN细线条边框
"medium"MEDIUM中等粗细边框
"dashed"DASHED虚线边框
"dotted"DOTTED点线边框
"thick"THICK粗线条边框
"double"DOUBLE双线条边框
"hair"HAIR极细边框(发丝线)
"medium_dashed"MEDIUM_DASHED中等粗细虚线边框
"dash_dot"DASH_DOT点划线交替边框
"medium_dash_dot"MEDIUM_DASH_DOT中等粗细点划线边框
"dash_dot_dot"DASH_DOT_DOT点划点交替边框
"medium_dash_dot_dot"MEDIUM_DASH_DOT_DOT中等粗细点划点边框
"slanted_dash_dot"SLANTED_DASH_DOT斜向点划线边框

🎨 填充样式取值说明

常量名称描述取值/格式
no_fill无填充样式FillPatternType.NO_FILL
solid_foreground纯色前景填充FillPatternType.SOLID_FOREGROUND
fine_dots细点填充样式FillPatternType.FINE_DOTS
alt_bars交替条纹填充FillPatternType.ALT_BARS
sparse_dots稀疏点填充样式FillPatternType.SPARSE_DOTS
thick_horz_bands粗水平条纹FillPatternType.THICK_HORZ_BANDS
thick_vert_bands粗垂直条纹FillPatternType.THICK_VERT_BANDS
thick_backward_diag粗反向对角线FillPatternType.THICK_BACKWARD_DIAG
thick_forward_diag粗正向对角线FillPatternType.THICK_FORWARD_DIAG
big_spots大斑点填充样式FillPatternType.BIG_SPOTS
bricks砖块纹理填充FillPatternType.BRICKS
thin_horz_bands细水平条纹FillPatternType.THIN_HORZ_BANDS
thin_vert_bands细垂直条纹FillPatternType.THIN_VERT_BANDS
thin_backward_diag细反向对角线FillPatternType.THIN_BACKWARD_DIAG
thin_forward_diag细正向对角线FillPatternType.THIN_FORWARD_DIAG
squares正方形纹理填充FillPatternType.SQUARES
diamonds菱形纹理填充FillPatternType.DIAMONDS
less_dots低密度点填充FillPatternType.LESS_DOTS
least_dots最低密度点填充FillPatternType.LEAST_DOTS

🌈 JColorEnum 颜色常量(按编码名)

编码名描述索引值映射颜色
black1黑色(变体1)0IndexedColors.BLACK
white1白色(变体1)1IndexedColors.WHITE
red1红色(变体1)2IndexedColors.RED
brightGreen1亮绿色(变体1)3IndexedColors.BRIGHT_GREEN
blue1蓝色(变体1)4IndexedColors.BLUE
yellow1黄色(变体1)5IndexedColors.YELLOW
pink1粉色(变体1)6IndexedColors.PINK
turquoise1青绿色(变体1)7IndexedColors.TURQUOISE
black标准黑色8IndexedColors.BLACK
white标准白色9IndexedColors.WHITE
red标准红色10IndexedColors.RED
brightGreen标准亮绿色11IndexedColors.BRIGHT_GREEN
blue标准蓝色12IndexedColors.BLUE
yellow标准黄色13IndexedColors.YELLOW
pink标准粉色14IndexedColors.PINK
turquoise标准青绿色15IndexedColors.TURQUOISE
darkRed深红色16IndexedColors.DARK_RED
green绿色17IndexedColors.GREEN
darkBlue深蓝色18IndexedColors.DARK_BLUE
darkYellow深黄色19IndexedColors.DARK_YELLOW
violet紫罗兰色20IndexedColors.VIOLET
teal水鸭色21IndexedColors.TEAL
grey25Percent25%灰色22IndexedColors.GREY_25_PERCENT
grey50Percent50%灰色23IndexedColors.GREY_50_PERCENT
cornflowerBlue矢车菊蓝24IndexedColors.CORNFLOWER_BLUE
maroon褐红色25IndexedColors.MAROON
lemonChiffon柠檬绸色26IndexedColors.LEMON_CHIFFON
lightTurquoise1浅青绿色(变体1)27IndexedColors.LIGHT_TURQUOISE
orchid兰花紫28IndexedColors.ORCHID
coral珊瑚色29IndexedColors.CORAL
royalBlue宝蓝色30IndexedColors.ROYAL_BLUE
lightCornflowerBlue浅矢车菊蓝31IndexedColors.LIGHT_CORNFLOWER_BLUE
skyBlue天蓝色40IndexedColors.SKY_BLUE
lightTurquoise浅青绿色41IndexedColors.LIGHT_TURQUOISE
lightGreen浅绿色42IndexedColors.LIGHT_GREEN
lightYellow浅黄色43IndexedColors.LIGHT_YELLOW
paleBlue淡蓝色44IndexedColors.PALE_BLUE
rose玫瑰红45IndexedColors.ROSE
lavender薰衣草紫46IndexedColors.LAVENDER
tan棕褐色47IndexedColors.TAN
lightBlue浅蓝色48IndexedColors.LIGHT_BLUE
aqua水绿色49IndexedColors.AQUA
lime酸橙绿50IndexedColors.LIME
gold金色51IndexedColors.GOLD
lightOrange浅橙色52IndexedColors.LIGHT_ORANGE
orange橙色53IndexedColors.ORANGE
blueGrey蓝灰色54IndexedColors.BLUE_GREY
grey40Percent40%灰色55IndexedColors.GREY_40_PERCENT
darkTeal深水鸭色56IndexedColors.DARK_TEAL
seaGreen海绿色57IndexedColors.SEA_GREEN
darkGreen深绿色58IndexedColors.DARK_GREEN
oliveGreen橄榄绿59IndexedColors.OLIVE_GREEN
brown棕色60IndexedColors.BROWN
plum李子紫61IndexedColors.PLUM
indigo靛蓝色62IndexedColors.INDIGO
grey80Percent80%灰色63IndexedColors.GREY_80_PERCENT
automatic自动颜色64IndexedColors.AUTOMATIC

单元格样式

EXPORT  WITH SHEET="学生表",HEADER=true,
MAPPING={
	"id":"主键",
	"name":"姓名",
	"gender":"性别",
	"age":"年龄",
	"enrollmentDate":"入学时间",
	"className":"班级",
	"ignoreField":"是否忽略"
},
FORMULAS={
D5:'ABS(D2)'},  STYLE={
    ROW 1: {
      fontName: Arial,
      fontHeightInPoints: 12,
      italic: true,
      color: yellow,
      bold: true
    }}
List<Map<String, Object>> data = JObjectConverter.convert(getData());
FileOutputStream fileOutputStream=new FileOutputStream("d://test//style.xlsx");
JQuickExcelCommonExportExecutor executor = new JQuickExcelCommonExportExecutor();
JExcelExportModel config = (JExcelExportModel) executor.execute(rule);
HashMap<String,Object> map = new HashMap<>();
map.put("1","男");
map.put("0","女");
JContext context = new JContext();
context.put("dict",map);
JExcelExportHandler handler = new JExcelExportHandler(config,context,JQuickRow.toRows(data));
Workbook workbook=handler.getWorkBook();
workbook.write(fileOutputStream);

🔄 合并策略

策略描述适用场景
MERGE_WITH_MAX取最大值成绩、销售额统计
MERGE_WITH_MIN取最小值最低价、最低分
MERGE_WITH_AVG取平均值平均分、平均工资
MERGE_WITH_SUM求和总计、汇总
MERGE_WITH_FIRST取第一个值主数据保留
MERGE_WITH_LAST取最后一个值最新数据
MERGE_WITH_CONCAT字符串连接名称合并
MERGE_WITH_COUNT计数统计数量
MERGE_WITH_VALUE固定值汇总标签
EXPORT WITH FOOTER="Generated by JQuickExcel on ${current_date()}"

Comprehensive Export Test

EXPORT WITH
SHEET="AnnualReport",
HEADER=true,
FORMAT={
"A:A": "text",
"B:B": "number",
"C:C": "currency",
"D1:D100": "date"
},
STYLE={
ROW 1: {"font": "bold", "color": "blue", "align": "center"},
COL B: {"bgcolor": "lightyellow"},
A1:D1: {"border": "thick"}
},
FORMULAS={
E2:E100: "SUM(B2:D2)",
F1: "TOTAL:",
F2:F100: "AVERAGE(B2:D2)"
},
MERGE: {
ROWS 1..1,
COLS A..F WITH FIRST
},
GRAPH={
TYPE=PIE,
TITLE="Revenue Breakdown",
CATEGORIES=["Q1", "Q2", "Q3", "Q4"],
SERIES=[{NAME="2023", DATA=[45000, 52000, 48000, 51000]}]
},
FOOTER="Confidential - Internal Use Only"

捐献 ☕

感谢您使用这个开源项目!它完全免费并将持续维护,但开发者确实需要您的支持。


如何支持我们

  1. 请我喝杯咖啡
    果这个项目为您节省了时间或金钱,请考虑通过小额捐赠支持我。

  2. 您的捐赠用途

  • 维持项目运行的服务器成本.
  • 开发新功能以提供更多价值.
  • 优化文档以提升用户体验.
  1. 每一分都很重要
    即使是1分钱的捐赠也能激励我熬夜调试!

为什么捐赠?

✔️ 保持项目永远免费且无广告.
✔️ 支持及时响应问题和社区咨询.
✔️ 实现计划中的未来功能.

感谢您成为让开源世界更美好的伙伴!


补充说明

  • 本项目和产品维护.
  • 您的支持确保其可持续性和成长 .

🌟 立即支持

赞助时欢迎通过 email 留言。您的名字将被列入项目README文件的 "特别感谢" 名单中! Ali Pay Wechat Pay