跳转到内容

JQuick-Excel

JQuick-Excel 是一个轻量级 Java 框架,用于导入与导出 xls / xlsx 工作簿。它把 XML 服务定义与声明式 DSL 结合起来,覆盖映射、转换、校验、公式、样式、合并汇总、图表与页脚。

XML 定义让 Excel 规则紧贴服务契约:Java 调用方从该定义创建代理,然后向导入 / 导出操作传入业务数据、流与上下文变量。

  • 将工作表导入为 List<JQuickRow>。
  • 将业务数据导出为工作簿。
  • 按名称或索引选择工作表。
  • 双向映射表头与字段。
  • 使用上下文感知表达式转换值。
  • 校验单元格、行、列与矩形区域。
  • 渲染公式、样式、合并、图表与页脚。
  • 双格式支持:同时支持 xls 与 xlsx。
  • 声明式规则:通过 IMPORT WITH 与 EXPORT WITH 定义导入导出规则。
  • 字段映射与转换:字段映射、格式化与基于求值器的转换。
  • 20 条内置校验规则,并支持显式的范围作用域。
  • 公式能力:数学、日期时间、文本、逻辑与查找公式。
  • 10 种图表类型,通过 GRAPH DSL 配置。
  • 样式设置:行、列、单元格与区域样式。
  • 9 种合并汇总策略。
  • 42 套内置导出主题。
  • 大文件友好:流式导出、大文件导入与样式缓存配置。
<dependency>
<groupId>io.github.paohaijiao</groupId>
<artifactId>jquick-excel</artifactId>
<version>3.7.0</version>
</dependency>

在 resources 目录下创建 jquick-excel.xml:

<?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">
<![CDATA[
EXPORT WITH
SHEET="Students",
HEADER=true,
MAPPING={"id":"ID","name":"Name","age":"Age"}
]]>
</excel>
<excel name="importExcel" returnClass="java.util.List">
<![CDATA[
IMPORT WITH
SHEET="Students",
HEADER=true,
MAPPING={"ID":"id","Name":"name","Age":"age"}
]]>
</excel>
</excels>

XML 中的 namespace 指向被代理的服务接口:

import com.github.paohaijiao.statement.JQuickRow;
import com.github.paohaijiao.xml.param.Param;
import java.util.List;
public interface JQuickExcelExportService {
void exportExcel(@Param("field") String field, @Param("value") String value);
List<JQuickRow> importExcel(@Param("field") String field, @Param("value") String value);
}

导出解析器接收转换后的行数据与输出流,JQuickXmlFactory 依据 XML 创建服务代理:

import com.github.paohaijiao.convert.JObjectConverter;
import com.github.paohaijiao.statement.JQuickRow;
import com.github.paohaijiao.xml.JQuickFactory;
import com.github.paohaijiao.xml.JQuickXmlFactory;
import com.github.paohaijiao.xml.parse.JQuickParseHandler;
import com.github.paohaijiao.xml.parse.excel.JQuickExcelExportXmlParseFactory;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class XmlExportExample {
public static void main(String[] args) throws Exception {
List<Map<String, Object>> data = new ArrayList<>();
Map<String, Object> student = new LinkedHashMap<>();
student.put("id", "1001");
student.put("name", "Alice");
student.put("age", 20);
data.add(student);
List<JQuickRow> rows = JQuickRow.toRows(JObjectConverter.convert(data));
try (OutputStream output = new FileOutputStream("students.xlsx")) {
JQuickParseHandler parser = new JQuickExcelExportXmlParseFactory(rows, output);
JQuickFactory factory = new JQuickXmlFactory(parser, "jquick-excel.xml");
JQuickExcelExportService service = factory.createApi(JQuickExcelExportService.class);
service.exportExcel("field", "value");
}
}
}

导入解析器接收 JContext 与输入流,上下文值可在 DSL 转换中使用:

import com.github.paohaijiao.context.JContext;
import com.github.paohaijiao.statement.JQuickRow;
import com.github.paohaijiao.xml.JQuickFactory;
import com.github.paohaijiao.xml.JQuickXmlFactory;
import com.github.paohaijiao.xml.parse.JQuickParseHandler;
import com.github.paohaijiao.xml.parse.excel.JQuickExcelImportXmlParseFactory;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class XmlImportExample {
public static void main(String[] args) throws Exception {
try (InputStream input = XmlImportExample.class.getClassLoader()
.getResourceAsStream("students.xlsx")) {
Map<String, Object> gender = new HashMap<>();
gender.put("Male", "1");
gender.put("Female", "2");
JContext context = new JContext();
context.put("dict", gender);
JQuickParseHandler parser = new JQuickExcelImportXmlParseFactory(context, input);
JQuickFactory factory = new JQuickXmlFactory(parser, "jquick-excel.xml");
JQuickExcelExportService service = factory.createApi(JQuickExcelExportService.class);
List<JQuickRow> rows = service.importExcel("field", "value");
System.out.println(rows.size());
}
}
}
IMPORT WITH
SHEET="Students",
HEADER=true,
MAPPING={"ID":"id","Name":"name","Age":"age"},
TRANSFORM={"name":toUpper(${name})},
VALIDATION={
ROW 2..100:{
integer{required:true,msg:'Age must be an integer'}
},
C2:C100:{
email{required:true,msg:'Invalid email'}
}
}
参数 说明 示例
SHEET 按名称或索引选择工作表 SHEET="Students"
HEADER 首行是否为表头 HEADER=true
MAPPING 表头到目标字段的映射 MAPPING={"ID":"id"}
TRANSFORM 导入值的转换 TRANSFORM={"name":toUpper(${name})}
VALIDATION 对指定范围应用校验规则 VALIDATION={C2:C4:{integer{required:true}}}

校验与公式目标支持行、列、单元格与矩形区域四种写法:ROW 5 / ROW 1..10、COL A / COL A..D、C1、A1:B5。

规则 用途 规则 用途
boolean 布尔值校验 email 邮箱格式
integer 整数校验 mobile 手机号格式
decimal 小数校验 max_length / min_length 字符串长度上下限
max_value / min_value 数值上下限 regex 正则校验
date_format 日期格式 start_with / not_start_with 前缀要求 / 禁止
max_date / min_date 日期上下限 end_with / not_end_with 后缀要求 / 禁止
dict 字典项校验 contain / not_contain 子串要求 / 禁止

导出 DSL:格式、公式、样式、合并、图表与页脚

Section titled “导出 DSL:格式、公式、样式、合并、图表与页脚”
EXPORT WITH
SHEET="Report",
HEADER=true,
MAPPING={"id":"ID","name":"Name","amount":"Amount"},
FORMAT={"amount":"currency"},
TRANSFORM={"name":toUpper(${name})},
FORMULAS={D2:'SUM(B2:C2)'},
STYLE={ROW 1:{bold:true}},
MERGE:{ROWS 1..1,COLS A..D WITH FIRST},
GRAPH={TYPE=PIE,TITLE="Revenue",CATEGORIES=["Q1"],SERIES=[{NAME="2023",DATA=[1]}]},
FOOTER="Generated by JQuickExcel"
参数 说明 示例
SHEET 目标工作表 SHEET="Report"
HEADER 是否生成表头 HEADER=true
MAPPING 源字段到表头的映射 MAPPING={"id":"ID"}
FORMAT Excel 显示格式 FORMAT={"amount":"currency"}
TRANSFORM 输出前的值转换 TRANSFORM={"name":toUpper(${name})}
FORMULAS 向目标写入公式 FORMULAS={D2:'SUM(B2:C2)'}
STYLE 向目标应用样式 STYLE={ROW 1:{bold:true}}
MERGE 定义合并汇总 MERGE:{ROWS 1..1,COLS A..D WITH FIRST}
GRAPH 定义图表数据与类型 GRAPH={TYPE=PIE,...}
FOOTER 页脚文本 FOOTER="Generated by JQuickExcel"