public class TemplateSheet extends Sheet
TemplateSheet将复制模板工作表的样式并替换占位符,
同时TemplateSheet也可以和其它Worksheet混用,这意味着可以添加多个模板工作表和普通工作表。
创建模板工作表需要指定模板文件,它可以是本地文件也可是输入流InputStream,支持的类型包含xls
和xlsx两种格式,除模板文件外还需要指定工作表,未指定工作表时默认以第一个工作表做为模板。
TemplateSheet工作表导出时不受ExcelColumn注解限制,导出的数据范围由模板中的占位符决定,
默认占位符由一对封闭的大括号${key}组成,虽然占位符与EL表达式写法相似但模板占位符并不具备EL的能力,
所以无法使用${1 + 2}或${System.getProperty("user.name")}这类语句来做运算,
占位符仅做替换不做运算所以不需要担心安全漏洞问题。
setData(java.lang.Object)方法为占位符绑定值,支持对象、Map、Array和List类型,数据量较大时也可以绑定一个数据生产者data-supplier来分片拉取数据,
它被定义为BiFunction<Integer, T, List<T>>,其中第一个入参Integer表示已拉取数据的记录数
(并非已写入数据),第二个入参T表示上一批数据中最后一个对象,业务端可以通过这两个参数来计算下一批数据应该从哪个节点开始拉取,
通常你可以使用第一个参数除以每批拉取的数据大小来确定当前页码,如果数据已排序则可以使用T对象的排序字段来计算下一批数据的游标以跳过
limit ... offset ... 分页查询从而极大提升取数性能。
new Workbook("模板测试")
// 模板工作表
.addSheet(new TemplateSheet(Paths.get("./template.xlsx"))
// 免分页查询用户,根据ID排序并游标拉取
.setData((i,lastOne) -> queryUser(i > 0 ? ((User)lastOne).getId():0))
// 普通对象数组工作表
.addSheet(new ListSheet<>().setData(list))
.writeTo(Paths.get("/tmp/"));
每个占位符都有一个命名空间,使用${namespace.key}这种格式来添加命名空间,默认命名空间为null。
占位符中还包含三个内置函数它们分别为[@link:]、[@list:]和[@media:],
分别用于设置单元格的值为超链接、序列和图片,其中序列的值可以从源工作表中获取也可以使用setData(String, Object)来设置。
注意:内置函数必须独占一个单元格且仅识别固定的三个内置函数,任意其它命令将被识别为普通命名空间
占位符整体样式:[@内置函数:][命名空间][.]<占位符>
template.xlsx模板如下:
+--------+--------+--------------+---------------+------------------+
| 姓名 | 年龄 | 性别 | 头像 | 简历原件 |
+--------+--------+--------------+---------------+------------------+
|${name} | ${age} | ${@list:sex} | ${@media:pic} | ${@link:jumpUrl} |
+--------+--------+--------------+---------------+------------------+
// 组装测试数据
List<Map<String, Object>> data = new ArrayList<>();
Map<String, Object> row1 = new HashMap<>();
row1.put("name", "张三");
row1.put("age", 26);
row1.put("sex", "男");
row1.put("pic", Paths.get("./images/head.png"));
row1.put("jumpUrl", " https://jianli.com/zhangsan");
data.add(row1);
new Workbook("内置函数测试")
// 模板工作表
.addSheet(new TemplateSheet(Paths.get("./template.xlsx"))
// 替换模板中占位符
.setData(data)
// 替换模板中"@list:sex"值为性别序列
.setData("@list:sex", Arrays.asList("未知", "男", "女")))
.writeTo(Paths.get("/tmp/"));
参考文档:
| 限定符和类型 | 类和说明 |
|---|---|
static class |
TemplateSheet.CommitRowSetIterator
需要手动调用
TemplateSheet.CommitRowSetIterator.commit()方法才会移动游标 |
static class |
TemplateSheet.Node
单元格预处理节点
|
static class |
TemplateSheet.PreCell
预处理单元格
|
static class |
TemplateSheet.ValueWrapper
填充对象
|
| 限定符和类型 | 字段和说明 |
|---|---|
protected int |
afr
占位符位置标记 pf: 当前占位符的行号 pi: 当前占位符在preNodes的下标
afr:auto-filter row
|
protected Map<Long,Comment> |
comments0
缓存源文件批注
Key: 坐标 Value:批注
|
protected int[] |
fontIndices |
static String |
HYPERLINK_KEY
内置单元格类型-超链接样式
|
static String |
LIST_KEY
内置单元格类型-序列
|
static String |
MEDIA_KEY
内置单元格类型-图片
|
protected List<Dimension> |
mergeCells
合并单元格(输出时需特殊处理)
|
protected Map<Long,Dimension> |
mergeCells0
缓存源文件合并单元格
Key: 首坐标 Value:单元格范围
|
protected Map<String,TemplateSheet.ValueWrapper> |
namespaceMapper
填充数据缓存
|
protected int |
originalSheetIndex
源工作表索引
|
protected String |
originalSheetName
源工作表名
|
protected int |
pf
占位符位置标记 pf: 当前占位符的行号 pi: 当前占位符在preNodes的下标
afr:auto-filter row
|
protected int |
pi
占位符位置标记 pf: 当前占位符的行号 pi: 当前占位符在preNodes的下标
afr:auto-filter row
|
protected List<Drawings.Picture> |
pictures
图片
|
protected TemplateSheet.PreCell[][] |
preCells
包含占位符的单元格预处理后的结果
|
protected String |
prefix
占位符前缀和后缀
|
protected ExcelReader |
reader
读取模板用
|
protected TemplateSheet.CommitRowSetIterator |
rowIterator
行数据迭代器
|
protected Map<Integer,Integer> |
styleMap
样式映射,缓存源样式索引映射到目标样式索引
|
protected String |
suffix
占位符前缀和后缀
|
protected Path |
templatePath
模板路径
|
protected InputStream |
templateStream
模板流
|
protected boolean |
useOriginalSheetName
以Excel格式输出
|
protected boolean |
writeAsExcel
以Excel格式输出
|
autoSize, cellValueAndStyle, columns, comments, copyCount, copySheet, extProp, extPropMark, headerReady, headerRowHeight, headStyle, headStyleIndex, hidden, id, LOGGER, name, nonHeader, progressConsumer, relManager, rowBlock, rowHeight, rows, sheetWriter, shouldClose, showGridLines, startCoordinate, watermark, width, workbook, zebraFill, zebraFillStyle| 构造器和说明 |
|---|
TemplateSheet(InputStream templateStream)
实例化模板工作表,默认以第一个工作表做为模板
|
TemplateSheet(InputStream templateStream,
int originalSheetIndex)
实例化模板工作表并指定模板工作表索引,如果指定索引超过模板Excel中包含的工作表数量则抛异常
|
TemplateSheet(InputStream templateStream,
String originalSheetName)
实例化模板工作表并指定模板工作表名,如果指定源工作表不存在则抛异常
|
TemplateSheet(Path templatePath)
实例化模板工作表,默认以第一个工作表做为模板
|
TemplateSheet(Path templatePath,
int originalSheetIndex)
实例化模板工作表并指定模板工作表索引,如果指定索引超过模板Excel中包含的工作表数量则抛异常
|
TemplateSheet(Path templatePath,
String originalSheetName)
实例化模板工作表并指定模板工作表名,如果指定源工作表不存在则抛异常
|
TemplateSheet(String name,
InputStream templateStream)
实例化模板工作表,默认以第一个工作表做为模板
|
TemplateSheet(String name,
InputStream templateStream,
int originalSheetIndex)
实例化模板工作表并指定模板工作表索引,如果指定索引超过模板Excel中包含的工作表数量则抛异常
|
TemplateSheet(String name,
InputStream templateStream,
String originalSheetName)
实例化模板工作表并指定模板工作表名,如果指定源工作表不存在则抛异常
|
TemplateSheet(String name,
Path templatePath)
实例化模板工作表,默认以第一个工作表做为模板
|
TemplateSheet(String name,
Path templatePath,
int originalSheetIndex)
实例化模板工作表并指定模板工作表索引,如果指定索引超过模板Excel中包含的工作表数量则抛异常
|
TemplateSheet(String name,
Path templatePath,
String originalSheetName)
实例化模板工作表并指定模板工作表名,如果指定源工作表不存在则抛异常
|
| 限定符和类型 | 方法和说明 |
|---|---|
protected TemplateSheet.PreCell |
afterParseCell(TemplateSheet.PreCell pn)
解析完占位符后调用此方法,可以处理内置函数
|
void |
afterSheetDataWriter(int total)
当输出协议写完sheetData时调用
|
void |
close()
回闭连接,回收资源,删除临时文件等
|
protected static int |
copyStyle(Styles srcStyles,
Styles distStyle,
int copyXf)
复制样式
|
protected void |
datetimeCell(Styles styles,
Cell cell)
日期类型添加默认format
|
static long |
dimensionKey(int row,
int col)
首行首列进行计算后转为缓存的Key
|
protected void |
fillValue(Row row,
Cell cell,
TemplateSheet.PreCell pn,
Column emptyColumn) |
Column[] |
getAndSortHeaderColumns()
获取表头,Worksheet工作表输出协议调用此方法来获取表头信息
此方法先调用内部
Sheet.getHeaderColumns()获取基础信息,然后对其进行排序,列反转,
合并等深加工处理 |
protected static Object |
getFirstObject(List<?> list)
获取数组中第一个非
null值 |
protected Object |
getNodeValue(TemplateSheet.Node node)
获取占位符的实际值
|
protected Object |
getObjectValue(AccessibleObject ao,
Object o,
String key)
反射获取对象的值
|
protected int |
hyperlinkStyle(Styles styles,
int xf) |
protected int |
init()
读取模板头信息并复杂到当前工作表
|
RowBlock |
nextBlock()
获取下一段
RowBlock行块数据,工作表输出协议通过此方法循环获取行数据并落盘,
行块被设计为一个滑行窗口,下游输出协议只能获取一个窗口的数据默认包含32行。 |
protected Map<String,AccessibleObject> |
parseClass(Class<?> clazz)
解析对象的方法和字段,方便后续取数
|
static int |
prefixMatch(String[] array,
String v)
前缀匹配,数组中的词为前缀词
|
protected TemplateSheet.CommitRowSetIterator |
prepare(Sheet originalSheet)
预处理样式和占位符
|
protected TemplateSheet.PreCell |
prepareCellValue(int row,
int col,
String v,
int prefixLen,
int suffixLen)
单元格字符串预处理,检测是否包含占位符以及占位符预处理
|
protected int |
prepareCommonData(FullSheet originalSheet)
解析公共数据
|
protected void |
resetBlockData()
你需要覆写本方法获取行数据并将Java对象或自定义行数据通过
ICellValueAndStyle.reset(org.ttzero.excel.entity.Row, org.ttzero.excel.reader.Cell, java.lang.Object, org.ttzero.excel.entity.Column)转换器将数据转换为输出协议允许的结构,
ICellValueAndStyle#reset方法除转换数据外还添单元格样式 |
protected void |
rowCommit(Row row0,
Row row) |
protected void |
rowEnd(Row row0,
Row row) |
TemplateSheet |
setData(BiFunction<Integer,Object,List<?>> dataSupplier)
绑定一个
Supplier到默认命名空间,适用于未知长度或数量最大的数组 |
TemplateSheet |
setData(Object o)
绑定数据到默认命名空间,默认命名空间为
null |
TemplateSheet |
setData(String namespace,
BiFunction<Integer,Object,List<?>> dataSupplier)
绑定一个
Supplier到指定命名空间,适用于未知长度或数量最大的数组 |
TemplateSheet |
setData(String namespace,
Object o)
绑定数据到指定命名空间上
|
TemplateSheet |
setPrefix(String prefix)
设置占位符前缀,默认前缀为
$ģ |
TemplateSheet |
setSuffix(String suffix)
设置占位符后缀,默认后缀为
ĥ |
static Picture |
toWritablePicture(Drawings.Picture pic)
将图片转为导出格式
|
TemplateSheet |
useOriginalSheetName()
使用源工作表名称作为当前工作表名
|
addRel, afterSheetAccess, autoSize, buildHeadStyle, calculateRealColIndex, cancelZebraLine, checkColumnLimit, clone, createComments, defaultHeadStyle, defaultHeadStyleIndex, defaultZebraLine, findRel, fixedSize, fixedSize, forWrite, getAutoSize, getCellValueAndStyle, getColumns, getComments, getCopySheetName, getDefaultWidth, getExtPropAsMap, getExtPropValue, getFileName, getForceExport, getHeaderColumns, getHeaderRowHeight, getHeadStyle, getHeadStyleIndex, getId, getName, getNonHeader, getProgressConsumer, getRelManager, getRowBlockSize, getRowHeight, getRowLimit, getSheetWriter, getStartColNum, getStartRowNum, getWatermark, getWorkbook, getZebraFill, getZebraFillStyle, hasHeaderColumns, hidden, hideGridLines, ignoreHeader, insert, int2Col, isAutoSize, isHidden, isScrollToVisibleArea, isShowGridLines, markExtProp, mergeHeaderCellsIfEquals, onProgress, paging, putAllExtProp, putExtProp, putExtPropIfAbsent, resetCommonProperties, reverseHeadColumn, search, setCellValueAndStyle, setColumns, setColumns, setHeaderRowHeight, setHeadStyle, setHeadStyleIndex, setId, setName, setRowHeight, setSheetWriter, setStartCoordinate, setStartCoordinate, setStartCoordinate, setStartCoordinate, setStartCoordinate, setStartCoordinate, setWatermark, setWorkbook, setZebraLine, showGridLines, size, sortColumns, toCoordinate, writeToprotected String prefix
protected String suffix
protected Path templatePath
protected InputStream templateStream
protected ExcelReader reader
protected int originalSheetIndex
protected String originalSheetName
protected TemplateSheet.CommitRowSetIterator rowIterator
protected List<Drawings.Picture> pictures
protected boolean writeAsExcel
protected boolean useOriginalSheetName
protected TemplateSheet.PreCell[][] preCells
protected int pf
protected int pi
protected int afr
protected Map<String,TemplateSheet.ValueWrapper> namespaceMapper
protected int[] fontIndices
public TemplateSheet(Path templatePath)
templatePath - 模板路径public TemplateSheet(String name, Path templatePath)
name - 指定工作表名称templatePath - 模板路径public TemplateSheet(Path templatePath, int originalSheetIndex)
templatePath - 模板路径originalSheetIndex - 指定源工作表索引(从0开始)public TemplateSheet(String name, Path templatePath, int originalSheetIndex)
name - 指定工作表名称templatePath - 模板路径originalSheetIndex - 指定源工作表索引(从0开始)public TemplateSheet(Path templatePath, String originalSheetName)
templatePath - 模板路径originalSheetName - 指定源工作表名public TemplateSheet(String name, Path templatePath, String originalSheetName)
name - 指定工作表名称templatePath - 模板路径originalSheetName - 指定源工作表名public TemplateSheet(InputStream templateStream)
templateStream - 模板输入流public TemplateSheet(String name, InputStream templateStream)
name - 设置工作表名templateStream - 模板输入流public TemplateSheet(InputStream templateStream, int originalSheetIndex)
templateStream - 模板输入流originalSheetIndex - 指定源工作表索引public TemplateSheet(InputStream templateStream, String originalSheetName)
templateStream - 模板输入流originalSheetName - 指定源工作表名public TemplateSheet(String name, InputStream templateStream, int originalSheetIndex)
name - 设置工作表名templateStream - 模板输入流originalSheetIndex - 指定源工作表索引public TemplateSheet(String name, InputStream templateStream, String originalSheetName)
name - 设置工作表名templateStream - 模板输入流originalSheetName - 指定源工作表名public TemplateSheet setPrefix(String prefix)
$ģprefix - 占位符前缀public TemplateSheet setSuffix(String suffix)
ĥsuffix - 占位符后缀public TemplateSheet useOriginalSheetName()
public TemplateSheet setData(Object o)
nullo - 任意对象,可以为Java Bean,Map,或者数组public TemplateSheet setData(String namespace, Object o)
namespace - 命名空间o - 任意对象,可以为Java Bean,Map,或者数组public TemplateSheet setData(BiFunction<Integer,Object,List<?>> dataSupplier)
Supplier到默认命名空间,适用于未知长度或数量最大的数组dataSupplier - 数据产生者public TemplateSheet setData(String namespace, BiFunction<Integer,Object,List<?>> dataSupplier)
Supplier到指定命名空间,适用于未知长度或数量最大的数组namespace - 命名空间dataSupplier - 数据产生者public RowBlock nextBlock()
RowBlock行块数据,工作表输出协议通过此方法循环获取行数据并落盘,
行块被设计为一个滑行窗口,下游输出协议只能获取一个窗口的数据默认包含32行。public Column[] getAndSortHeaderColumns()
Sheet此方法先调用内部Sheet.getHeaderColumns()获取基础信息,然后对其进行排序,列反转,
合并等深加工处理
getAndSortHeaderColumns 在类中 Sheetprotected int init()
throws IOException
IOException - 读取模板异常protected void resetBlockData()
SheetICellValueAndStyle.reset(org.ttzero.excel.entity.Row, org.ttzero.excel.reader.Cell, java.lang.Object, org.ttzero.excel.entity.Column)转换器将数据转换为输出协议允许的结构,
ICellValueAndStyle#reset方法除转换数据外还添单元格样式resetBlockData 在类中 Sheetprotected Object getNodeValue(TemplateSheet.Node node)
node - 占位符节点信息protected Object getObjectValue(AccessibleObject ao, Object o, String key)
ao - Method 或 Fieldo - 对象key - 占位符protected void fillValue(Row row, Cell cell, TemplateSheet.PreCell pn, Column emptyColumn)
protected void datetimeCell(Styles styles, Cell cell)
styles - Stylescell - 单元格public void afterSheetDataWriter(int total)
SheetafterSheetDataWriter 在类中 Sheettotal - 已写数据行public void close()
throws IOException
Sheetclose 在类中 SheetIOException - if I/O error occurpublic static Picture toWritablePicture(Drawings.Picture pic)
pic - 图片protected TemplateSheet.CommitRowSetIterator prepare(Sheet originalSheet)
originalSheet - 模板工作表protected static int copyStyle(Styles srcStyles, Styles distStyle, int copyXf)
srcStyles - 源样式表distStyle - 目标样式表copyXf - 样式索引protected int prepareCommonData(FullSheet originalSheet)
originalSheet - 源模板工作表protected TemplateSheet.PreCell prepareCellValue(int row, int col, String v, int prefixLen, int suffixLen)
row - 单元格行坐标(one base)col - 单元格列坐标(zero base)v - 单元格原始值prefixLen - 占位符前缀长度suffixLen - 占位符后缀长度protected TemplateSheet.PreCell afterParseCell(TemplateSheet.PreCell pn)
pn - 原始占位符预处理protected int hyperlinkStyle(Styles styles, int xf)
protected Map<String,AccessibleObject> parseClass(Class<?> clazz)
clazz - 待解析的对象public static long dimensionKey(int row,
int col)
row - 行号(zero base)col - 列号(zero base)protected static Object getFirstObject(List<?> list)
null值list - 数组null值Copyright © 2025. All rights reserved.