简介:在IT领域,自动生成排版规范的Word文档广泛应用于数据报告、自动化办公和批量文本处理。通过Java语言结合Apache POI等工具库,开发者可实现对.docx文件的读写与样式控制,支持字体、段落、表格、图片、页眉页脚等元素的精确排版,并能通过模板机制动态填充数据,完成高效自动化导出。该技术已在金融报表、合同生成、邮件合并等场景中发挥重要作用。本文介绍完整的Word文档生成流程,涵盖核心API使用、页面元素操作、性能优化及异常处理,帮助开发者构建稳定高效的文档自动化系统。
1. Apache POI框架简介与核心组件(HWPF/XWPF)
Apache POI概述与核心模块
Apache POI是Java平台处理Microsoft Office文档的权威开源库,支持Word、Excel、PowerPoint等格式的读写操作。其核心模块中, XWPF 用于处理基于OpenXML标准的 .docx 文件,而 HWPF 则负责旧版二进制 .doc 格式。
// Maven依赖配置示例
AI写代码
java
运行
XWPF采用DOM模型解析文档,通过 XWPFDocument 、 XWPFParagraph 、 XWPFRun 等对象构建层次化结构,便于编程控制。相较之下,HWPF功能有限且维护较少,推荐新项目统一使用XWPF。本章为后续自动化文档生成奠定理论与环境基础。
2. 使用XWPF创建与操作.docx文档基础流程
在Java应用开发中,自动生成结构化、排版规范的Word文档已成为报表生成、合同定制、公文自动化等场景中的核心需求。Apache POI的XWPF模块作为处理 .docx 格式文件的核心工具包,提供了对OpenXML标准的完整封装,使开发者可以通过面向对象的方式构建复杂的Word文档。本章将系统性地阐述如何基于XWPF完成从零开始创建文档的基础流程,涵盖文档初始化、内容组织逻辑以及模板驱动的动态修改三大关键环节。通过深入剖析 XWPFDocument 、 XWPFParagraph 和 XWPFRun 之间的层级关系,并结合代码示例与流程图解,帮助读者建立清晰的操作模型。
2.1 文档对象的初始化与基本结构构建
2.1.1 创建空白XWPFDocument实例
在使用Apache POI进行Word文档操作之前,必须首先获得一个可操作的文档容器——即 XWPFDocument 类的实例。该类是整个XWPF模块的根对象,代表一个完整的 .docx 文档,其内部遵循Office Open XML(OOXML)标准组织内容,包括正文、样式表、图像资源、页眉页脚等多个部分。
创建一个全新的空白文档非常简单,只需调用无参构造函数即可:
import org.apache.poi.xwpf.usermodel.XWPFDocument;
public class DocxCreator {
public static void main(String[] args) {
// 创建一个新的空白.docx文档
XWPFDocument document = new XWPFDocument();
// 后续操作在此基础上展开
}
}
AI写代码
java
运行
代码逻辑逐行解读:
第1行:导入 XWPFDocument 类,这是所有文档操作的起点。
第5行:通过 new XWPFDocument() 初始化一个空文档对象。此时内存中已存在符合 .docx 结构的ZIP归档骨架,包含必要的XML部件如 [Content_Types].xml 、 word/document.xml 等,但尚未添加任何用户可见内容。
此对象不仅支持写入文本、表格、图片等内容,还维护着文档级别的元数据(如作者、标题)、主题设置及底层OPC(Open Packaging Conventions)包结构。值得注意的是, XWPFDocument 实现了 Closeable 接口,因此在使用完毕后必须显式关闭以释放流资源,避免内存泄漏。
属性 说明
document.xml 存储主文档内容(段落、表格等)
styles.xml 定义文档使用的样式集合
settings.xml 包含页面布局、兼容性选项等设置
_rels/.rels 描述各部件之间的引用关系
下面是一个简单的mermaid流程图,展示文档初始化后的内部结构组成:
graph TD
A[XWPFDocument] --> B[[OPC Package]]
B --> C["[Content_Types].xml"]
B --> D[word/_rels/document.xml.rels]
B --> E[word/document.xml]
B --> F[word/styles.xml]
B --> G[word/theme/theme1.xml]
E --> H[Body Content: Paragraphs, Tables]
AI写代码
mermaid
该图表明, XWPFDocument 本质上是对一个ZIP压缩包的抽象,其中每个XML文件对应不同的功能模块。当执行 new XWPFDocument() 时,这些基础组件会被自动创建并加载到内存中,为后续的内容插入提供支撑。
2.1.2 添加段落与文本内容的基本方法
一旦获得 XWPFDocument 实例,下一步就是向其中添加可读内容。最基础的内容单元是段落( XWPFParagraph ),而段落由一个或多个文本运行( XWPFRun )构成。这种设计源于OpenXML中“段落-运行”的嵌套结构,允许在同一段内实现字体、颜色等样式的局部变化。
以下代码演示如何添加一个包含纯文本的段落:
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
public class AddParagraphExample {
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
// 创建新段落
XWPFParagraph paragraph = document.createParagraph();
// 获取段落中的文本运行对象
XWPFRun run = paragraph.createRun();
run.setText("这是一个使用Apache POI生成的示例段落。");
// 保存文档
try (FileOutputStream out = new FileOutputStream("output/basic.docx")) {
document.write(out);
}
document.close();
}
}
AI写代码
java
运行
参数说明与逻辑分析:
document.createParagraph() :向文档末尾追加一个新的段落对象,并返回对该段落的引用。每调用一次即新增一段。
paragraph.createRun() :在指定段落中创建一个文本运行(Run)。一个段落可以有多个Run,用于实现不同样式的拼接。
run.setText(String text) :设置当前Run中的文本内容。注意此方法会覆盖原有文本。
document.write(OutputStream) :将整个文档结构序列化为 .docx 文件并输出至指定流。
上述代码生成的文档将在Word中显示一行中文文本。若需换行,不能直接使用 \n ,而应调用 run.addBreak() 或创建新的段落来实现自然分段。
此外,可通过链式调用来简化代码:
document.createParagraph()
.createRun()
.setText("链式调用方式添加文本");
AI写代码
java
运行
这种方式提升了代码可读性,尤其适用于快速原型开发。
2.1.3 文档保存与输出流管理
文档编辑完成后,必须将其持久化为物理文件或字节数组,以便传输或展示。XWPF提供了两种主要输出方式:写入文件流或写入字节流。
写入本地文件
FileOutputStream fileOut = new FileOutputStream("report.docx");
document.write(fileOut);
fileOut.close(); // 推荐使用try-with-resources
AI写代码
java
运行
写入字节数组(适用于Web响应)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.write(baos);
byte[] docBytes = baos.toByteArray();
baos.close();
AI写代码
java
运行
推荐始终使用 try-with-resources 语句确保资源正确释放:
try (FileOutputStream out = new FileOutputStream("output.docx")) {
document.write(out);
} catch (IOException e) {
e.printStackTrace();
} finally {
document.close();
}
AI写代码
java
运行
输出方式 适用场景 性能特点
FileOutputStream 本地存储、批量导出 高效稳定
ByteArrayOutputStream Web服务返回、内存缓存 占用堆空间,适合小文档
ServletOutputStream Spring MVC控制器直接下载 需配合HTTP头设置
错误处理方面,常见异常包括:
- IOException :磁盘满、权限不足、路径无效
- NullPointerException :未初始化document或paragraph
- InvalidFormatException :模板损坏或不符合OOXML规范
务必在生产环境中加入日志记录与异常兜底机制,保障系统的健壮性。
2.2 段落与文本单元的组织逻辑
2.2.1 XWPFParagraph与XWPFRun的关系解析
理解 XWPFParagraph 与 XWPFRun 之间的协作机制,是掌握精细排版控制的关键。二者的关系类似于HTML中的 标签与 标签:段落定义整体段落级格式(如对齐、缩进),而Run则负责控制其中某一部分文字的具体显示效果(如字体、颜色)。
一个典型的段落结构如下所示:
[Paragraph]
└── [Run #1] "这是一段"
└── [Run #2] "加粗的文字"
└── [Run #3] "和普通文字混合"
AI写代码
text
对应的Java代码实现:
XWPFParagraph p = document.createParagraph();
XWPFRun r1 = p.createRun();
r1.setText("这是一段");
XWPFRun r2 = p.createRun();
r2.setBold(true);
r2.setColor("FF0000");
r2.setText("加粗的文字");
XWPFRun r3 = p.createRun();
r3.setText("和普通文字混合");
AI写代码
java
运行
逐行分析:
- 第2行:创建段落,作为所有Run的容器。
- 第3–4行:第一个Run插入普通文本。
- 第6–8行:第二个Run设置加粗与红色字体(RGB值 FF0000 ),再插入特定文本。
- 第10–11行:第三个Run恢复默认样式继续输入。
由此可知, 同一段落内的多个Run共享段落级属性 (如对齐方式),但各自拥有独立的字符级样式。这种分离设计使得复杂排版成为可能,例如法律条文中“第X条”加粗、“内容”正常、“关键词”高亮等。
下图用mermaid表示其结构关系:
classDiagram
class XWPFDocument {
+List~XWPFParagraph~ getParagraphs()
+XWPFParagraph createParagraph()
}
class XWPFParagraph {
+List~XWPFRun~ getRuns()
+XWPFRun createRun()
+setAlignment(ParagraphAlignment align)
}
class XWPFRun {
+void setText(String text)
+void setBold(boolean bold)
+void setColor(String hexColor)
+void setFontFamily(String font)
}
XWPFDocument "1" *-- "0..*" XWPFParagraph : contains
XWPFParagraph "1" *-- "1..*" XWPFRun : contains
AI写代码
mermaid
该UML类图清晰展示了三者间的聚合关系:文档包含多个段落,每个段落又包含至少一个Run。
2.2.2 多段落顺序插入与内容追加策略
在实际应用中,往往需要按顺序插入多个段落,形成结构化的文档内容。XWPF默认采用“追加模式”,即每次调用 createParagraph() 都会在文档末尾添加新段。
考虑如下场景:生成一份会议纪要,依次包含标题、时间、地点、议题列表。
String[] topics = {"项目进度汇报", "预算调整讨论", "人员变动通报"};
// 标题段落
XWPFParagraph title = document.createParagraph();
title.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleRun = title.createRun();
titleRun.setBold(true);
titleRun.setFontSize(16);
titleRun.setText("会议纪要");
// 时间信息
addSimpleParagraph(document, "会议时间:2025年4月5日");
// 地点信息
addSimpleParagraph(document, "会议地点:第三会议室");
// 议题列表
for (String topic : topics) {
XWPFParagraph item = document.createParagraph();
item.setIndentLeft(400); // 左缩进约2字符宽度
XWPFRun run = item.createRun();
run.setText("• " + topic);
}
AI写代码
java
运行
辅助方法定义:
private static void addSimpleParagraph(XWPFDocument doc, String text) {
XWPFParagraph p = doc.createParagraph();
XWPFRun r = p.createRun();
r.setText(text);
}
AI写代码
java
运行
此策略的优点在于逻辑清晰、易于维护。但对于大型文档(如上百页报告),频繁调用 createParagraph() 可能导致内存占用过高。此时可结合第六章介绍的流式处理方案优化性能。
2.2.3 特殊字符与换行符的正确处理方式
在跨平台环境下处理文本时,特殊字符的渲染容易出现问题。例如,直接使用 \n 换行在Word中不会生效,因为 .docx 使用OpenXML的
正确的做法是使用 XWPFRun 提供的API:
XWPFRun run = paragraph.createRun();
run.setText("第一行");
run.addBreak(); // 软换行(Shift+Enter)
run.setText("第二行");
run.addBreak(BreakType.PAGE); // 分页符
run.setText("第三页开始");
AI写代码
java
运行
支持的换行类型包括:
BreakType
效果
对应Word操作
TEXT_WRAPPING
自动换行
Enter
PAGE
分页符
Ctrl+Enter
COLUMN
分栏符
—
LINE_SEPARATOR
行分隔符
—
此外,对于包含占位符(如 ${name} )或XML敏感字符( < , > , & )的文本,XWPF会自动转义以防止解析错误。但在某些高级替换场景中,建议预处理字符串:
String safeText = userInput.replaceAll("[<>\"&]", "");
AI写代码
java
运行
同时注意编码问题:确保输入文本使用UTF-8编码,特别是在处理中文、日文等多字节字符时,避免出现乱码。
2.3 基于模板的文档加载与修改
2.3.1 从现有.docx文件加载XWPFDocument
相较于从零构建,基于模板的文档生成更为高效且贴近实际业务需求。许多企业已有标准化的合同、报告模板,只需填充变量即可复用。
加载模板的方法如下:
FileInputStream templateIn = new FileInputStream("template/contract_template.docx");
XWPFDocument document = new XWPFDocument(templateIn);
// 修改内容...
templateIn.close();
AI写代码
java
运行
Apache POI会在加载时解析模板中的所有XML节点,重建内存中的对象模型。这意味着你可以像操作新建文档一样访问段落、表格、图片等元素。
重要提示:
- 模板文件必须是合法的 .docx (即ZIP压缩的OpenXML文档)
- 不支持旧版 .doc 格式(需使用HWPF)
- 若模板过大(>10MB),建议启用缓冲流提升读取效率:
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("large_template.docx")
);
XWPFDocument doc = new XWPFDocument(OPCPackage.open(bis));
AI写代码
java
运行
2.3.2 模板文档的结构分析与可编辑区域识别
为了实现精准的内容替换,必须先识别模板中的“可编辑区域”。常见做法是在模板中使用占位符标记,如:
客户名称:${client_name}
签订日期:${sign_date}
总金额:${amount} 元
AI写代码
text
程序的任务是遍历所有段落,查找并替换这些占位符。
以下是通用的段落扫描逻辑:
Map
data.put("${client_name}", "张三科技有限公司");
data.put("${sign_date}", "2025-04-05");
data.put("${amount}", "88,000");
for (XWPFParagraph p : document.getParagraphs()) {
List
if (runs == null || runs.isEmpty()) continue;
String text = p.getText();
for (Map.Entry
if (text.contains(entry.getKey())) {
for (XWPFRun run : runs) {
String runText = run.getText(0);
if (runText != null && runText.contains(entry.getKey())) {
run.setText(runText.replace(entry.getKey(), entry.getValue()), 0);
}
}
}
}
}
AI写代码
java
运行
关键点说明:
- getParagraphs() 返回文档中所有段落的列表,按顺序排列。
- getRuns() 获取段落内所有文本运行,某些情况下占位符可能被拆分在多个Run中。
- 使用 getText(0) 获取Run的原始文本(索引0表示唯一文本节点)。
- 替换操作需保留Run的样式属性,仅更改文本内容。
对于表格中的单元格内容,也需类似遍历:
for (XWPFTable table : document.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph p : cell.getParagraphs()) {
// 同上替换逻辑
}
}
}
}
AI写代码
java
运行
2.3.3 动态内容替换的初步实践
综合以上技术,实现一个完整的模板填充示例:
public class TemplateFiller {
public static void fillContractTemplate() throws Exception {
try (FileInputStream in = new FileInputStream("template/contract.docx")) {
XWPFDocument doc = new XWPFDocument(in);
Map
"${company}", "星辰软件有限公司",
"${project}", "智能客服系统开发",
"${price}", "¥1,200,000.00",
"${date}", LocalDate.now().toString()
);
// 遍历段落替换
replaceInParagraphs(doc.getParagraphs(), placeholders);
// 遍历表格替换
for (XWPFTable tbl : doc.getTables()) {
replaceInTable(tbl, placeholders);
}
try (FileOutputStream out = new FileOutputStream("output/filled_contract.docx")) {
doc.write(out);
}
doc.close();
}
}
private static void replaceInParagraphs(List
for (XWPFParagraph p : paragraphs) {
String text = p.getText();
if (text == null) continue;
boolean found = false;
for (String key : map.keySet()) {
if (text.contains(key)) {
found = true;
break;
}
}
if (found) {
for (XWPFRun run : p.getRuns()) {
String rText = run.getText(0);
if (rText != null) {
for (Map.Entry
if (rText.contains(e.getKey())) {
rText = rText.replace(e.getKey(), e.getValue());
run.setText(rText, 0);
}
}
}
}
}
}
}
private static void replaceInTable(XWPFTable table, Map
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
replaceInParagraphs(cell.getParagraphs(), map);
}
}
}
}
AI写代码
java
运行
该程序能够准确识别并替换分布在段落和表格中的占位符,生成个性化的合同文档。为进一步提升灵活性,可在后续章节引入正则表达式匹配、条件判断、循环列表插入等高级特性。
3. 字体、字号、颜色及段落样式的编程控制(XWPFRun与XWPFParagraph)
在自动化生成Word文档的过程中,仅仅实现内容的填充是远远不够的。为了满足企业级文档输出对排版美观性、专业性和一致性的高要求,必须对文本和段落的样式进行精细化编程控制。Apache POI 的 XWPF 模块通过 XWPFRun 和 XWPFParagraph 两个核心类分别管理 字符级格式 与 段落级格式 ,其设计遵循了 OpenXML 标准中关于文档结构的分层模型。深入理解这两个对象的属性设置机制、继承规则以及它们之间的协作方式,是实现高质量文档渲染的关键。
本章将从底层出发,系统剖析如何通过 Java 编程动态配置字体样式、颜色效果、段落对齐、缩进间距等视觉元素,并进一步探讨样式复用策略与自定义样式体系的构建方法。通过对 API 的深度调用示例、参数逻辑分析以及可视化流程图展示,帮助开发者建立起可维护、可扩展的文档样式控制架构。
3.1 文本样式控制:XWPFRun属性设置
XWPFRun 是 Apache POI 中表示“运行”(Run)这一概念的核心类,对应于 Word 文档中的一个连续文本片段,具有统一的字符格式。例如,在同一段落中,“这是 加粗 的文字”,其中“加粗”部分就是一个独立的 Run 对象,拥有不同于前后文本的字体属性。因此,要实现细粒度的文本格式化,就必须熟练掌握 XWPFRun 的各项属性设置方法。
3.1.1 字体名称、大小、加粗、斜体与下划线配置
在 XWPF 中,每个 XWPFRun 实例都可以单独设置字体族(Font Family)、字号(Size)、是否加粗(Bold)、斜体(Italic)、下划线(Underline)等基础属性。这些设置直接影响文本的呈现效果,适用于标题强调、关键词突出等场景。
以下是一个完整的代码示例,演示如何创建带有多种字体样式的段落:
import org.apache.poi.xwpf.usermodel.*;
public class FontExample {
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
// 创建段落
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
// 设置正常文本
run.setText("这是一段普通文本,");
run.setFontFamily("宋体");
run.setFontSize(12);
// 新建一个Run用于加粗斜体
run = paragraph.createRun();
run.setText("这是加粗斜体带下划线的文本");
run.setFontFamily("微软雅黑");
run.setFontSize(14);
run.setBold(true);
run.setItalic(true);
run.setUnderline(UnderlinePatterns.SINGLE);
// 保存文档
try (FileOutputStream out = new FileOutputStream("font_example.docx")) {
document.write(out);
}
document.close();
}
}
AI写代码
java
运行
代码逻辑逐行解读与参数说明:
行号
代码
解读
7
XWPFDocument document = new XWPFDocument();
初始化一个空的 .docx 文档容器,作为所有内容的父级结构。
9
XWPFParagraph paragraph = document.createParagraph();
向文档添加一个新的段落对象,后续文本将插入到该段落中。
10
XWPFRun run = paragraph.createRun();
在当前段落中创建第一个 Run,用于承载连续格式的文本。
12-14
setText , setFontFamily , setFontSize
分别设置文本内容、字体名称和字号(单位为磅)。注意:字体需系统支持,否则会回退到默认字体。
17-23
第二个 run = paragraph.createRun() 开始新 Run
关键点:每次调用 createRun() 都会开启一个新的格式区间,避免影响前文样式。
21
setUnderline(UnderlinePatterns.SINGLE)
设置单线下划线;其他可选值包括 DOUBLE , DOTTED , THICK 等,详见枚举类。
⚠️ 注意事项 :
- 若在同一 run 上连续调用 setText() 多次,后一次会覆盖前一次内容。
- 不同 Run 必须分开创建才能实现混合样式。
- setFontFamily() 接受的是字体名字符串,建议使用常见中文字体如“宋体”、“黑体”、“微软雅黑”。
3.1.2 字体颜色与高亮效果的RGB值设定
除了基本字体属性外, XWPFRun 还支持通过 RGB 值精确控制字体颜色和背景高亮色。这对于制作彩色报告、错误提示或重点标注非常有用。
XWPFRun colorRun = paragraph.createRun();
colorRun.setText("这是红色字体并带有黄色高亮");
colorRun.setColor("FF0000"); // 设置字体颜色为红色(十六进制RGB)
colorRun.setHighlightColor(HighlightColor.YELLOW); // 设置背景高亮为黄色
AI写代码
java
运行
更进一步地,还可以使用低层级 CT 对象直接操作 OpenXML 属性,以支持更多高亮类型或透明度控制:
// 使用底层 XML Bean 设置自定义高亮颜色(非标准色)
CTUnderline ctUnderline = CTUnderline.Factory.newInstance();
ctUnderline.setVal(STUnderline.NONE);
colorRun.getCTR().getXmlObject().set(CTUnderline.type, ctUnderline);
// 设置字体颜色(使用 CTRPr 类)
CTRPr rpr = colorRun.getCTR().getRPR();
if (rpr == null) rpr = colorRun.getCTR().addNewRPR();
CTColor color = CTColor.Factory.newInstance();
color.setVal("0000FF"); // 蓝色
rpr.setColor(color);
AI写代码
java
运行
参数说明表:
方法
参数类型
可选值/说明
setColor(String hexColor)
String
六位十六进制颜色码(如 "FF0000" 表示红色)
setHighlightColor(HighlightColor color)
enum
提供预设色: YELLOW , GREEN , CYAN , MAGENTA , BLUE , RED , DARK_BLUE , DARK_CYAN 等
getCTR()
CTR
返回底层 XML bean,可用于高级定制(需熟悉 OOXML 结构)
? 技巧提示 :当需要设置非标准高亮色(如浅灰、橙色)时,可通过修改 w:highlight XML 节点的 val 属性实现,但兼容性可能受限于某些旧版 Word 解析器。
3.1.3 上标、下标及特殊字体效果的应用
在科学文档、数学公式或化学表达式中,常需使用上标(superscript)或下标(subscript)。 XWPFRun 提供了 setTextPosition() 方法来实现这一功能。
XWPFRun subscriptRun = paragraph.createRun();
subscriptRun.setText("H₂O 是水的分子式");
// 将 '2' 设为下标(位置负值表示下沉)
XWPFRun subRun = paragraph.createRun();
subRun.setText("2");
subRun.setTextPosition(-10); // 下沉 10 磅,典型下标值
XWPFRun normalRun = paragraph.createRun();
normalRun.setText("O 是水的分子式");
AI写代码
java
运行
此外,还可结合 setCapitalization() 实现小型大写(Small Caps),或使用 setStrikeThrough() 添加删除线:
XWPFRun strikeRun = paragraph.createRun();
strikeRun.setText("此内容已被删除");
strikeRun.setStrikeThrough(true);
XWPFRun smallCapsRun = paragraph.createRun();
smallCapsRun.setText("小型大写文本");
smallCapsRun.setCapitalization(1); // 1 表示 small caps,0 表示正常
AI写代码
java
运行
特殊效果对照表:
效果
方法
参数说明
上标
setTextPosition(positiveValue)
推荐值:+6 到 +10(单位:半磅)
下标
setTextPosition(negativeValue)
推荐值:-6 到 -10
删除线
setStrikeThrough(boolean)
true 启用删除线
小型大写
setCapitalization(int)
1=Small Caps, 0=Normal
阴影
setShadow(boolean)
支持,但渲染效果依赖客户端
? 实践建议 :
- 上/下标不宜频繁使用,应封装成工具方法提高可读性;
- setTextPosition() 数值单位为“半磅”(half-point),即 10 表示 5pt 位移;
- 并非所有 Word 客户端都能完美还原小型大写或阴影效果,建议测试目标环境。
classDiagram
class XWPFRun {
+setText(String)
+setFontFamily(String)
+setFontSize(int)
+setBold(boolean)
+setItalic(boolean)
+setUnderline(UnderlinePatterns)
+setColor(String)
+setHighlightColor(HighlightColor)
+setTextPosition(int)
+setStrikeThrough(boolean)
}
class UnderlinePatterns {
<
SINGLE
DOUBLE
DOTTED
THICK
}
class HighlightColor {
<
YELLOW
GREEN
CYAN
MAGENTA
BLUE
RED
}
XWPFRun --> UnderlinePatterns : uses
XWPFRun --> HighlightColor : uses
AI写代码
mermaid
上图展示了 XWPFRun 类与其相关枚举类型的关联关系,体现了 Apache POI 对 OpenXML 规范的映射设计。
3.2 段落格式化:XWPFParagraph高级设置
如果说 XWPFRun 控制的是“字”的外观,那么 XWPFParagraph 则决定了“行”的布局。它负责管理段落级别的格式信息,包括对齐方式、缩进、行距、段前段后间距等,直接影响文档的整体排版结构与阅读体验。
3.2.1 对齐方式(左对齐、居中、右对齐、两端对齐)
段落对齐是文档中最常见的格式需求之一。XWPF 提供 setAlignment() 方法来设置段落对齐模式,接受 TableRowAlign 枚举类型。
XWPFParagraph alignPara = document.createParagraph();
alignPara.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = alignPara.createRun();
run.setText("这是一个居中的段落");
AI写代码
java
运行
支持的对齐方式如下:
枚举值
效果
应用场景
LEFT
左对齐(默认)
正文段落
CENTER
居中对齐
标题、章节名
RIGHT
右对齐
页眉、日期、签名栏
BOTH
两端对齐
正式公文、出版物
✅ 最佳实践 :对于正式文档,正文推荐使用 BOTH (两端对齐),以获得更整齐的左右边缘。
3.2.2 缩进控制(首行缩进、左右边距)
通过 setIndentationLeft() 、 setIndentationRight() 和 setIndentationFirstLine() 可以精确控制段落的缩进量。数值单位为 Twips (缇),1 英寸 = 1440 Twips,1 厘米 ≈ 567 Twips。
XWPFParagraph indentPara = document.createParagraph();
indentPara.setIndentationLeft(567); // 左缩进 1cm
indentPara.setIndentationRight(283); // 右缩进 0.5cm
indentPara.setIndentationFirstLine(567); // 首行缩进 1cm
XWPFRun run = indentPara.createRun();
run.setText("这是一个设置了复杂缩进的段落。首行缩进1厘米,左右分别缩进1cm和0.5cm。");
AI写代码
java
运行
缩进单位换算参考表:
单位
换算关系
示例值
Twip
1/1440 英寸
567 ≈ 1cm
Point
1/72 英寸
72pt = 1in
Pixel
依赖 DPI
通常 96px = 1in
⚠️ 注意:Apache POI 不提供自动单位转换工具,开发者需自行计算 Twips 值。
3.2.3 行间距与段前段后间距的精确调整
良好的行间距能显著提升文档可读性。XWPF 支持通过 setSpacingAfter() , setSpacingBefore() 和 setSpacingLineRule() 设置段前、段后及行间距离。
XWPFParagraph spacingPara = document.createParagraph();
// 设置段前 12pt,段后 6pt
spacingPara.setSpacingBefore(240); // 12pt * 20 = 240 twips
spacingPara.setSpacingAfter(120); // 6pt * 20 = 120 twips
// 设置行间距为 1.5 倍(276 单位表示 1.5 行高)
spacingPara.setSpacingLine(276);
spacingPara.setSpacingLineRule(LineSpacingRule.AUTO);
XWPFRun run = spacingPara.createRun();
run.setText("这段文字具有较大的段前段后间距和1.5倍行距。");
AI写代码
java
运行
行间距规则说明:
LineSpacingRule
含义
适用场景
AUTO
自动行距(基于字号)
默认值
EXACT
精确值(单位 twips)
固定排版
AT_LEAST
最小行高
防止文字挤压
? 经验分享 :
- 段前/段后间距单位为 twips(×20 = pt);
- 行高若设为 EXACT ,建议设置为字号的 1.2~1.5 倍,避免截断;
- 使用 AT_LEAST 更安全,允许内容扩展而不溢出。
flowchart TD
A[开始设置段落格式] --> B{选择对齐方式}
B --> C[LEFT / CENTER / RIGHT / BOTH]
C --> D[设置缩进]
D --> E[左/右/首行缩进(twips)]
E --> F[配置间距]
F --> G[段前/段后/行距]
G --> H[保存至文档]
H --> I[结束]
AI写代码
mermaid
流程图展示了段落格式化的典型操作路径,强调了单位转换与顺序执行的重要性。
3.3 样式复用与自定义样式定义
在实际项目中,若每次都要手动设置字体、颜色、缩进等属性,不仅效率低下且难以保证一致性。为此,XWPF 提供了 XWPFStyles 机制,允许开发者定义和复用样式模板,极大提升了开发效率与维护性。
3.3.1 利用XWPFStyles应用预设样式(如Heading1)
Word 内置了许多标准样式(如 Heading 1 , Title , Subtitle ),可通过名称直接引用:
XWPFStyles styles = document.getStyles();
XWPFParagraph heading = document.createParagraph();
heading.setStyle("Heading1");
XWPFRun run = heading.createRun();
run.setText("这是一个一级标题");
AI写代码
java
运行
前提是模板文档中已存在该样式。也可通过 styles.addStyle() 注册新样式。
3.3.2 创建并注册自定义段落样式
若需创建全新样式(如“公司正文”、“法律条款”),可通过 CTStyle 手动定义:
CTStyle ctStyle = CTStyle.Factory.newInstance();
ctStyle.setStyleId("CustomBodyText");
STStyleType.Enum type = STStyleType.PARAGRAPH;
ctStyle.setType(type);
// 设置基于样式
CTString styleName = CTString.Factory.newInstance();
styleName.setVal("自定义正文");
ctStyle.setName(styleName);
// 设置段落属性
CTPPr ppr = CTPPr.Factory.newInstance();
ppr.setAlign(STJc.LEFT);
ppr.setInd(CTTrPtMeasure.Factory.newInstance());
ppr.getInd().setLeft(Long.valueOf(720)); // 0.5 inch
styles.getCTStyles().addStyle(ctStyle);
// 应用样式
XWPFParagraph customPara = document.createParagraph();
customPara.setStyle("CustomBodyText");
AI写代码
java
运行
3.3.3 样式继承机制与优先级规则
XWPF 遵循 CSS 式的样式继承机制:
- 段落样式 → Run 样式 → 直接属性设置
- 后者优先级高于前者
即:
run.setBold(true); // 最高优先级
// 覆盖了即使样式中定义为非粗体的情况
AI写代码
java
运行
层级
来源
优先级
1
直接属性设置(如 setBold() )
最高
2
Run/Paragraph 样式定义
中等
3
默认文档样式
最低
? 设计建议 :建立全局样式表 .dotx 模板,加载后复用,确保品牌一致性。
// 加载含样式的模板
try (FileInputStream fis = new FileInputStream("template.dotx")) {
XWPFDocument doc = new XWPFDocument(fis);
XWPFParagraph p = doc.createParagraph();
p.setStyle("CompanyNameStyle");
}
AI写代码
java
运行
综上所述, XWPFRun 与 XWPFParagraph 构成了 Apache POI 文档样式控制的两大支柱。通过对字体、颜色、段落格式的精细操控,结合样式复用机制,开发者能够构建出高度专业化、标准化的自动化文档输出系统。下一章将在此基础上引入表格结构,拓展复杂数据的组织能力。
4. 表格生成与格式化(XWPFTable应用)
在现代企业级文档自动化系统中,表格作为信息结构化展示的核心载体,广泛应用于报表、合同、技术文档等场景。Apache POI 的 XWPF 模块提供了对 .docx 格式中表格的全面支持,通过 XWPFTable 、 XWPFTableRow 和 XWPFTableCell 三个核心类构建出完整的表格对象模型。本章将深入探讨如何利用这些组件实现从零开始创建表格、动态管理行列结构、精确控制单元格内容样式,并进一步优化整体外观布局,以满足复杂业务场景下的排版需求。
4.1 表格创建与行列管理
4.1.1 初始化XWPFTable对象并指定列数
在 Apache POI 中, XWPFTable 是表示一个 Word 文档中表格的主类,它继承自 IBodyElement 接口,能够被添加到文档主体或节中。创建表格的第一步是通过 XWPFDocument 实例调用 createTable(rows, cols) 方法初始化一个具有固定行数和列数的表格对象。
XWPFDocument document = new XWPFDocument();
// 创建一个3行5列的空表格
XWPFTable table = document.createTable(3, 5);
AI写代码
java
运行
该方法底层会自动构建对应数量的 XWPFTableRow 和 XWPFTableCell 对象,并建立父子关系链。值得注意的是,虽然指定了初始行数,但实际开发中更常见的是先创建单行(表头),然后通过程序逻辑动态追加后续数据行。
参数
类型
描述
rows
int
初始行数,必须大于0
cols
int
列数,用于确定每行的单元格数量
⚠️ 注意 :若传入非法参数(如负值),将抛出 IllegalArgumentException 。此外, .docx 规范限制最大列数为63,超过此值可能导致兼容性问题。
使用 Mermaid 流程图展示表格初始化过程:
graph TD
A[XWPFDocument] --> B[调用 createTable(rows, cols)]
B --> C{验证参数合法性}
C -->|合法| D[创建XWPFTable实例]
D --> E[生成指定数量的XWPFTableRow]
E --> F[为每一行创建XWPFTableCell]
F --> G[建立DOM树结构]
G --> H[返回table引用]
C -->|非法| I[抛出IllegalArgumentException]
AI写代码
mermaid
上述流程体现了 POI 内部对 OpenXML 结构的封装机制——每一个 XWPFTable 都对应一个
4.1.2 动态添加行与单元格数据填充
尽管可以通过 createTable 预设行数,但在大多数应用场景中(如导出数据库查询结果),表格行数往往是未知的,需在运行时逐行添加。为此, XWPFTable 提供了 createRow() 方法来扩展表格:
// 获取已有表格并添加新行
XWPFTableRow newRow = table.createRow();
newRow.getCell(0).setText("姓名");
newRow.getCell(1).setText("年龄");
newRow.getCell(2).setText("部门");
AI写代码
java
运行
然而需要注意的是,第一次调用 createRow() 实际上并不会增加“可见”行,而是复用最初由 createTable 创建的第一行。因此,正确做法通常是先清除默认行再重新构建:
// 清除默认生成的首行(可选)
while (table.getNumberOfRows() > 0) {
table.removeRow(0);
}
// 手动添加表头行
XWPFTableRow headerRow = table.createRow();
for (int i = 0; i < 5; i++) {
headerRow.getCell(i).setText("列标题 " + (i + 1));
}
AI写代码
java
运行
对于数据填充,可通过嵌套循环遍历二维数据集:
List
Arrays.asList("张三", "28", "研发部", "高级工程师", "2020-01-01"),
Arrays.asList("李四", "32", "市场部", "项目经理", "2019-05-15")
);
for (List
XWPFTableRow row = table.createRow();
for (int i = 0; i < rowData.size(); i++) {
row.getCell(i).setText(rowData.get(i));
}
}
AI写代码
java
运行
代码逻辑逐行解析:
List
外层 for 循环迭代每一行数据。
table.createRow() 动态插入新行。
内层 for 循环将每个字段值写入对应单元格。
row.getCell(i).setText(...) 设置文本内容,注意索引不能越界。
此模式适用于中小型数据集。当处理大量数据时,应结合流式处理策略避免内存溢出(详见第六章)。
4.1.3 合并单元格(横向与纵向合并)实现技巧
单元格合并是提升表格可读性的关键功能,在财务报表、组织架构图等场景中尤为常见。Apache POI 支持通过设置 GridSpan (横向合并)和 VMerge (纵向合并)属性实现跨列与跨行合并。
横向合并示例(跨列)
// 创建一行用于标题合并
XWPFTableRow titleRow = table.createRow();
XWPFTableCell cell = titleRow.getCell(0);
// 设置该单元格跨越5列
CTTcPr tcPr = cell.getCTTc().getTcPr();
if (tcPr == null) {
tcPr = cell.getCTTc().addNewTcPr();
}
CTTblWidth gridSpan = tcPr.addNewGridSpan();
gridSpan.setW(BigInteger.valueOf(5));
cell.setText("员工基本信息汇总表");
AI写代码
java
运行
参数说明:
- CTTcPr : 单元格属性容器,包含宽度、边框、对齐等配置。
- GridSpan.w : 表示该单元格所占的网格列数,类型为 BigInteger 。
纵向合并示例(跨行)
纵向合并需分别设置起始单元格为 restart ,其余为 continue :
// 假设有3行,希望第一列的前两行垂直合并
XWPFTableRow row1 = table.getRow(1);
XWPFTableRow row2 = table.getRow(2);
XWPFTableCell cell1 = row1.getCell(0);
XWPFTableCell cell2 = row2.getCell(0);
// 起始单元格
CTVMerge vMerge1 = cell1.getCTTc().getTcPr().addNewVMerge();
vMerge1.setVal(STMerge.RESTART);
// 续接单元格
CTVMerge vMerge2 = cell2.getCTTc().getTcPr().addNewVMerge();
vMerge2.setVal(STMerge.CONTINUE);
AI写代码
java
运行
合并类型
属性名称
控制方式
适用场景
横向合并
GridSpan
设置 w 值
表头标题
纵向合并
VMerge
RESTART / CONTINUE
分组统计
⚠️ 重要提示 :手动合并后,被合并区域内的其他单元格仍存在,不可再赋值,否则会导致渲染错乱。建议在合并完成后统一设置内容。
4.2 单元格内容与样式控制
4.2.1 设置单元格内文本样式与段落布局
每个 XWPFTableCell 默认包含一个段落( XWPFParagraph ),而段落中又可包含多个 XWPFRun 对象,形成“单元格 → 段落 → 文本片段”的三层结构。这意味着可以在同一单元格内混合不同字体样式:
XWPFTableCell cell = table.getRow(0).getCell(0);
cell.getText().clear(); // 清空默认段落
XWPFParagraph p = cell.addParagraph();
XWPFRun boldRun = p.createRun();
boldRun.setBold(true);
boldRun.setText("重要提示:");
XWPFRun normalRun = p.createRun();
normalRun.setText(" 此项需人工审核。");
AI写代码
java
运行
该代码实现了富文本效果:前半部分加粗,后半部分正常显示。
表格:常用文本样式属性对照表
样式属性
方法名
示例值
是否支持
加粗
setBold(boolean)
true
✅
斜体
setItalic(boolean)
false
✅
下划线
setUnderline(UnderlinePatterns)
SINGLE
✅
字体大小
setFontSize(int)
12
✅
字体名称
setFontFamily(String)
“宋体”
✅
颜色
setColor(String)
“FF0000”
✅
通过组合 Run 可实现类似 HTML 的局部样式控制,极大增强了表达能力。
4.2.2 背景颜色与边框线型的独立配置
设置单元格背景色需要访问底层 CT 对象:
XWPFTableCell cell = row.getCell(0);
CTShd ctShd = cell.getCTTc().getTcPr().addNewShd();
ctShd.setFill("D3D3D3"); // 灰色背景
ctShd.setColor("auto");
ctShd.setVal(STShd.CLEAR);
AI写代码
java
运行
其中 fill="D3D3D3" 表示填充色 RGB 值,十六进制表示法。
边框则可通过 setBorderTop , setBorderBottom 等方法单独设置:
cell.setBorderTop(XWPFBorderType.SINGLE, 1, 0, "000000");
cell.setBorderLeft(XWPFBorderType.THICK, 3, 0, "000000");
AI写代码
java
运行
参数含义如下:
- 第一参数:边框类型(SINGLE、THICK、DASH_DOT 等)
- 第二参数:线宽(单位:8ths of a point)
- 第三参数:间距(可忽略)
- 第四参数:颜色(HEX 格式)
4.2.3 自动换行与垂直对齐方式调整
控制文本换行与对齐有助于提升表格整洁度:
CTTcPr tcPr = cell.getCTTc().getTcPr();
if (tcPr == null) tcPr = cell.getCTTc().addNewTcPr();
// 启用自动换行
CTTextWrap textWrap = tcPr.addNewTextWrap();
textWrap.setVal(STTextWrap.fromString("wrap"));
// 设置垂直居中
CTVerticalJc vAlign = tcPr.addNewVAlign();
vAlign.setVal(STVerticalJc.CENTER);
AI写代码
java
运行
Mermaid 图表示意:
classDiagram
XWPFTableCell --> XWPFParagraph : 包含
XWPFParagraph --> XWPFRun : 包含多个
XWPFTableCell --> CTTcPr : 持有样式
CTTcPr --> CTShd : 背景
CTTcPr --> CTTextWrap : 换行
CTTcPr --> CTVAlign : 垂直对齐
AI写代码
mermaid
4.3 表格整体外观优化
4.3.1 表格宽度分配策略(固定/百分比)
可通过 setWidth() 和 setWidthType() 控制表格总宽:
table.setWidth("80%"); // 百分比宽度
table.setWidthType(TableWidthDistribution.AUTO);
AI写代码
java
运行
或使用固定值(单位:twips,1 inch = 1440 twips):
table.setWidth("9000"); // 约6.25英寸
AI写代码
java
运行
列宽可通过 setCellMarginLeft 或直接修改 CTTcPr 中的 tcW 实现:
XWPFTableCell cell = row.getCell(0);
CTTcPr tcPr = cell.getCTTc().getTcPr();
CTTblWidth tcW = tcPr.addNewTcW();
tcW.setW(BigInteger.valueOf(2000)); // 设置宽度
tcW.setType(STTblWidth.DXA); // DXA 表示 twentieths of a point
AI写代码
java
运行
4.3.2 表头重复显示(适用于跨页表格)
启用表头跨页重复的关键是标记第一行为“标题行”:
XWPFTableRow header = table.getRow(0);
header.getCtRow().addNewTrPr().addNewTblHeader();
AI写代码
java
运行
这样当表格分页时,Word 将自动复制该行至新页面顶部。
4.3.3 边框隐藏与网格样式统一设置
批量设置无边框并恢复网格线:
table.setInsideHBorder(XWPFBorderType.NIL, 0, 0, null);
table.setInsideVBorder(XWPFBorderType.NIL, 0, 0, null);
table.setOutsideBorder(XWPFBorderType.SINGLE, 1, 0, "000000");
AI写代码
java
运行
或统一为细线网格:
for (XWPFTableRow r : table.getRows()) {
for (XWPFTableCell c : r.getTableCells()) {
c.setBorderTop(XWPFBorderType.SINGLE, 1, 0, "000000");
c.setBorderBottom(XWPFBorderType.SINGLE, 1, 0, "000000");
c.setBorderLeft(XWPFBorderType.SINGLE, 1, 0, "000000");
c.setBorderRight(XWPFBorderType.SINGLE, 1, 0, "000000");
}
}
AI写代码
java
运行
综上所述,通过对 XWPFTable 的精细化控制,不仅可以实现基础表格构建,还能完成高度定制化的专业排版需求,为自动化文档生成提供强大支撑。
5. 图片与图表插入技术(XWPFPictureData集成)
在自动化文档生成系统中,图像和图表的嵌入不仅是提升信息表达力的关键手段,更是构建专业级报告、技术白皮书或商业合同的重要组成部分。Apache POI 的 XWPF 模块通过 XWPFPictureData 类实现了对多种图像格式的支持,并提供了灵活的图文混排机制,使得开发者可以在 .docx 文档中精确控制图像的位置、尺寸以及与文本的交互方式。本章将深入剖析图像资源的加载流程、图片样式配置逻辑,以及如何结合外部绘图库实现动态图表的嵌入,从而为复杂文档场景提供完整的可视化支持。
5.1 图像资源的嵌入与定位
5.1.1 支持的图像格式(JPEG、PNG、EMF等)与限制
Apache POI 在 XWPF 中支持多种主流图像格式的嵌入,主要包括 JPEG、PNG、GIF、BMP 和 EMF(Enhanced Metafile),这些格式分别适用于不同的使用场景:
图像格式
MIME Type
特点
使用建议
JPEG
image/jpeg
高压缩比,适合照片类图像
报告中的实景图、产品照
PNG
image/png
无损压缩,支持透明通道
图标、流程图、带透明背景的图形
GIF
image/gif
支持动画,色彩有限
动态演示不推荐用于正式文档
BMP
image/bmp
未压缩,体积大
不推荐生产环境使用
EMF
image/emf
Windows 矢量图,缩放不失真
专业出版物、高分辨率打印
需要注意的是,虽然 POI 支持上述格式,但 .docx 文件本质上是基于 OpenXML 标准的 ZIP 包,所有图像都会被编码为二进制数据并存储于 word/media/ 目录下。因此,在实际应用中应优先选择压缩效率高且兼容性良好的格式,如 PNG 和 JPEG。
此外,存在以下限制:
- 文件大小 :过大的图像可能导致内存溢出或文档打开缓慢。
- DPI 分辨率 :Word 默认按 96 DPI 渲染图像,若需高清输出,应在插入后手动调整布局。
- 跨平台兼容性 :EMF 是 Windows 特有格式,在非 Windows 系统上可能无法正确渲染。
5.1.2 将字节数组或文件流转换为XWPFPictureData
要将图像嵌入 .docx 文档,必须首先将其转化为 XWPFPictureData 对象。该过程通常包括读取图像输入流,并调用 Document#addPicture() 方法注册图片资源。
import org.apache.poi.xwpf.usermodel.*;
import java.io.FileInputStream;
import java.io.IOException;
public class ImageEmbedder {
public static void embedImage(XWPFDocument document, String imagePath, int pictureType) throws IOException {
try (FileInputStream is = new FileInputStream(imagePath)) {
byte[] bytes = is.readAllBytes();
// 将图像数据添加到文档中,返回其在文档中的索引
int pictureIndex = document.addPictureData(bytes, pictureType);
// 获取当前段落或创建新段落
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
// 插入图片
run.addPicture(document.getPackagePart(), pictureType, imagePath,
Units.toEMU(400), Units.toEMU(300)); // 宽400px, 高300px
}
}
}
AI写代码
java
运行
代码逻辑逐行解读:
FileInputStream is = new FileInputStream(imagePath)
打开本地图像文件的输入流,准备读取原始字节。
byte[] bytes = is.readAllBytes()
将整个图像读入内存字节数组。注意:对于大文件,此操作可能引发 OutOfMemoryError ,后续章节会介绍流式处理优化方案。
document.addPictureData(bytes, pictureType)
调用文档对象方法将图像数据注册为一个内嵌资源,返回唯一索引 pictureIndex ,用于后续引用。
document.getPackagePart()
获取底层 OPCPackage 的 PackagePart,这是 OpenXML 文档结构的一部分,表示当前文档容器。
Units.toEMU(400)
Apache POI 使用 English Metric Units (EMU) 表示尺寸(1 inch = 914400 EMUs)。此处将像素转换为 EMU 单位以适配 Word 布局引擎。
run.addPicture(...)
在指定 Run 中插入图像,形成图文混排效果。
⚠️ 参数说明: pictureType 必须匹配实际图像类型,例如 XWPFDocument.PICTURE_TYPE_JPEG 或 PICTURE_TYPE_PNG ,否则会导致文档损坏。
5.1.3 在段落中插入图片并控制尺寸与位置
图像在 Word 文档中的呈现依赖于其所在的 XWPFRun 和父级 XWPFParagraph 。默认情况下,图像以“内联”(inline)形式插入,即作为文本流的一部分进行排列。
可以通过设置运行属性来微调图像位置:
XWPFRun run = paragraph.createRun();
run.setText("图1:系统架构示意图");
run.addCarriageReturn(); // 换行
// 设置图片居中对齐
paragraph.setAlignment(ParagraphAlignment.CENTER);
run = paragraph.createRun();
run.addPicture(
document.getPackagePart(),
XWPFDocument.PICTURE_TYPE_PNG,
"arch-diagram.png",
Units.toEMU(500), // 宽度(EMU)
Units.toEMU(350) // 高度(EMU)
);
AI写代码
java
运行
mermaid 流程图:图像插入流程
graph TD
A[开始] --> B{图像源是否存在?}
B -- 否 --> C[抛出 FileNotFoundException]
B -- 是 --> D[读取图像为字节数组]
D --> E[调用 addPictureData 注册图像]
E --> F[获取 PackagePart 引用]
F --> G[创建段落与Run]
G --> H[调用 addPicture 插入图像]
H --> I[设置尺寸与对齐方式]
I --> J[结束]
AI写代码
mermaid
该流程清晰展示了从图像读取到最终渲染的完整链路,强调了资源注册与布局分离的设计思想。
5.2 图片样式与环绕方式设置
5.2.1 图文混排模式(inline vs floating)选择
Apache POI 提供两种主要图像布局模式:
Inline(内联) :图像作为字符插入文本流中,随段落移动,不能自由定位。
Floating(浮动) :图像脱离文本流,可设置绝对位置、环绕方式和层级关系。
目前 XWPF 原生 API 主要支持 Inline 模式。要实现 Floating 效果,需直接操作底层 OpenXML XML 结构,借助 CTDrawing 和 CTAnchor 元素。
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.math.BigInteger;
private void addFloatingImage(XWPFDocument doc, XWPFParagraph paragraph, byte[] imageData) {
// 创建 Drawing 容器
CTDrawing drawing = paragraph.getCTP().addNewR().addNewDrawing();
// 创建锚点(相对于页边距定位)
CTAnchor anchor = drawing.addNewAnchor();
anchor.setSimplePos(false);
anchor.setRelativeHeight(BigInteger.valueOf(25165824)); // 层级Z-order
anchor.setBehindDoc(false); // 是否置于文字下方
anchor.setLockWithAspectLock(true); // 锁定宽高比
// 设置位置(单位:EMU)
CTPoint2D offset = anchor.addNewPositionH().addNewAlign();
offset.setVal(STAlignType.CENTER); // 水平居中
anchor.addNewPositionV().addNewAlign().setVal(STAlignType.CENTER);
// 图像宽度高度(EMU)
anchor.setExtent(CTSSTUnit.Factory.newInstance());
anchor.getExtent().setCx(Units.toEMU(400));
anchor.getExtent().setCy(Units.toEMU(300));
// 创建图像内容
CTGraphicalObjectFrame graphicFrame = anchor.addNewGraphic().addNewGraphicData();
graphicFrame.setUri("http://schemas.openxmlformats.org/drawingml/2006/picture");
CTPicture ctPic = graphicFrame.addNewPic();
CTNonVisualPictureProperties nvProps = ctPic.addNewNvPicPr();
nvProps.addNewCNvPr().setId(1);
nvProps.getCNvPr().setName("Picture 1");
// 设置图像数据引用
CTRelativeFromH posH = anchor.addNewPositionH();
posH.setRelativeFrom(STRelativeFromH.MARGIN);
posH.setAlign(STAlignH.CENTER);
CTPositiveSize2D extent = ctPic.addNewSpPr().addNewXfrm().addNewExt();
extent.setCx(Units.toEMU(400));
extent.setCy(Units.toEMU(300));
// 添加 Blip(图像位图引用)
CTBlipFillProperties blipFill = ctPic.addNewBlipFill();
CTBlip blib = blipFill.addNewBlip();
String relationshipId = doc.addPictureData(imageData, XWPFDocument.PICTURE_TYPE_PNG);
blib.setEmbed(relationshipId);
}
AI写代码
java
运行
表格:Inline 与 Floating 模式的对比
特性
Inline 模式
Floating 模式
实现难度
简单,原生支持
复杂,需操作 CT 对象
定位能力
固定在段落流中
可设定坐标、对齐方式
环绕支持
仅基本换行
支持四周型、紧密型等
编辑友好性
易于维护
修改困难,易出错
推荐用途
内容插图、小图标
精确定位图表、封面图
5.2.2 设置图片与文字的环绕类型(四周型、紧密型等)
尽管 XWPF 不直接暴露环绕设置接口,但可通过修改 anchor 中的 wrapSquare 元素实现:
CTWrapSquare wrap = anchor.addNewWrapSquare();
wrap.setWrapText(STWrapText.BOTH_SIDES); // BOTH_SIDES / LEFT / RIGHT
AI写代码
java
运行
环绕类型说明如下:
BOTH_SIDES :文字环绕图像两侧(四周型)
LEFT :仅右侧环绕
RIGHT :仅左侧环绕
LARGEST :根据图像形状自动判断
这种底层操作允许开发者模拟 Microsoft Word 中的高级排版行为,但需要熟悉 OpenXML Schema 结构。
5.2.3 图片标题自动生成与编号管理
为了增强文档的专业性,常需为图像添加自动编号标题,如“图1:XXX”。
private int figureCounter = 1;
private void insertLabeledImage(XWPFDocument doc, XWPFParagraph para, String imagePath, String caption) throws IOException {
byte[] imgData = Files.readAllBytes(Paths.get(imagePath));
int picType = determinePictureType(imagePath);
// 插入图像
XWPFRun run = para.createRun();
run.addCarriageReturn();
run.setText(String.format("图%d:%s", figureCounter++, caption));
run.addCarriageReturn();
run = para.createRun();
run.addPicture(
doc.getPackagePart(),
picType,
imagePath,
Units.toEMU(450),
Units.toEMU(300)
);
run.addCarriageReturn();
}
AI写代码
java
运行
此方法实现了简单的顺序编号机制。更高级的做法是结合 XWPFStyles 定义“题注”样式,并利用 numId 实现多级列表编号。
5.3 图表与复杂图形的间接集成方案
5.3.1 使用Apache POI插入已生成的图表图像
由于 Apache POI 当前版本(5.2.4)尚不支持原生 Chart 对象(如
典型流程如下:
使用 JFreeChart、XChart 或 Plotly Java 生成统计图并导出为 PNG。
将图像写入临时文件或内存流。
调用 XWPFRun#addPicture 插入文档。
// 示例:生成柱状图并插入
JFreeChart chart = ChartFactory.createBarChart(
"销售额统计", "月份", "金额",
createDataset(), PlotOrientation.VERTICAL, true, true, false
);
BufferedImage bufferedImage = chart.createBufferedImage(600, 400);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", baos);
// 插入到文档
int idx = document.addPictureData(baos.toByteArray(), Document.PICTURE_TYPE_PNG);
XWPFParagraph p = document.createParagraph();
XWPFRun r = p.createRun();
r.addPicture(document.getPackagePart(), XWPFDocument.PICTURE_TYPE_PNG, "chart.png",
Units.toEMU(500), Units.toEMU(350));
AI写代码
java
运行
这种方式虽失去交互性和动态更新能力,但在大多数报表场景中已足够使用。
5.3.2 结合JFreeChart等库生成统计图并嵌入文档
下面是一个完整的 JFreeChart + POI 集成示例:
private CategoryDataset createDataset() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(120, "Q1", "北京");
dataset.addValue(150, "Q1", "上海");
dataset.addValue(130, "Q1", "广州");
return dataset;
}
private void generateChartAndInsert(XWPFDocument doc) throws IOException {
JFreeChart chart = ChartFactory.createBarChart(
"区域销售对比", "城市", "销售额(万元)",
createDataset(),
PlotOrientation.VERTICAL,
true, true, false
);
// 自定义样式
chart.getTitle().setFont(new Font("SimHei", Font.BOLD, 16));
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.getDomainAxis().setLabelFont(new Font("SimSun", Font.PLAIN, 12));
plot.getRangeAxis().setLabelFont(new Font("SimSun", Font.PLAIN, 12));
BufferedImage img = chart.createBufferedImage(700, 400);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(img, "png", os);
XWPFParagraph p = doc.insertNewParagraph(doc.getDocument().getCTBody().addNewP());
XWPFRun r = p.createRun();
r.addPicture(
new ByteArrayInputStream(os.toByteArray()),
XWPFDocument.PICTURE_TYPE_PNG,
"sales-chart.png",
Units.toEMU(600),
Units.toEMU(400)
);
}
AI写代码
java
运行
✅ 优势:完全可控的视觉设计;支持中文渲染;可复用于 PDF、Web 输出。
❌ 缺陷:图表为静态图像,无法在 Word 中双击编辑。
5.3.3 图表更新机制与动态数据绑定思路
尽管无法实现真正的“动态图表”,但仍可通过模板化策略模拟数据驱动更新:
预定义图像占位符 :在模板文档中标记图像区域(如 ${chart:sales} )。
运行时替换 :识别标记,生成对应图表图像,替换原图。
缓存机制 :对高频图表进行结果缓存,避免重复计算。
Map
String placeholder = "${chart:revenue-q3}";
if (placeholder.startsWith("${chart:")) {
String key = extractKey(placeholder); // revenue-q3
BufferedImage chartImg = chartCache.computeIfAbsent(key, k -> generateRevenueChart(k));
byte[] pngData = renderToByteArray(chartImg, "png");
replacePlaceholderWithImage(document, placeholder, pngData);
}
AI写代码
java
运行
未来随着 POI 社区对 XWPFChart 的逐步支持,有望实现真正的 OpenXML Chart 对象插入,届时将能生成可在 Word 中编辑的图表。
6. 自动化应用场景实战:报表生成、合同定制、邮件合并
6.1 基于模板的动态数据填充与占位符替换
在企业级文档自动化场景中,使用预定义的 .docx 模板进行动态内容填充是一种高效且可维护的方式。Apache POI 提供了对段落和表格中文本内容的精细控制能力,使得开发者可以实现基于占位符(如 ${name} )的智能替换机制。
6.1.1 定义占位符语法与正则匹配规则
推荐采用 ${key} 的语法格式作为占位符标识,便于通过正则表达式精准识别。以下为通用匹配逻辑:
import java.util.regex.Pattern;
public class PlaceholderMatcher {
// 匹配 ${xxx} 格式的占位符
private static final Pattern PLACEHOLDER_PATTERN =
Pattern.compile("\\$\\{([a-zA-Z0-9._]+)}");
public static Pattern getPattern() {
return PLACEHOLDER_PATTERN;
}
}
AI写代码
java
运行
该正则表达式会捕获 ${} 内部的字段名(如 user.name ),支持嵌套属性路径。
6.1.2 遍历段落与表格实现全局替换
XWPF 中需分别处理段落(XWPFParagraph)和表格(XWPFTable)。以下是统一遍历并替换的核心方法:
import org.apache.poi.xwpf.usermodel.*;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
public void replacePlaceholders(XWPFDocument doc, Map
// 替换普通段落
for (XWPFParagraph p : doc.getParagraphs()) {
replaceInParagraph(p, data);
}
// 替换所有表格中的段落
for (XWPFTable table : doc.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph p : cell.getParagraphs()) {
replaceInParagraph(p, data);
}
}
}
}
}
private void replaceInParagraph(XWPFParagraph paragraph, Map
String text = paragraph.getText();
if (text == null) return;
Matcher matcher = PlaceholderMatcher.getPattern().matcher(text);
StringBuffer sb = new StringBuffer();
boolean hasReplacement = false;
while (matcher.find()) {
String key = matcher.group(1);
String value = data.getOrDefault(key, "N/A"); // 默认值防空
matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
hasReplacement = true;
}
matcher.appendTail(sb);
if (hasReplacement) {
// 清除原有 runs 并添加新文本
List
if (!runs.isEmpty()) {
XWPFRun firstRun = runs.get(0);
firstRun.setText(sb.toString(), 0);
for (int i = 1; i < runs.size(); i++) {
paragraph.removeRun(i);
}
} else {
paragraph.createRun().setText(sb.toString());
}
}
}
AI写代码
java
运行
执行逻辑说明 :
- 使用 StringBuffer 和 Matcher.appendReplacement() 实现安全字符串拼接;
- 替换后保留原第一个 Run 的样式(字体、颜色等),避免格式丢失;
- 若原段落无 Run,则创建新的 Run 插入。
6.1.3 处理复杂数据结构(列表、嵌套对象)的渲染逻辑
当模板中需要循环插入表格行或重复段落时,可引入特殊标记(如 ... )结合 AST 解析实现结构化渲染。
示例:JSON 数据模型
{
"reportTitle": "月度销售报告",
"generatedDate": "2025-04-05",
"salesTeam": [
{"name": "张三", "region": "华东", "quota": 800000},
{"name": "李四", "region": "华北", "quota": 750000},
{"name": "王五", "region": "华南", "quota": 920000}
]
}
AI写代码
json
可通过递归遍历模板段落,在检测到 LOOP 指令时动态克隆行并填充每项数据。
6.2 批量文档生成中的流式处理与内存优化策略
6.2.1 分批生成避免 OutOfMemoryError
传统 XWPFDocument 将整个文档加载至内存,面对数千份合同或报表时极易引发 OutOfMemoryError 。建议按批次处理,例如每批 50 份文档,处理完成后释放资源:
for (int i = 0; i < dataList.size(); i += 50) {
List
processBatch(batch);
System.gc(); // 可选触发垃圾回收
}
AI写代码
java
运行
6.2.2 使用 SXWPFStreaming 库进行大文档支持
SXWPFStreaming 是一个扩展库,提供类似 SXSSF 的流式写入能力。其核心思想是延迟写入、分块输出:
特性
XWPFDocument
SXWPFStreaming
内存占用
高(全载入)
低(流式)
最大文档大小
~100页以内
数千页
支持模板修改
是
是(受限)
并发写入
否
否
Maven坐标
poi-ooxml
com.github.opensagres:xdocreport
使用示例(伪代码):
InputStream templateStream = new FileInputStream("template.docx");
XDocReport report = XDocReportRegistry.getRegistry().loadReport(templateStream, TemplateEngineKind.Freemarker);
OutputStream out = new FileOutputStream("output_report.docx");
Context context = report.createContext();
context.put("data", complexDataModel);
report.process(context, out);
AI写代码
java
运行
6.2.3 文件分片与异步导出机制设计
对于超大规模任务(如10万份保单),应设计如下架构:
graph TD
A[用户请求导出] --> B{是否批量?}
B -->|是| C[拆分为子任务]
C --> D[放入消息队列 RabbitMQ/Kafka]
D --> E[消费者集群并行处理]
E --> F[生成文档并上传OSS/S3]
F --> G[发送完成通知邮件]
B -->|否| H[同步生成返回流]
AI写代码
mermaid
此方案实现了解耦、容错与横向扩展能力。
本文还有配套的精品资源
简介:在IT领域,自动生成排版规范的Word文档广泛应用于数据报告、自动化办公和批量文本处理。通过Java语言结合Apache POI等工具库,开发者可实现对.docx文件的读写与样式控制,支持字体、段落、表格、图片、页眉页脚等元素的精确排版,并能通过模板机制动态填充数据,完成高效自动化导出。该技术已在金融报表、合同生成、邮件合并等场景中发挥重要作用。本文介绍完整的Word文档生成流程,涵盖核心API使用、页面元素操作、性能优化及异常处理,帮助开发者构建稳定高效的文档自动化系统。
————————————————
版权声明:本文为CSDN博主「銀河鐵道的企鵝」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42573757/article/details/152081238
https://infogram.com/wvvpf_sfnjg
https://infogram.com/xtwhp_tdoaq
https://infogram.com/tlaes_pvsyt
https://infogram.com/oymlk_kiwfl
https://infogram.com/cirjn_ysbdo
https://infogram.com/nddre_jnwlx
https://infogram.com/sgznh_oprhi
https://infogram.com/rsztc_ncrnv
https://infogram.com/zqcuy_vaunz
https://infogram.com/dgxwv_zqpqw
https://infogram.com/vrfb-1h1749wqkl0qq2z
https://infogram.com/80128-nlhp-1h1749wqkl0qq2z
https://infogram.com/13589-xhgt-51624-1h1749wqkl0qq2z
https://infogram.com/505db0a2-9cb2-4a26-a51c-643856951e87
https://infogram.com/hwfy-1hmr6g8jedmgo2n
https://infogram.com/19598-zqhm-1hmr6g8jedmgo2n
https://infogram.com/60503-jegr-10919-1hmr6g8jedmgo2n
https://infogram.com/7f788e15-04a4-4574-bd5a-e6c6634056bc
https://infogram.com/bydi-1h0n25opk800l4p
https://infogram.com/10842-tsfv-1h0n25opk800l4p
https://infogram.com/80120-vpea-90598-1h0n25opk800l4p
https://infogram.com/80e27e3a-22e7-4cd4-b3c4-525d47df95b5
https://infogram.com/fddf-1h9j6q750vorv4g
https://infogram.com/85670-zfkj-1h9j6q750vorv4g
https://infogram.com/40013-hlff-79765-1h9j6q750vorv4g
https://infogram.com/23b009e0-3b37-4f08-ac93-ba87d7a783ff
https://infogram.com/zfcx-1hnq41op5ky8p23
https://infogram.com/59013-rzek-1hnq41op5ky8p23
https://infogram.com/98258-aodp-50344-1hnq41op5ky8p23
https://infogram.com/16734524-0f6b-456d-99cf-b8364ce732ac
https://infogram.com/ckcu-1hnp27eqk30yy4g
https://infogram.com/28208-ueeh-1hnp27eqk30yy4g
https://infogram.com/79445-esdm-28631-1hnp27eqk30yy4g
https://infogram.com/19e316c6-3710-405a-8301-b81cc8764057
https://infogram.com/krml-1hxj48mq350952v
https://infogram.com/21543-dplg-1hxj48mq350952v
https://infogram.com/94612-mzod-29083-1hxj48mq350952v
https://infogram.com/48ceab04-7604-438b-8914-250c3aace1bb
https://infogram.com/sffb-1h7v4pd03nvyj4k
https://infogram.com/21195-ldwx-1h7v4pd03nvyj4k
https://infogram.com/54144-mngu-47626-1h7v4pd03nvyj4k
https://infogram.com/aa714bff-6a09-4e0d-9eae-c6bb317032b4
https://infogram.com/asnf-1h984wv1j3wyz2p
https://infogram.com/60440-tqea-1h984wv1j3wyz2p
https://infogram.com/19167-caox-68564-1h984wv1j3wyz2p
https://infogram.com/4f25eb77-70ec-4c10-83bd-d17f34ff0df9
https://infogram.com/mwnc-1h0r6rzw0lonw4e
https://infogram.com/77602-eipp-1h0r6rzw0lonw4e
https://infogram.com/96135-oeou-26759-1h0r6rzw0lonw4e
https://infogram.com/792d96fb-bda2-47a4-a00b-9cc7304de274
https://infogram.com/uljy-1h1749wqkljvl2z
https://infogram.com/42820-prek-1h1749wqkljvl2z
https://infogram.com/06963-wtkq-25916-1h1749wqkljvl2z
https://infogram.com/c593c5f0-2e22-4106-bbd3-7fa7ef77a585
https://infogram.com/gqjv-1h0n25opk8joz4p
https://infogram.com/71973-bvfh-1h0n25opk8joz4p
https://infogram.com/84040-iyln-84103-1h0n25opk8joz4p
https://infogram.com/70d9f0e4-a4d1-400e-bc12-10674d6a24e2
https://infogram.com/wipl-1h9j6q750vq054g
https://infogram.com/73485-ocsz-1h9j6q750vq054g
https://infogram.com/92711-yqrd-44525-1h9j6q750vq054g
https://infogram.com/f3d9e1e9-85e7-401b-a7a3-43762aeca4c4
https://infogram.com/hnqi-1h7v4pd03nq984k
https://infogram.com/54772-zhsw-1h7v4pd03nq984k
https://infogram.com/60668-jvrb-93719-1h7v4pd03nq984k
https://infogram.com/347b2fad-9b99-421f-b3e8-c8517f0b689e
https://infogram.com/ptaz-1hnq41op5kjnk23
https://infogram.com/00838-kzdl-1hnq41op5kjnk23
https://infogram.com/81224-jcbr-93263-1hnq41op5kjnk23
https://infogram.com/1b12820d-56bf-4106-965e-2dd01059edff
https://infogram.com/pitq-1hnp27eqk3jzn4g
https://infogram.com/20382-koob-1hnp27eqk3jzn4g
https://infogram.com/09878-rqui-12817-1hnp27eqk3jzn4g
https://infogram.com/762f5466-4373-4745-86b7-ad33c8151f59
https://infogram.com/betn-1hxj48mq35jrq2v
https://infogram.com/87917-vgzq-1hxj48mq35jrq2v
https://infogram.com/43339-dnuf-72102-1hxj48mq35jrq2v
https://infogram.com/fe5c21ab-5075-4202-9551-4454466a7914
https://infogram.com/blde-1h984wv1j3gnd2p
https://infogram.com/36375-vnrh-1h984wv1j3gnd2p
https://infogram.com/75254-dbnw-91555-1h984wv1j3gnd2p
https://infogram.com/0ba2a738-6f13-4ca3-8422-59f0685a7992
https://infogram.com/rfth-1h0r6rzw0lqgl4e
https://infogram.com/01923-jzwu-1h0r6rzw0lqgl4e
https://infogram.com/57066-sovz-02581-1h0r6rzw0lqgl4e
https://infogram.com/a5cf8ea2-62c4-4c24-8469-a110da552e10
https://infogram.com/gscs-1hmr6g8jed3jo2n
https://infogram.com/91699-ymeg-1hmr6g8jed3jo2n
https://infogram.com/63730-aidl-42399-1hmr6g8jed3jo2n
https://infogram.com/61838a6f-3348-4f76-9766-4e4eb56a89cc
https://infogram.com/tffn-1h1749wqklj0q2z
https://infogram.com/48062-lzia-1h1749wqklj0q2z
https://infogram.com/76822-vnhf-99129-1h1749wqklj0q2z
https://infogram.com/1918a533-4730-42d3-86b5-3cac5c6001dd
https://infogram.com/npex-1h0n25opk8jjl4p
https://infogram.com/62449-gnvs-1h0n25opk8jjl4p
https://infogram.com/25072-gyfp-78900-1h0n25opk8jjl4p
https://infogram.com/3a419afb-d371-4d93-af19-320a3617d68c
https://infogram.com/mwwo-1h9j6q750vqev4g
https://infogram.com/29700-eqyb-1h9j6q750vqev4g
https://infogram.com/65197-oexg-88442-1h9j6q750vqev4g
https://infogram.com/01292fc8-2bdb-42cd-816d-d24337655955
https://infogram.com/ulgm-1hnq41op5kjzp23
https://infogram.com/42627-oeni-1hnq41op5kjzp23
https://infogram.com/91831-wtie-87075-1hnq41op5kjzp23
https://infogram.com/7a886788-4b61-4e12-8c02-765295ef1a09
https://infogram.com/yhhj-1hnp27eqk3j7y4g
https://infogram.com/51975-ajnn-1hnp27eqk3j7y4g
https://infogram.com/08281-apic-67260-1hnp27eqk3j7y4g
https://infogram.com/120950e0-6336-4a70-9e96-6a123d449453
https://infogram.com/kehg-1h984wv1j3gez2p
https://infogram.com/52945-egnk-1h984wv1j3gez2p
https://infogram.com/48078-muiz-26557-1h984wv1j3gez2p
https://infogram.com/88fb275e-c321-4097-a0f3-8cb8bd87ad0f
https://infogram.com/sszx-1hxj48mq35jy52v
https://infogram.com/72550-mugb-1hxj48mq35jy52v
https://infogram.com/30945-uabp-26909-1hxj48mq35jy52v
https://infogram.com/7ba6a10e-42a0-4a16-a560-d91dc653968c
https://infogram.com/rzko-1h0r6rzw0lqjw4e
https://infogram.com/53367-mfnz-1h0r6rzw0lqjw4e
https://infogram.com/18400-thlg-37653-1h0r6rzw0lqjw4e
https://infogram.com/2f8c34d3-3fa3-484c-94ff-a15ffd0288c6
https://infogram.com/htar-1hmr6g8jedndz2n
https://infogram.com/74393-czvd-1hmr6g8jedndz2n
https://infogram.com/38435-jcbj-55480-1hmr6g8jedndz2n
https://infogram.com/b04d96b6-abab-418d-8bfa-a8989e38e688
https://infogram.com/bcoo-1h1749wqkl1wl2z
https://infogram.com/15704-twqb-1h1749wqkl1wl2z
https://infogram.com/43052-dkpg-76455-1h1749wqkl1wl2z
https://infogram.com/9aefd522-b8da-4f49-ab74-dd3cd33611e3
https://infogram.com/mmiv-1h0n25opk8rkz4p
https://infogram.com/13373-egki-1h0n25opk8rkz4p
https://infogram.com/31606-gcjn-84420-1h0n25opk8rkz4p
https://infogram.com/548c20fb-76f3-401a-b4aa-bdc83efb9dc0
https://infogram.com/zfix-1h9j6q750vry54g
https://infogram.com/18973-thoa-1h9j6q750vry54g
https://infogram.com/36789-bnjp-73906-1h9j6q750vry54g
https://infogram.com/841e532e-cf7e-430f-aeb2-86bd3a320237
https://infogram.com/htsn-1h7v4pd03n5p84k
https://infogram.com/12726-zfub-1h7v4pd03n5p84k
https://infogram.com/60631-bctg-91640-1h7v4pd03n5p84k
https://infogram.com/74a63203-88fd-4373-a622-c91429a1dbf8
https://infogram.com/bcjo-1hnp27eqk3gxn4g
https://infogram.com/07150-vepr-1hnp27eqk3gxn4g
https://infogram.com/22104-vtkg-71673-1hnp27eqk3gxn4g
https://infogram.com/776ab147-c037-4618-996b-f62750f7d6c5
https://infogram.com/brtf-1hnq41op5kmqk23
https://infogram.com/69312-wxwq-1hnq41op5kmqk23
https://infogram.com/01081-dzux-91327-1hnq41op5kmqk23
https://infogram.com/f9fcea8d-7db3-44de-837f-0e07dfad8944
https://infogram.com/jylv-1hxj48mq35znq2v
https://infogram.com/08682-edgh-1hxj48mq35znq2v
https://infogram.com/63895-kono-82768-1hxj48mq35znq2v
https://infogram.com/72809fbf-4aa1-42e7-9b8b-f8013cb8a005
https://infogram.com/mcms-1h984wv1j378d2p
https://infogram.com/52731-nado-1h984wv1j378d2p
https://infogram.com/71447-oknl-60955-1h984wv1j378d2p
https://infogram.com/0570a02d-aa90-4a59-8b4f-8d9d3fbd82f1
https://infogram.com/cpuw-1h0r6rzw0ldwl4e
https://infogram.com/54190-vnlr-1h0r6rzw0ldwl4e
https://infogram.com/54830-exvo-81093-1h0r6rzw0ldwl4e
https://infogram.com/595336b0-d02b-4781-ab02-7e6190844004
https://infogram.com/kdmm-1hmr6g8jednmo2n
https://infogram.com/96220-efsq-1hmr6g8jednmo2n
https://infogram.com/22853-elof-89435-1hmr6g8jednmo2n
https://infogram.com/64a4a91d-2067-48ab-9552-66afad5b7cc4
https://infogram.com/emar-1h1749wqkl1jq2z
https://infogram.com/72266-xkzm-1h1749wqkl1jq2z
https://infogram.com/94171-gubj-00480-1h1749wqkl1jq2z
https://infogram.com/f9d3421c-01f9-46b8-8d8e-18ed85281fd1
https://infogram.com/pvam-1h0n25opk8rrl4p
https://infogram.com/68140-hpcz-1h0n25opk8rrl4p
https://infogram.com/75356-iebe-17417-1h0n25opk8rrl4p
https://infogram.com/6b581ed1-e4bd-4ec1-bdc9-9f1e85fa112a
https://infogram.com/gfcy-1h9j6q750vr9v4g
https://infogram.com/22325-ahic-1h9j6q750vr9v4g
https://infogram.com/61392-andq-67794-1h9j6q750vr9v4g
https://infogram.com/edbccd06-33cf-4773-8cb7-5cf948a68e17
https://infogram.com/spai-1hnp27eqk3gly4g
https://infogram.com/67042-kjcv-1hnp27eqk3gly4g
https://infogram.com/06269-uyba-65473-1hnp27eqk3gly4g
https://infogram.com/c00a7a47-06ac-4d78-8e59-ea4e3c993a8c
https://infogram.com/emaf-1h7v4pd03n58j4k
https://infogram.com/46911-wgcs-1h7v4pd03n58j4k
https://infogram.com/26537-gubx-26669-1h7v4pd03n58j4k
https://infogram.com/6d5ef2f8-73e6-47e7-816b-439d1c3052dd
https://infogram.com/iiak-1hnq41op5kmrp23
https://infogram.com/86513-acdx-1hnq41op5kmrp23
https://infogram.com/25748-jzcc-95834-1hnq41op5kmrp23
https://infogram.com/98817bc0-5ff9-4574-9440-643e0369a4ff
https://infogram.com/tovl-1hxj48mq35zk52v
https://infogram.com/94040-lhyz-1hxj48mq35zk52v
https://infogram.com/13375-nwxd-36189-1hxj48mq35zk52v
https://infogram.com/1b02b6a0-416c-4a13-b20a-7e317fa5036e
https://infogram.com/xswi-1h984wv1j379z2p
https://infogram.com/75336-pmyw-1h984wv1j379z2p
https://infogram.com/82860-zaxa-14374-1h984wv1j379z2p
https://infogram.com/4d7b9d71-7e2c-41c8-aa46-1ca52e1852d1
https://infogram.com/rvms-1h0r6rzw0lmlw4e
https://infogram.com/95832-jpof-1h0r6rzw0lmlw4e
https://infogram.com/33868-tdnk-95054-1h0r6rzw0lmlw4e
https://infogram.com/6c7b8b79-d951-4119-b2c2-062c824b985b
https://infogram.com/xinh-1hmr6g8jedr7z2n
https://infogram.com/16705-qfnd-1hmr6g8jedr7z2n
https://infogram.com/15484-yqpz-84145-1hmr6g8jedr7z2n
https://infogram.com/1d3c000b-4974-40ee-88ee-70b687b24135
https://infogram.com/aglw-1h1749wqklgkl2z
https://infogram.com/68836-uizz-1h1749wqklgkl2z
https://infogram.com/17051-upmo-23215-1h1749wqklgkl2z
https://infogram.com/9577b4eb-7ed0-4ed2-b40b-8e890d035cee
https://infogram.com/pxlx-1h0n25opk8vmz4p
https://infogram.com/15907-ivcs-1h0n25opk8vmz4p
https://infogram.com/88875-jfmp-11546-1h0n25opk8vmz4p
https://infogram.com/064b8663-f8bd-4415-917d-e581112f763c
https://infogram.com/peqs-1h9j6q750vep54g
https://infogram.com/44530-ichn-1h9j6q750vep54g
https://infogram.com/12397-rurk-10059-1h9j6q750vep54g
https://infogram.com/8a6757c7-608b-458a-8385-7fb58216990a
https://infogram.com/zpur-1h7v4pd03nyj84k
https://infogram.com/73521-sftn-1h7v4pd03nyj84k
https://infogram.com/41370-byvk-59040-1h7v4pd03nyj84k
https://infogram.com/5c857fec-2e92-47b3-8f9a-f3ff6c40c9cc
https://infogram.com/sssb-1hnq41op5kexk23
https://infogram.com/22060-lqjx-1hnq41op5kexk23
https://infogram.com/85913-matt-40621-1hnq41op5kexk23
https://infogram.com/d2b63da0-5162-42b8-bd1c-b57959a169f1
https://infogram.com/syls-1hnp27eqk3r1n4g
https://infogram.com/43714-lwcn-1hnp27eqk3r1n4g
https://infogram.com/86782-upmk-49273-1hnp27eqk3r1n4g
https://infogram.com/3009c0b4-6da5-4839-9b0d-9c7faf5ab5dc
https://infogram.com/anvj-1hxj48mq35d8q2v
https://infogram.com/17892-vtyu-1hxj48mq35d8q2v
https://infogram.com/49344-cvwb-49726-1hxj48mq35d8q2v
https://infogram.com/d9bf5484-7061-4818-bd0e-42a5b4870377
https://infogram.com/iiyq-1h984wv1j3rld2p
https://infogram.com/78938-acid-1h984wv1j3rld2p
https://infogram.com/64550-kqzi-68714-1h984wv1j3rld2p
https://infogram.com/40834c05-ccf9-424c-845e-b8278ee0165f
https://infogram.com/qpqh-1h0r6rzw0lmol4e
https://infogram.com/14097-krwk-1h0r6rzw0lmol4e
https://infogram.com/63964-jxrz-59466-1h0r6rzw0lmol4e
https://infogram.com/35c32888-a384-41ba-98df-5e4e6b230161
https://infogram.com/fqrj-1hmr6g8jedr3o2n
https://infogram.com/00623-yoie-1hmr6g8jedr3o2n
https://infogram.com/69903-hysb-98827-1hmr6g8jedr3o2n
https://infogram.com/8ba57a94-e862-411f-b3cc-2ecd7363bac9
https://infogram.com/bpbc-1h1749wqklg1q2z
https://infogram.com/07487-tjdp-1h1749wqklg1q2z
https://infogram.com/22438-dxcu-17855-1h1749wqklg1q2z
https://infogram.com/d6ddd291-e50b-4954-ad6a-b5d6658a8b58
https://infogram.com/ikrf-1h0n25opk8vvl4p
https://infogram.com/81830-cmxj-1h0n25opk8vvl4p
https://infogram.com/91328-kssx-46883-1h0n25opk8vvl4p
https://infogram.com/3fdda5c9-6011-4a14-aa15-b2d364651bf8
https://infogram.com/snqj-1h9j6q750vekv4g
https://infogram.com/48800-llhe-1h9j6q750vekv4g
https://infogram.com/42470-uwrb-66944-1h9j6q750vekv4g
https://infogram.com/be93e263-d5d6-464a-98f7-c7f6d08b4ebc
https://infogram.com/mygt-1h7v4pd03ny7j4k
https://infogram.com/60765-gsuw-1h7v4pd03ny7j4k
https://infogram.com/91826-gghl-44515-1h7v4pd03ny7j4k
https://infogram.com/c3bf5cd5-2c4a-4c6f-9282-7cd1b5e8587a
https://infogram.com/jxez-1hnq41op5kedp23
https://infogram.com/97829-cvvv-1hnq41op5kedp23
https://infogram.com/61098-lofr-93480-1hnq41op5kedp23
https://infogram.com/3cc5c1c1-303b-4cc5-8e7d-c0063d3a128f
https://infogram.com/bpgu-1hnp27eqk3r9y4g
https://infogram.com/20943-wvjf-1hnp27eqk3r9y4g
https://infogram.com/62710-dxhm-53855-1hnp27eqk3r9y4g
https://infogram.com/3d9013b7-cf19-4ede-86b2-7fa91343bb19
https://infogram.com/flgr-1hxj48mq35dx52v
https://infogram.com/40617-arjc-1hxj48mq35dx52v
https://infogram.com/41135-hthj-33042-1hxj48mq35dx52v
https://infogram.com/75a3e1e9-f9e0-4dad-8cb3-3844b44adb0f
https://infogram.com/malm-1h0r6rzw0lypw4e
https://infogram.com/49231-gczp-1h0r6rzw0lypw4e
https://infogram.com/34265-gine-02744-1h0r6rzw0lypw4e
https://infogram.com/5000d7e1-63fb-4a04-a5fe-90f39f30bfb8
https://infogram.com/mhec-1h984wv1j353z2p
https://infogram.com/49119-hnzo-1h984wv1j353z2p
https://infogram.com/04242-opfu-23397-1h984wv1j353z2p
https://infogram.com/b5348092-8d72-4f3b-9430-ed5b761b2705
https://infogram.com/snhf-1hmr6g8jedx8z2n
https://infogram.com/35626-llza-1hmr6g8jedx8z2n
https://infogram.com/56530-uwjx-82104-1hmr6g8jedx8z2n
https://infogram.com/727e81b5-b4f0-483b-8d90-69a10f32a3e4
https://infogram.com/omft-1h1749wqklzxl2z
https://infogram.com/56011-iolx-1h1749wqklzxl2z
https://infogram.com/86161-pvgm-21064-1h1749wqklzxl2z
https://infogram.com/dcab157d-c652-47f3-9c12-7d0d970ae54b
https://infogram.com/rjav-1h0n25opk8q3z4p
https://infogram.com/89414-mpvg-1h0n25opk8q3z4p
https://infogram.com/66220-tabn-72328-1h0n25opk8q3z4p
https://infogram.com/3d8407fb-800b-4898-93d5-cb8fd9035421
https://infogram.com/sqny-1h9j6q750v9j54g
https://infogram.com/15221-nsbb-1h9j6q750v9j54g
https://infogram.com/37625-uyoq-40332-1h9j6q750v9j54g
https://infogram.com/e9c9232d-3f97-48bb-9f51-cb890032658d
https://infogram.com/gina-1h7v4pd03nlx84k
https://infogram.com/87621-boql-1h7v4pd03nlx84k
https://infogram.com/41754-iros-69819-1h7v4pd03nlx84k
https://infogram.com/80395673-bc4a-4158-883a-889115887faf
https://infogram.com/chko-1hnq41op5k8lk23
https://infogram.com/06917-xnfa-1hnq41op5k8lk23
https://infogram.com/09540-eqlh-08777-1hnq41op5k8lk23
https://infogram.com/cfb5e6f9-66a8-48f0-b497-14485afb6ae3
https://infogram.com/kouf-1hnp27eqk3dpn4g
https://infogram.com/90662-dmtb-1hnp27eqk3dpn4g
https://infogram.com/63850-mwvx-08221-1hnp27eqk3dpn4g
https://infogram.com/13134eaf-a9d8-4344-9083-f7e056741d93
https://infogram.com/llis-1hxj48mq35gwq2v
https://infogram.com/32743-fnpw-1hxj48mq35gwq2v
https://infogram.com/88177-ntkk-17830-1hxj48mq35gwq2v
https://infogram.com/830133fd-806c-4b5e-b860-1bc3bb70f6b9
https://infogram.com/byrw-1h984wv1j351d2p
https://infogram.com/07145-tstj-1h984wv1j351d2p
https://infogram.com/69006-doso-36875-1h984wv1j351d2p
https://infogram.com/e3a76436-cda2-4cb8-87a7-56081a5b98da
https://infogram.com/jszz-1h0r6rzw0lyql4e
https://infogram.com/75033-eycl-1h0r6rzw0lyql4e
https://infogram.com/98577-lbir-76603-1h0r6rzw0lyql4e
https://infogram.com/3a26aa82-81cb-4a02-9d63-fedb51cbb0db
https://infogram.com/zfpk-1hmr6g8jedxno2n
https://infogram.com/58571-sdgy-1hmr6g8jedxno2n
https://infogram.com/75517-bvqd-97711-1hmr6g8jedxno2n
https://infogram.com/aec52e58-4bbe-42d5-8994-3243813db99e
https://infogram.com/acbt-1h0n25opk8qql4p
https://infogram.com/46287-swlh-1h0n25opk8qql4p
https://infogram.com/50401-ckkm-26060-1h0n25opk8qql4p
https://infogram.com/e598877a-e874-47ad-8f94-89a9cb789f26
https://infogram.com/iitk-1h1749wqklzgq2z
https://infogram.com/13516-doow-1h1749wqklzgq2z
https://infogram.com/63511-kzuc-24714-1h1749wqklzgq2z
https://infogram.com/34377be2-2ac6-4a20-a1c6-e614bc80f70c
https://infogram.com/fuwl-1h9j6q750v9lv4g
https://infogram.com/19684-zwco-1h9j6q750v9lv4g
https://infogram.com/56561-hkyd-54062-1h9j6q750v9lv4g
https://infogram.com/41376937-c4fb-4765-be9c-c93d4aa45efa
https://infogram.com/dvcb-1h7v4pd03nl1j4k
https://infogram.com/02499-vpeo-1h7v4pd03nl1j4k
https://infogram.com/99020-fdet-93284-1h7v4pd03nl1j4k
https://infogram.com/8aeec4ea-2b12-4428-a6e3-88416293dfd8
https://infogram.com/lhse-1hnq41op5k8gp23
https://infogram.com/55673-efkz-1hnq41op5k8gp23
https://infogram.com/33977-nxuw-33212-1hnq41op5k8gp23
https://infogram.com/e3028fbc-3909-480a-a973-7aba89ef3b0b
https://infogram.com/gaso-1hnp27eqk3d8y4g
https://infogram.com/34575-zyjj-1hnp27eqk3d8y4g
https://infogram.com/53358-iitg-22776-1hnp27eqk3d8y4g
https://infogram.com/f724bbcb-33ba-4f29-8583-51eb9e975d7e
https://infogram.com/czhc-1hxj48mq35e552v
https://infogram.com/24707-vxgy-1hxj48mq35e552v
https://infogram.com/51957-ehiv-61737-1hxj48mq35e552v
https://infogram.com/55a559da-562a-4e59-b726-d318b4c77382
https://infogram.com/owha-1h984wv1j3doz2p
https://infogram.com/36737-iyvd-1h984wv1j3doz2p
https://infogram.com/92469-iejs-22932-1h984wv1j3doz2p
https://infogram.com/134a54d0-c808-4b4f-895c-9c2e04e265b6
https://infogram.com/wqxd-1h0r6rzw0l5zw4e
https://infogram.com/84340-popy-1h0r6rzw0l5zw4e
https://infogram.com/62626-yyzv-60969-1h0r6rzw0l5zw4e
https://infogram.com/4dbd0789-7442-484f-9312-74571b580944
https://infogram.com/hnya-1hmr6g8jedzez2n
https://infogram.com/35069-bpee-1hmr6g8jedzez2n
https://infogram.com/72147-jvzs-11156-1hmr6g8jedzez2n
https://infogram.com/a63b317f-0c44-4f4e-a527-60e7615d758f
https://infogram.com/ftcd-1h1749wqklmol2z
https://infogram.com/43485-yrty-1h1749wqklmol2z
https://infogram.com/74399-hcdv-90962-1h1749wqklmol2z
https://infogram.com/f0b58536-06e1-45d1-bb07-6f4b85b03426
https://infogram.com/rqca-1h0n25opk8lzz4p
https://infogram.com/47049-mwxl-1h0n25opk8lzz4p
https://infogram.com/97484-tyds-50257-1h0n25opk8lzz4p
https://infogram.com/7777fc5d-9e33-41d8-9d4f-62ea5cfdbc40
https://infogram.com/ybeo-1h9j6q750vkx54g
https://infogram.com/97619-quhc-1h9j6q750vkx54g
https://infogram.com/31418-ajgg-49096-1h9j6q750vkx54g
https://infogram.com/d5fc6735-104e-48f0-810b-465db1d1eaf9
https://infogram.com/iejo-1h7v4pd03n8m84k
https://infogram.com/98003-aylb-1h7v4pd03n8m84k
https://infogram.com/72318-kmkg-88097-1h7v4pd03n8m84k
https://infogram.com/79fa98bf-167b-4115-96a1-cf4129222936
https://infogram.com/xfji-1hnq41op5kz1k23
https://infogram.com/66992-pzlv-1hnq41op5kz1k23
https://infogram.com/99633-znka-17578-1hnq41op5kz1k23
https://infogram.com/22e1f5ab-c34e-49c9-9d0f-12080ce9a9ac
https://infogram.com/lslx-1hnp27eqk3yvn4g
https://infogram.com/51290-furb-1hnp27eqk3yvn4g
https://infogram.com/00504-famp-96668-1hnp27eqk3yvn4g
https://infogram.com/816f6181-395d-4a19-a02d-1a075d1f2f0a
https://infogram.com/polu-1hxj48mq35eqq2v
https://infogram.com/64525-kugg-1hxj48mq35eqq2v
https://infogram.com/75793-rxmn-76953-1hxj48mq35eqq2v
https://infogram.com/39aaceff-2964-492a-8d10-59046c8e9265
https://infogram.com/btlr-1h0r6rzw0l5dl4e
https://infogram.com/22790-wzgd-1h0r6rzw0l5dl4e
https://infogram.com/36088-dbnk-35140-1h0r6rzw0l5dl4e
https://infogram.com/da9065c2-6415-4c3d-b354-d91f9c154937
https://infogram.com/fpmo-1h984wv1j3dwd2p
https://infogram.com/15696-xjoc-1h984wv1j3dwd2p
https://infogram.com/85965-gynh-16335-1h984wv1j3dwd2p
https://infogram.com/2b2b238b-bc9e-498f-8c5b-7ad95b8ba289
https://infogram.com/cqseo_yakyh
https://infogram.com/qbro-1hmr6g8jedzro2n
https://infogram.com/24074-ivtc-1hmr6g8jedzro2n
https://infogram.com/13925-srsh-65313-1hmr6g8jedzro2n
https://infogram.com/d2b56aea-41e2-4d1d-aea5-609b4aae5f45
https://infogram.com/gwzs-1h1749wqklmzq2z
https://infogram.com/02083-bccd-1h1749wqklmzq2z
https://infogram.com/57196-ieik-84151-1h1749wqklmzq2z
https://infogram.com/6c3cd7d3-bbc4-4560-82d9-da1071b23899
https://infogram.com/woni-1h0n25opk8lll4p
https://infogram.com/46379-pmed-1h0n25opk8lll4p
https://infogram.com/65639-yeoa-44573-1h0n25opk8lll4p
https://infogram.com/4009d5bd-0e51-4c5d-b375-a9b82f650e7f
https://infogram.com/xfbet_tptyu
https://infogram.com/pzyww_ljqpx
https://infogram.com/jqusp_fammq
https://infogram.com/zrumt_vbngm
https://infogram.com/ggzh-1h7v4pd03n8gj4k
https://infogram.com/83329-zwrc-1h7v4pd03n8gj4k
https://infogram.com/10680-aobz-40568-1h7v4pd03n8gj4k
https://infogram.com/4fd46cd4-97f2-4982-9d9b-6defdf27cea5
https://infogram.com/kdae-1h9j6q750vknv4g
https://infogram.com/21006-cxcr-1h9j6q750vknv4g
https://infogram.com/00722-mlbw-01754-1h9j6q750vknv4g
https://infogram.com/b5d0e1d5-b094-4e8f-b19d-a0e303a740ea
https://infogram.com/apqp-1hnq41op5kzvp23
https://infogram.com/31607-sjsd-1hnq41op5kzvp23
https://infogram.com/26328-cgri-29662-1hnq41op5kzvp23
https://infogram.com/dbe2e98a-eeaa-4267-b803-ed7436a61aae
https://infogram.com/aevk-1hnp27eqk3ywy4g
https://infogram.com/73896-tcmg-1hnp27eqk3ywy4g
https://infogram.com/02948-cnwc-20374-1hnp27eqk3ywy4g
https://infogram.com/18afb466-c103-41ef-a9fc-aa386c5798b9
https://infogram.com/hzys-1hxj48mq35lp52v
https://infogram.com/25912-bbev-1hxj48mq35lp52v
https://infogram.com/38710-jizk-39479-1hxj48mq35lp52v
https://infogram.com/9e1b2ba6-1854-4d85-9705-bad596b6a817
https://infogram.com/kufw-1h984wv1j3kvz2p
https://infogram.com/45882-faii-1h984wv1j3kvz2p
https://infogram.com/70863-mlgo-48754-1h984wv1j3kvz2p
https://infogram.com/67094da3-31a2-45b7-8188-cf663963c6d2
https://infogram.com/qbjz-1hmr6g8jedvwz2n
https://infogram.com/27712-ivlm-1hmr6g8jedvwz2n
https://infogram.com/97181-kjkr-07360-1hmr6g8jedvwz2n
https://infogram.com/d31191f1-c59f-4f80-83ea-fedf29aa14f3
https://infogram.com/qibp-1h0r6rzw0l90w4e
https://infogram.com/20453-jftl-1h0r6rzw0l90w4e
https://infogram.com/73086-sydq-28904-1h0r6rzw0l90w4e
https://infogram.com/d9b5b4ec-46e1-48f0-9338-a57e4a48b77b
https://infogram.com/gckb-1h1749wqkl93l2z
https://infogram.com/21483-aeye-1h1749wqkl93l2z
https://infogram.com/35062-iklt-46722-1h1749wqkl93l2z
https://infogram.com/6a7e29f9-5531-4f37-a3ae-e41346d5f2cd
https://infogram.com/lplq-1h0n25opk81dz4p
https://infogram.com/23445-gnoc-1h0n25opk81dz4p
https://infogram.com/60223-nxmi-35912-1h0n25opk81dz4p
https://infogram.com/62b44438-2684-4024-a7cd-25e3aa4d04e6
https://infogram.com/zjme-1h9j6q750vlm54g
https://infogram.com/87514-shea-1h9j6q750vlm54g
https://infogram.com/51403-tzow-15074-1h9j6q750vlm54g
https://infogram.com/07db1103-f2a7-4be3-bbbd-cf067ee13e95
https://infogram.com/cdsw-1h7v4pd03n7e84k
https://infogram.com/06831-vbrs-1h7v4pd03n7e84k
https://infogram.com/52677-elto-63772-1h7v4pd03n7e84k
https://infogram.com/c3a24dab-505e-408e-89c8-2c72871a1052
https://infogram.com/ibwz-1hnq41op5krwk23
https://infogram.com/77202-bzvu-1hnq41op5krwk23
https://infogram.com/96995-kkfr-24588-1hnq41op5krwk23
https://infogram.com/6fbcd9bd-4081-47f1-a9e3-0d2b23009498
https://infogram.com/qwmc-1hnp27eqk37qn4g
https://infogram.com/32958-qqoq-1hnp27eqk37qn4g
https://infogram.com/87190-senc-62516-1hnp27eqk37qn4g
https://infogram.com/0c62adfc-ec02-41bd-939c-1a3a0c8e1ac5
https://infogram.com/jzku-1hxj48mq35l0q2v
https://infogram.com/40284-efff-1hxj48mq35l0q2v
https://infogram.com/37446-lhlm-33277-1hxj48mq35l0q2v
https://infogram.com/05e0df13-8c3f-4a56-8c31-5bd9641593ae
https://infogram.com/fhor-1h984wv1j3kgd2p
https://infogram.com/84987-yffm-1h984wv1j3kgd2p
https://infogram.com/05799-zpqj-31462-1h984wv1j3kgd2p
https://infogram.com/707090b6-0e54-40ba-8072-bdd63e4f2134
https://infogram.com/mcmc-1h0r6rzw0l9ml4e
https://infogram.com/03916-fady-1h0r6rzw0l9ml4e
https://infogram.com/93367-gknu-40519-1h0r6rzw0l9ml4e
https://infogram.com/51fa41d8-d1d5-42fd-8d15-575886e7da8d
https://infogram.com/cdmw-1hmr6g8jedvxo2n
https://infogram.com/59431-uxpk-1hmr6g8jedvxo2n
https://infogram.com/04236-elop-69099-1hmr6g8jedvxo2n
https://infogram.com/3e924a92-f562-4d96-a9f2-c4957b55248d
https://infogram.com/ueuf-1h1749wqkl9mq2z
https://infogram.com/93948-ogai-1h1749wqkl9mq2z
https://infogram.com/52162-wuvx-48326-1h1749wqkl9mq2z
https://infogram.com/c8a539c2-affe-4dbe-bd67-90223b235258
https://infogram.com/dbnw-1h0n25opk811l4p
https://infogram.com/32052-wzej-1h0n25opk811l4p
https://infogram.com/12276-xjpo-79756-1h0n25opk811l4p
https://infogram.com/99962f16-750f-409b-806f-2aa3684c769c
https://infogram.com/vkve-1h9j6q750vlzv4g
https://infogram.com/11617-oimz-1h9j6q750vlzv4g
https://infogram.com/76122-xsww-38073-1h9j6q750vlzv4g
https://infogram.com/1097008a-2be1-4088-a859-13fdff18c135
https://infogram.com/ecey-1h7v4pd03n7zj4k
https://infogram.com/78794-wwgm-1h7v4pd03n7zj4k
https://infogram.com/62098-gkfr-66577-1h7v4pd03n7zj4k
https://infogram.com/59d8d8f6-33bd-44c8-9e50-59b22eb2bd31
https://infogram.com/qzev-1hnq41op5kr7p23
https://infogram.com/46326-itgj-1hnq41op5kr7p23
https://infogram.com/26931-shfo-27062-1hnq41op5kr7p23
https://infogram.com/891f140b-3d02-43df-ac89-d209328a6688
https://infogram.com/qojq-1hxj48mq359m52v
https://infogram.com/61522-kqxu-1hxj48mq359m52v
https://infogram.com/79238-swkj-26575-1hxj48mq359m52v
https://infogram.com/aed91a18-f1af-4737-b2b3-a0b3c3e310ca
https://infogram.com/tter-1h984wv1j3mjz2p
https://infogram.com/75360-mngf-1h984wv1j3mjz2p
https://infogram.com/20502-vbfk-75020-1h984wv1j3mjz2p
https://infogram.com/6cbd4e93-eac3-4a3d-ab54-5363cb38c94c
https://infogram.com/raxk-1h0r6rzw0l73w4e
https://infogram.com/65896-juzy-1h0r6rzw0l73w4e
https://infogram.com/72882-tjyd-14933-1h0r6rzw0l73w4e
https://infogram.com/4053bd90-e122-41d8-96e0-d6fd3dc6aeb1
https://infogram.com/llnu-1hmr6g8jed01z2n
https://infogram.com/95491-dxxh-1hmr6g8jed01z2n
https://infogram.com/34328-ftom-93514-1hmr6g8jed01z2n
https://infogram.com/93b4bb3b-0d43-4043-99f3-45a2d2ff83cc
https://infogram.com/aeoo-1h1749wqklynl2z
https://infogram.com/78921-ugcs-1h1749wqklynl2z
https://infogram.com/29232-cupg-24994-1h1749wqklynl2z
https://infogram.com/5b1e1db0-e52c-46f5-a255-6e9335491387
https://infogram.com/iila-1h0n25opk8nxz4p
https://infogram.com/26890-bgcv-1h0n25opk8nxz4p
https://infogram.com/89768-kqms-22359-1h0n25opk8nxz4p
https://infogram.com/ac328863-29da-4264-b373-a2fa7ac71a24
https://infogram.com/aisi-1h9j6q750vn854g
https://infogram.com/89469-vowu-1h9j6q750vn854g
https://infogram.com/49713-bzca-93476-1h9j6q750vn854g
https://infogram.com/f8cac4b5-c266-4fff-a12c-e2b10f5c5da5
https://infogram.com/donj-1h7v4pd03n1k84k
https://infogram.com/06738-xpun-1h7v4pd03n1k84k
https://infogram.com/47306-fwpb-52921-1h7v4pd03n1k84k
https://infogram.com/50dc6409-3898-4534-8f2e-bce65a489a05
https://infogram.com/nrsr-1hnq41op5kdpk23
https://infogram.com/81918-flue-1hnq41op5kdpk23
https://infogram.com/95344-pztj-91704-1hnq41op5kdpk23
https://infogram.com/6b1e5c8d-34b7-4807-8dac-8dcaa4c41d86
https://infogram.com/gckf-1hnp27eqk3l0n4g
https://infogram.com/60994-ywms-1hnp27eqk3l0n4g
https://infogram.com/30272-aklx-40642-1hnp27eqk3l0n4g
https://infogram.com/7feed570-fbc4-4977-9cc9-7a3eedc3f79d
https://infogram.com/khsk-1hxj48mq359jq2v
https://infogram.com/32779-dfjf-1hxj48mq359jq2v
https://infogram.com/62828-eqtc-09154-1hxj48mq359jq2v
https://infogram.com/a7057000-8451-4f2f-b993-5a8f7668a1d2
https://infogram.com/ajse-1h984wv1j3m7d2p
https://infogram.com/38652-scvr-1h984wv1j3m7d2p
https://infogram.com/23494-bruw-19636-1h984wv1j3m7d2p
https://infogram.com/278ccaf7-1e39-4f26-8cff-62ae70f93762
https://infogram.com/xpwh-1h0r6rzw0l7yl4e
https://infogram.com/86234-svzs-1h0r6rzw0l7yl4e
https://infogram.com/66153-zxxz-97242-1h0r6rzw0l7yl4e
https://infogram.com/c441ef72-fa78-4768-b6b2-b18f9e3f6501
https://infogram.com/htao-1hmr6g8jed0zo2n
https://infogram.com/35574-czds-1hmr6g8jed0zo2n
https://infogram.com/49769-jbch-37215-1hmr6g8jed0zo2n
https://infogram.com/b8fe66b8-8406-402a-a310-625467932b06
https://infogram.com/yccb-1h1749wqkly9q2z
https://infogram.com/22089-seqe-1h1749wqkly9q2z
https://infogram.com/18111-akdt-86602-1h1749wqkly9q2z
https://infogram.com/60bf2212-9f91-481c-9562-25ba118c77d1
https://infogram.com/azro-1h0n25opk8nnl4p
https://infogram.com/14983-vfmz-1h0n25opk8nnl4p
https://infogram.com/93272-chsg-05219-1h0n25opk8nnl4p
https://infogram.com/396f4f69-e125-4c90-add1-da19cc13ce25
https://infogram.com/igbf-1h9j6q750vn1v4g
https://infogram.com/22674-dmeq-1h9j6q750vn1v4g
https://infogram.com/77707-kocx-06962-1h9j6q750vn1v4g
https://infogram.com/5150e343-d78c-4b51-b14e-b78f3689ad62
https://infogram.com/cwxb-1h7v4pd03n1oj4k
https://infogram.com/65195-cqzo-1h7v4pd03n1oj4k
https://infogram.com/67176-dfyt-24825-1h7v4pd03n1oj4k
https://infogram.com/81da98f7-754a-47bd-909a-7a2402912966
https://infogram.com/jshr-1hnq41op5kgkp23
https://infogram.com/62216-eykc-1hnq41op5kgkp23
https://infogram.com/92747-ljij-94140-1hnq41op5kgkp23
https://infogram.com/b60be51b-dac8-4eb4-86ec-2674a0511d27
https://infogram.com/ddfa-1hnp27eqk39my4g
https://infogram.com/93273-vxho-1hnp27eqk39my4g
https://infogram.com/73889-xlgb-93919-1hnp27eqk39my4g
https://infogram.com/39c05750-7fd2-4b03-be58-2064a850a198
https://infogram.com/cycu-1hxj48mq35y352v
https://infogram.com/08023-eajx-1hxj48mq35y352v
https://infogram.com/16591-ehem-83054-1hxj48mq35y352v
https://infogram.com/342d93cd-3f4b-4602-9440-164b886f7ef3
https://infogram.com/wjbe-1h984wv1j3y0z2p
https://infogram.com/26257-qlhh-1h984wv1j3y0z2p
https://infogram.com/95344-yrcw-61635-1h984wv1j3y0z2p
https://infogram.com/0bf045fd-9745-4e41-bd90-94946d728d19
https://infogram.com/uieg-1h0r6rzw0l1ew4e
https://infogram.com/12873-uchu-1h0r6rzw0l1ew4e
https://infogram.com/67679-wqgz-42431-1h0r6rzw0l1ew4e
https://infogram.com/60692554-2a6b-4e8d-8199-a038f4dcd63f
https://infogram.com/bmja-1hmr6g8jed5oz2n
https://infogram.com/98801-wsem-1hmr6g8jed5oz2n
https://infogram.com/75380-dvks-90914-1hmr6g8jed5oz2n
https://infogram.com/de4735c1-121b-4a38-91f1-0e2562ddbf0b
https://infogram.com/bbcr-1h1749wqkledl2z
https://infogram.com/54315-vdiu-1h1749wqkledl2z
https://infogram.com/64120-djdj-19368-1h1749wqkledl2z
https://infogram.com/7abf6442-7f8a-4642-acd3-516e36395a94
https://infogram.com/acjh-1h0n25opk87gz4p
https://infogram.com/14492-uepl-1h0n25opk87gz4p
https://infogram.com/95388-ukkz-60665-1h0n25opk87gz4p
https://infogram.com/742e631b-80b7-4575-a04c-d8a789e06dc3
https://infogram.com/sjczo_otutp
https://infogram.com/wrxbl_sbpvm
https://infogram.com/gupfq_cezzr
https://infogram.com/dbnms_zlxft
https://infogram.com/yomwu_uywqn
https://infogram.com/uhqux_qqaop
https://infogram.com/ropby_nyzvz
https://infogram.com/vvcdw_rfuxx
https://infogram.com/jiesc_fswmv
https://infogram.com/tcakx_pmtey
https://infogram.com/mziq-1h0n25opkx3el4p
https://infogram.com/66354-esle-1h0n25opkx3el4p
https://infogram.com/55460-npkj-55477-1h0n25opkx3el4p
https://infogram.com/273778f4-cc4e-4a24-960a-b4785607795c
https://infogram.com/fjga-1h7v4pd03mjwj4k
https://infogram.com/60409-zlve-1h7v4pd03mjwj4k
https://infogram.com/92378-hris-35256-1h7v4pd03mjwj4k
https://infogram.com/130c49bc-3eaa-413b-ab74-92d74e0be517
https://infogram.com/nqzr-1h9j6q750mjvv4g
https://infogram.com/32838-iwuc-1h9j6q750mjvv4g
https://infogram.com/68809-hgaj-54700-1h9j6q750mjvv4g
https://infogram.com/8eccae1b-26d1-4bfa-a0bd-7e25a485344c
https://infogram.com/nejh-1hnq41op5xnop23
https://infogram.com/53481-ikmt-1hnq41op5xnop23
https://infogram.com/86452-pmla-54142-1hnq41op5xnop23
https://infogram.com/60b0bfba-78db-4842-ab79-0ec697f863c7
https://infogram.com/hhhr-1hxj48mq3rvo52v
https://infogram.com/12256-cnld-1hxj48mq3rvo52v
https://infogram.com/78918-jxjj-35923-1hxj48mq3rvo52v
https://infogram.com/801dc93e-877c-4044-a1ea-d502826fc9c3
https://infogram.com/llio-1h984wv1jxzzz2p
https://infogram.com/64970-dfkc-1h984wv1jxzzz2p
https://infogram.com/81404-mujg-14118-1h984wv1jxzzz2p
https://infogram.com/faa8d8b7-0da1-42e6-86be-60604850a981
https://infogram.com/ssaf-1hnp27eqkxnky4g
https://infogram.com/01991-nyvr-1hnp27eqkxnky4g
https://infogram.com/46017-uabx-04661-1hnp27eqkxnky4g
https://infogram.com/06713fe3-b5a2-4a4e-99b2-b00941fbf559
https://infogram.com/edqp-1h0r6rzw08vxw4e
https://infogram.com/02794-wxac-1h0r6rzw08vxw4e
https://infogram.com/72872-glzh-03242-1h0r6rzw08vxw4e
https://infogram.com/c53e57fc-bab2-4847-b97c-2ce73071eb0f
https://infogram.com/qzrm-1hmr6g8jeyoyz2n
https://infogram.com/16159-jxqh-1hmr6g8jeyoyz2n
https://infogram.com/45189-shae-63437-1hmr6g8jeyoyz2n
https://infogram.com/638ff0c4-00b4-4bb1-9f59-ecd7cd01b2b3
https://infogram.com/kkpv-1h1749wqkd38l2z
https://infogram.com/29529-fqsh-1h1749wqkd38l2z
https://infogram.com/87091-esqo-62006-1h1749wqkd38l2z
https://infogram.com/f5c6fe07-8b90-4913-97a7-5dc8ed42e438
https://infogram.com/rbwf-1h0n25opkxzwz4p
https://infogram.com/23125-kzva-1h0n25opkxzwz4p
https://infogram.com/67373-trfx-39666-1h0n25opkxzwz4p
https://infogram.com/d33e4934-7109-4492-8de0-b5cd3aaceafa
https://infogram.com/afie-1h9j6q750mj554g
https://infogram.com/80110-syls-1h9j6q750mj554g
https://infogram.com/50289-cvkx-69659-1h9j6q750mj554g
https://infogram.com/5c397457-20b9-47ce-9911-5f038f5ca586
https://infogram.com/mqts-1h7v4pd03mjv84k
https://infogram.com/59512-ekvg-1h7v4pd03mjv84k
https://infogram.com/64938-ogul-40597-1h7v4pd03mjv84k
https://infogram.com/9daeb0db-d3ab-410e-8d65-ebd58782dc4c
https://infogram.com/ckjw-1hnq41op5xnmk23
https://infogram.com/31632-viar-1hnq41op5xnmk23
https://infogram.com/41755-esko-68335-1hnq41op5xnmk23
https://infogram.com/42da8a3a-c1b0-4d83-a0a9-b1300f95f2c4
https://infogram.com/fhkt-1hnp27eqkxnrn4g
https://infogram.com/16370-anfe-1hnp27eqkxnrn4g
https://infogram.com/08120-hpll-39520-1hnp27eqkxnrn4g
https://infogram.com/ab97f0f2-415e-4006-bb1d-3bef0f9ffa1e
https://infogram.com/zrak-1hxj48mq3rvgq2v
https://infogram.com/25286-uxdw-1hxj48mq3rvgq2v
https://infogram.com/02003-babd-18179-1hxj48mq3rvgq2v
https://infogram.com/549ea460-024f-45af-b555-00f583675e63
https://infogram.com/hysb-1h984wv1jxzdd2p
https://infogram.com/10282-awjx-1h984wv1jxzdd2p
https://infogram.com/83252-bgtt-18823-1h984wv1jxzdd2p
https://infogram.com/bcdcd08d-e314-4b94-88a9-35ab244a4c13
https://infogram.com/tjql-1h0r6rzw08v7l4e
https://infogram.com/04074-oplw-1h0r6rzw08v7l4e
https://infogram.com/07004-vrrd-17404-1h0r6rzw08v7l4e
https://infogram.com/33f219de-927e-4dc5-9146-bbb99379ec26
https://infogram.com/jvyo-1hmr6g8jeyo5o2n
https://infogram.com/52482-dxns-1hmr6g8jeyo5o2n
https://infogram.com/54642-ldag-37230-1hmr6g8jeyo5o2n
https://infogram.com/4817455b-0a40-4a9e-ba57-a3bab757731b
https://infogram.com/ugwy-1h1749wqkd35q2z
https://infogram.com/72835-oidb-1h1749wqkd35q2z
https://infogram.com/43496-woyq-26010-1h1749wqkd35q2z
https://infogram.com/a695c5a2-9c31-407c-a848-d84e08929af9
https://infogram.com/tude-1h0n25opkxz5l4p
https://infogram.com/23312-lofr-1h0n25opkxz5l4p
https://infogram.com/59533-ncee-54970-1h0n25opkxz5l4p
https://infogram.com/97f0d73e-7009-4131-852b-faacc53cda36
https://infogram.com/zyfb-1h9j6q750mxgv4g
https://infogram.com/98692-tatf-1h9j6q750mxgv4g
https://infogram.com/47906-bpgu-35040-1h9j6q750mxgv4g
https://infogram.com/11bd7fdb-f91d-4e72-8341-b030956d7699
https://infogram.com/nred-1h7v4pd03mxdj4k
https://infogram.com/68231-htkh-1h7v4pd03mxdj4k
https://infogram.com/14964-pafw-53626-1h7v4pd03mxdj4k
https://infogram.com/b1e1580d-2f10-4a62-94e4-ca5eaef95c7c
https://infogram.com/oiaa-1hnq41op5xq5p23
https://infogram.com/78732-ikgd-1hnq41op5xq5p23
https://infogram.com/98674-qqbs-42699-1hnq41op5xq5p23
https://infogram.com/dc4262a5-6684-424b-b962-b4a6ea003dbc
https://infogram.com/wvid-1hnp27eqkxz5y4g
https://infogram.com/78160-qxwh-1hnp27eqkxz5y4g
https://infogram.com/51778-ydjv-83427-1hnp27eqkxz5y4g
https://infogram.com/84f1677f-b419-4063-88d4-56714f598f47
https://infogram.com/mpyg-1hxj48mq3r1v52v
https://infogram.com/74752-fnqc-1hxj48mq3r1v52v
https://infogram.com/74202-oxaz-01455-1hxj48mq3r1v52v
https://infogram.com/06b191f4-091e-4945-a705-09d48a83b17a
https://infogram.com/ymzd-1h984wv1jxppz2p
https://infogram.com/59412-tsup-1h984wv1jxppz2p
https://infogram.com/70827-suaw-82642-1h984wv1jxppz2p
https://infogram.com/2acc7908-d182-400c-bf25-fb33d3efbfd4
https://infogram.com/kwpn-1h0r6rzw08x8w4e
https://infogram.com/68318-fcsz-1h0r6rzw08x8w4e
https://infogram.com/47133-lfyf-61221-1h0r6rzw08x8w4e
https://infogram.com/2249d983-a7bd-4a2b-af33-f297ab2e5982
https://infogram.com/zjfr-1hmr6g8jeyklz2n
https://infogram.com/44128-shwm-1hmr6g8jeyklz2n
https://infogram.com/59032-trgj-71359-1hmr6g8jeyklz2n
https://infogram.com/1517c902-b99e-41ce-841e-9b55b92bf20b
https://infogram.com/heiy-1h1749wqkdnrl2z
https://infogram.com/00371-zykl-1h1749wqkdnrl2z
https://infogram.com/96192-jmjq-90354-1h1749wqkdnrl2z
https://infogram.com/de5d6ef6-8656-48f1-8d3c-261b30b8351a
https://infogram.com/mgju-1h0n25opkxdpz4p
https://infogram.com/85103-gipy-1h0n25opkxdpz4p
https://infogram.com/31635-opkm-68397-1h0n25opkxdpz4p
https://infogram.com/deb70618-fb6a-4a0b-ae4d-5182e851b549
https://infogram.com/qdev-1h9j6q750mxo54g
https://infogram.com/16227-tjzh-1h9j6q750mxo54g
https://infogram.com/25725-sufo-27642-1h9j6q750mxo54g
https://infogram.com/dd6f39d8-62d4-43c1-878a-3554f36cbeb3
https://infogram.com/kouf-1h7v4pd03mxq84k
https://infogram.com/42158-eqij-1h7v4pd03mxq84k
https://infogram.com/15706-mwvx-08221-1h7v4pd03mxq84k
https://infogram.com/af738d50-4a48-43e8-95f5-bf3519e22c71
https://infogram.com/lmvw-1hnq41op5xqek23
https://infogram.com/33944-foja-1hnq41op5xqek23
https://infogram.com/41312-ncwp-98997-1hnq41op5xqek23
https://infogram.com/37f379ee-4a51-460a-8339-11606d77f74b
https://infogram.com/xwtg-1hnp27eqkxzdn4g
https://infogram.com/78333-qukb-1hnp27eqkxzdn4g
https://infogram.com/03024-zfuy-96778-1hnp27eqkxzdn4g
https://infogram.com/b93f78e0-698f-453b-8870-a6750fdcee6e
https://infogram.com/jttd-1hxj48mq3r1eq2v
https://infogram.com/08465-crlz-1hxj48mq3r1eq2v
https://infogram.com/49952-lbvd-57963-1hxj48mq3r1eq2v
https://infogram.com/6f2038ae-9e4f-4cab-93b7-ffae61abd0f4
https://infogram.com/qowt-1h984wv1jxpkd2p
https://infogram.com/76055-iiyg-1h984wv1jxpkd2p
https://infogram.com/60360-swyl-66849-1h984wv1jxpkd2p
https://infogram.com/57e60dbc-127b-4867-a0b6-088b63018769
https://infogram.com/ycpj-1h0r6rzw08x1l4e
https://infogram.com/49379-ragf-1h0r6rzw08x1l4e
https://infogram.com/71848-alqc-65482-1h0r6rzw08x1l4e
https://infogram.com/6d509a03-2f03-472a-a548-347dd42f8cf9
https://infogram.com/qdws-1hmr6g8jeykqo2n
https://infogram.com/33480-ljzd-1hmr6g8jeykqo2n
https://infogram.com/34302-smxk-45810-1hmr6g8jeykqo2n
https://infogram.com/86fe30d6-bd4a-4152-9b18-28523d9ddad0
https://infogram.com/tjex-1h1749wqkdnpq2z
https://infogram.com/72994-ophi-1h1749wqkdnpq2z
https://infogram.com/74061-vzfp-73124-1h1749wqkdnpq2z
https://infogram.com/fd46d8c8-a3c7-46cf-94a6-26a0c4774b36
https://infogram.com/nipb-1h0n25opkxx8l4p
https://infogram.com/83862-fcrp-1h0n25opkxx8l4p
https://infogram.com/41797-prqu-53406-1h0n25opkxx8l4p
https://infogram.com/17ceed3c-d3b5-46cb-b5fd-00f237e3a007
https://infogram.com/zlfl-1h9j6q750mm7v4g
https://infogram.com/92363-rfhy-1h9j6q750mm7v4g
https://infogram.com/96315-btgd-53085-1h9j6q750mm7v4g
https://infogram.com/8992b040-64be-4b49-994b-fadbe88ad560
https://infogram.com/swxh-1hnq41op5xx9p23
https://infogram.com/51529-kqau-1hnq41op5xx9p23
https://infogram.com/84078-mezz-02904-1hnq41op5xx9p23
https://infogram.com/517b0ecd-1f29-4147-93c8-764acff260ed
https://infogram.com/argk-1hxj48mq3rr152v
https://infogram.com/49171-vxjw-1hxj48mq3rr152v
https://infogram.com/63505-czhc-41731-1hxj48mq3rr152v
https://infogram.com/b598b0ae-2e10-4327-887f-a411c101e7e0
https://infogram.com/wcfm-1h984wv1jxxxz2p
https://infogram.com/19503-riiy-1h984wv1jxxxz2p
https://infogram.com/41935-qsge-62318-1h984wv1jxxxz2p
https://infogram.com/7cfcec13-0e41-440c-8f99-938035855122
https://infogram.com/sbcb-1h0r6rzw088rw4e
https://infogram.com/46345-mdie-1h0r6rzw088rw4e
https://infogram.com/10543-tjdt-71486-1h0r6rzw088rw4e
https://infogram.com/fb110828-5c61-490e-8c01-dc199e90ac13
https://infogram.com/hcdv-1h1749wqkddql2z
https://infogram.com/55815-bejy-1h1749wqkddql2z
https://infogram.com/73620-jken-10968-1h1749wqkddql2z
https://infogram.com/3dbdb55e-c2d6-4d12-bfab-36b757ede45d
https://infogram.com/rfhv-1h7v4pd03mm584k
https://infogram.com/37273-mlkg-1h7v4pd03mm584k
https://infogram.com/44150-tnin-59961-1h7v4pd03mm584k
https://infogram.com/13c42ef5-95c5-4a9c-b7ad-49705deece29
https://infogram.com/kqfe-1hnq41op5xx8k23
https://infogram.com/44325-fkli-1hnq41op5xx8k23
https://infogram.com/91877-eygw-28539-1hnq41op5xx8k23
https://infogram.com/881115dd-9c9a-4ce9-9d3c-422694683ed5
https://infogram.com/onan-1hnp27eqkxxyn4g
https://infogram.com/93679-ipgr-1hnp27eqkxxyn4g
https://infogram.com/30547-qdbg-89864-1hnp27eqkxxyn4g
https://infogram.com/cc8d8028-c334-4562-9f3a-05c900c10f5a
https://infogram.com/muqu-1hxj48mq3rrlq2v
https://infogram.com/58854-eobi-1hxj48mq3rrlq2v
https://infogram.com/42496-ocsm-48630-1hxj48mq3rrlq2v
https://infogram.com/8438de3c-97f2-4a8d-b9ea-224cb7d52e81
https://infogram.com/htoj-1h984wv1jxxmd2p
https://infogram.com/28214-znqw-1h984wv1jxxmd2p
https://infogram.com/59655-jbpb-77708-1h984wv1jxxmd2p
https://infogram.com/15edab78-21d9-4204-80dd-20be8d6fb70f
https://infogram.com/tyik-1h0r6rzw088nl4e
https://infogram.com/22968-napn-1h0r6rzw088nl4e
https://infogram.com/57460-ngkc-16053-1h0r6rzw088nl4e
https://infogram.com/ab454a98-cd2e-4623-91cb-abfba519fd45
https://infogram.com/nheg-1hmr6g8jeyypo2n
https://infogram.com/20769-hilk-1hmr6g8jeyypo2n
https://infogram.com/05783-pxgy-35018-1hmr6g8jeyypo2n
https://infogram.com/5a6f054a-07aa-4096-a5d9-2ef2d8c98392
https://infogram.com/fpmo-1h1749wqkd7lq2z
https://infogram.com/41966-zrss-1h1749wqkd7lq2z
https://infogram.com/90943-gynh-16335-1h1749wqkd7lq2z
https://infogram.com/459b17d7-863e-406e-9ed9-b96d2d0a74e2
https://infogram.com/ailq-1h0n25opkxgyl4p
https://infogram.com/93713-vogc-1h0n25opkxgyl4p
https://infogram.com/41898-crmj-04911-1h0n25opkxgyl4p
https://infogram.com/a4783349-00f0-4c84-b54d-6a895c510533
https://infogram.com/kmpy-1h9j6q750m80v4g
https://infogram.com/89969-eovc-1h9j6q750m80v4g
https://infogram.com/87337-muqq-44992-1h9j6q750m80v4g
https://infogram.com/ce1cbe47-eb2e-49bc-87b3-7c2151ff1889
https://infogram.com/znqs-1hnq41op5xl3p23
https://infogram.com/18321-tpww-1hnq41op5xl3p23
https://infogram.com/38156-bvrk-73374-1hnq41op5xl3p23
https://infogram.com/6aa7cdc4-937d-4c2f-b160-b5a8fb1690cf
https://infogram.com/ljqp-1hnp27eqkx1ny4g
https://infogram.com/40045-gplb-1hnp27eqkx1ny4g
https://infogram.com/51541-fsrh-33668-1hnp27eqkx1ny4g
https://infogram.com/f7b01bfe-60b3-45d1-932f-bc501002df0f
https://infogram.com/bkwf-1hxj48mq3rnr52v
https://infogram.com/81883-wqzr-1hxj48mq3rnr52v
https://infogram.com/58901-dsxx-92080-1hxj48mq3rnr52v
https://infogram.com/faf4ac30-94d1-4983-ab53-35466347410a
https://infogram.com/jrow-1h984wv1jxnnz2p
https://infogram.com/19446-ewki-1h984wv1jxnnz2p
https://infogram.com/73806-lzqo-93434-1h984wv1jxnnz2p
https://infogram.com/8c97829d-3767-456b-825b-4ee91b799840
https://infogram.com/ivtq-1h0r6rzw08rkw4e
https://infogram.com/00275-apvd-1h0r6rzw08rkw4e
https://infogram.com/47662-kdui-61917-1h0r6rzw08rkw4e
https://infogram.com/f3caddb6-0790-496c-8c12-0e323578a2a8
https://infogram.com/cmcy-1hmr6g8jeylgz2n
https://infogram.com/50551-ugem-1hmr6g8jeylgz2n
https://infogram.com/05714-eudr-60119-1hmr6g8jeylgz2n
https://infogram.com/77e0cb7b-4019-49d5-b961-a7ad96fda712
https://infogram.com/rhsc-1h1749wqkd70l2z
https://infogram.com/15437-lbyf-1h1749wqkd70l2z
https://infogram.com/31480-tptu-79057-1h1749wqkd70l2z
https://infogram.com/eaf1a429-12fa-456e-93e0-6a9341bee181
https://infogram.com/xugv-1h0n25opkxgjz4p
https://infogram.com/77111-sajh-1h0n25opkxgjz4p
https://infogram.com/31254-zchn-58207-1h0n25opkxgjz4p
https://infogram.com/46e88dc1-2303-4aa3-87e9-1e3bfa4e36f6
https://infogram.com/lffx-1h9j6q750m8r54g
https://infogram.com/38951-dzik-1h9j6q750m8r54g
https://infogram.com/02022-nnhp-79783-1h9j6q750m8r54g
https://infogram.com/522370b4-01a0-4afa-bd26-1b041f00c324
https://infogram.com/xjgu-1h7v4pd03mey84k
https://infogram.com/80793-qhxp-1h7v4pd03mey84k
https://infogram.com/22189-yshm-37178-1h7v4pd03mey84k
https://infogram.com/2776d562-4b11-46d2-aa69-c88854b77dbe
https://infogram.com/aggr-1hnq41op5xlzk23
https://infogram.com/61987-texn-1hnq41op5xlzk23
https://infogram.com/00374-cohj-08465-1hnq41op5xlzk23
https://infogram.com/1bd7c55c-12d7-44d7-b342-2411fec7506d
https://infogram.com/mlbs-1hnp27eqkx17n4g
https://infogram.com/25022-hrwe-1hnp27eqkx17n4g
https://infogram.com/32909-gtck-47717-1hnp27eqkx17n4g
https://infogram.com/87884107-e4a3-4fc7-883c-204bf1d67b55
https://infogram.com/uyjw-1h984wv1jxnyd2p
https://infogram.com/84885-pemh-1h984wv1jxnyd2p
https://infogram.com/10856-wolw-86555-1h984wv1jxnyd2p
https://infogram.com/d1da9c88-8029-4da6-8aac-00107d58921c
https://infogram.com/kszh-1h0r6rzw08rjl4e
https://infogram.com/84896-fyvt-1h0r6rzw08rjl4e
https://infogram.com/91054-mabz-06563-1h0r6rzw08rjl4e
https://infogram.com/8cb6b9ed-e99c-4d89-9ef9-ac419c963e94
https://infogram.com/rncp-1hmr6g8jey9do2n
https://infogram.com/71202-lpis-1hmr6g8jey9do2n
https://infogram.com/49279-tveh-15651-1hmr6g8jey9do2n
https://infogram.com/43c79ccc-e4f7-416f-b51a-60d02ea7187d
https://infogram.com/jxrf-1h1749wqkd8vq2z
https://infogram.com/28402-cvqa-1h1749wqkd8vq2z
https://infogram.com/38280-dfsx-55005-1h1749wqkd8vq2z
https://infogram.com/cd0e1d09-c0a6-4bbc-a01f-ff8db44b3dc9
https://infogram.com/qhhh-1h0n25opkx9ol4p
https://infogram.com/65353-jfyd-1h0n25opkx9ol4p
https://infogram.com/18186-spia-63804-1h0n25opkx9ol4p
https://infogram.com/2115924d-2371-41d4-8744-e6f8d2041a84
https://infogram.com/yory-1h9j6q750mwyv4g
https://infogram.com/66797-rmiu-1h9j6q750mwyv4g
https://infogram.com/29965-awsq-64358-1h9j6q750mwyv4g
https://infogram.com/b021d23b-3e73-4576-ad41-69f3c117e3e8
https://infogram.com/btmh-1h7v4pd03mkpj4k
https://infogram.com/22560-unov-1h7v4pd03mkpj4k
https://infogram.com/63696-dbnz-13880-1h7v4pd03mkpj4k
https://infogram.com/a5639fd4-1c21-4f65-9aac-438b8a61762a
https://infogram.com/fyhi-1hnq41op5x1np23
https://infogram.com/45432-ywye-1hnq41op5x1np23
https://infogram.com/45902-hgib-72135-1hnq41op5x1np23
https://infogram.com/a659f720-87d5-485c-ae92-50722536048b
https://infogram.com/zaxs-1hnp27eqkxpzy4g
https://infogram.com/13776-sywo-1hnp27eqkxpzy4g
https://infogram.com/40036-bryk-52716-1hnp27eqkxpzy4g
https://infogram.com/652c7c37-b7ab-42bf-a076-ebb66e7ba33d
https://infogram.com/dfxp-1hxj48mq3r8n52v
https://infogram.com/09903-ylbb-1hxj48mq3r8n52v
https://infogram.com/77820-fnzh-31901-1hxj48mq3r8n52v
https://infogram.com/036b7b8e-305d-4e75-ad14-b970c303f480
https://infogram.com/trot-1h0r6rzw08kgw4e
https://infogram.com/76181-ntuw-1h0r6rzw08kgw4e
https://infogram.com/78129-uipl-52949-1h0r6rzw08kgw4e
https://infogram.com/416297e7-03f5-449f-8f78-33131eeeb222
https://infogram.com/ewoq-1hmr6g8jey9jz2n
https://infogram.com/63758-xufl-1hmr6g8jey9jz2n
https://infogram.com/04135-yepi-00233-1hmr6g8jey9jz2n
https://infogram.com/8bc05740-1ccb-4cba-b943-0cc3c9077857
https://infogram.com/ibbr-1h1749wqkd8jl2z
https://infogram.com/04435-cdpu-1h1749wqkd8jl2z
https://infogram.com/44824-kjcj-69588-1h1749wqkd8jl2z
https://infogram.com/5b925e5e-e316-4cba-8a84-406d3037fb10
https://infogram.com/vvpb-1h0n25opkx9rz4p
https://infogram.com/74338-pxwe-1h0n25opkx9rz4p
https://infogram.com/82806-pdrb-59361-1h0n25opkx9rz4p
https://infogram.com/5d293d48-c64a-439e-bde7-44912db6ba7e
https://infogram.com/hvfs-1h9j6q750mwe54g
https://infogram.com/04582-cbid-1h9j6q750mwe54g
https://infogram.com/08314-jdhk-17711-1h9j6q750mwe54g
https://infogram.com/f47c62d6-18e9-4b72-ad30-1c9fe3e9978e
https://infogram.com/bydb-1h7v4pd03mkl84k
https://infogram.com/97269-trgp-1h7v4pd03mkl84k
https://infogram.com/38296-ugfu-88382-1h7v4pd03mkl84k
https://infogram.com/847b9248-bae3-4414-a826-57410559ea8b
https://infogram.com/orxh-1hnq41op5x1rk23
https://infogram.com/46069-glav-1hnq41op5x1rk23
https://infogram.com/64312-izza-87126-1hnq41op5x1rk23
https://infogram.com/bb60a0f6-c72c-4923-96d9-8c5ebde4fde1
https://infogram.com/esdx-1hnp27eqkxpln4g
https://infogram.com/96281-wlgl-1hnp27eqkxpln4g
https://infogram.com/13714-iijg-46548-1hnp27eqkxpln4g
https://infogram.com/8c7f556c-b643-4408-a4a1-468f00919042
https://infogram.com/yubh-1hxj48mq3r8yq2v
https://infogram.com/18668-rstc-1hxj48mq3r8yq2v
https://infogram.com/72291-scdz-26129-1hxj48mq3r8yq2v
https://infogram.com/4d66d1b3-9aaa-4a51-90de-274796b2aa64
https://infogram.com/bzce-1h984wv1jx8ed2p
https://infogram.com/92964-wfxq-1h984wv1jx8ed2p
https://infogram.com/95252-dhdw-95314-1h984wv1jx8ed2p
https://infogram.com/988d5f9f-5da0-4ac8-a56e-3cc94cf458f4
https://infogram.com/rlkh-1h0r6rzw08gll4e
https://infogram.com/78292-kjjd-1h0r6rzw08gll4e
https://infogram.com/93125-tuli-15222-1h0r6rzw08gll4e
https://infogram.com/03144fbe-9e4b-4adf-88b5-39597dd5e8df
https://infogram.com/fejr-1hmr6g8jeyg7o2n
https://infogram.com/33066-akmd-1hmr6g8jeyg7o2n
https://infogram.com/56779-hmlk-34706-1hmr6g8jeyg7o2n
https://infogram.com/067a4b3c-1534-4659-b079-33b3c7879cae
https://infogram.com/bxjt-1h1749wqkdrwq2z
https://infogram.com/35161-trlh-1h1749wqkdrwq2z
https://infogram.com/74196-vfkm-53482-1h1749wqkdrwq2z
https://infogram.com/153d210b-22f8-430d-a30e-2f05e5ab7957
https://infogram.com/izes-1h9j6q750mdpv4g
https://infogram.com/40602-dfzd-1h9j6q750mdpv4g
https://infogram.com/43861-khfk-63022-1h9j6q750mdpv4g
https://infogram.com/f1bd03b3-35f1-4e0c-bf8b-3df900d32584
https://infogram.com/mybg-1h7v4pd03mrjj4k
https://infogram.com/12250-esdt-1h7v4pd03mrjj4k
https://infogram.com/60645-ogcy-82992-1h7v4pd03mrjj4k
https://infogram.com/3840d0ee-e776-4f3f-a74c-458375a4529d
https://infogram.com/lntf-1hnq41op5xwqp23
https://infogram.com/16495-fphj-1hnq41op5xwqp23
https://infogram.com/55462-fvux-51663-1hnq41op5xwqp23
https://infogram.com/5e095978-ce13-4188-9075-648f67cc5a35
https://infogram.com/lulw-1hnp27eqkxvxy4g
https://infogram.com/10463-donj-1hnp27eqkxvxy4g
https://infogram.com/68398-ncmo-72315-1hnp27eqkxvxy4g
https://infogram.com/1a735b5c-22b2-4687-a445-4bb80b742628
https://infogram.com/fejnj_bothc
https://infogram.com/rhhx-1hxj48mq3rw852v
https://infogram.com/43006-kfzt-1hxj48mq3rw852v
https://infogram.com/96174-tpjp-51545-1hxj48mq3rw852v
https://infogram.com/01894eee-6597-44d2-86c2-1f71ec3f4328
https://infogram.com/oiirz_kssls
https://infogram.com/attf-1h984wv1jxllz2p
https://infogram.com/00628-snvs-1h984wv1jxllz2p
https://infogram.com/17151-cbux-49865-1h984wv1jxllz2p
https://infogram.com/cc9faa1c-8b0c-4d7c-b17f-a219d151beec
https://infogram.com/igjj-1h0r6rzw08gww4e
https://infogram.com/14182-cipm-1h0r6rzw08gww4e
https://infogram.com/10136-kwkb-88793-1h0r6rzw08gww4e
https://infogram.com/77305196-52af-4d5e-a1f2-5c52387e804e
https://infogram.com/qfuay_mpmur
https://infogram.com/bruwg_xbmqz
https://infogram.com/vhqt-1hmr6g8jeygmz2n
https://infogram.com/50045-ofho-1hmr6g8jeygmz2n
https://infogram.com/23115-xqrl-58506-1hmr6g8jeygmz2n
https://infogram.com/3f39f4c6-e393-4623-bde4-1379affc9d1d
https://infogram.com/luyw-1h1749wqkdr1l2z
https://infogram.com/47602-doaj-1h1749wqkdr1l2z
https://infogram.com/09753-fkzo-78334-1h1749wqkdr1l2z
https://infogram.com/618dbeca-8f4d-4ef6-befa-16746e100df8
https://infogram.com/jbchn_fluag
https://infogram.com/htqx-1h0n25opkxwvz4p
https://infogram.com/04574-czli-1h0n25opkxwvz4p
https://infogram.com/78924-akrp-16542-1h0n25opkxwvz4p
https://infogram.com/3ce1c3aa-1820-4e35-a3a3-5b1a429130ad
https://infogram.com/seog-1h7v4pd03mr884k
https://infogram.com/79855-lcfc-1h7v4pd03mr884k
https://infogram.com/55390-umpz-86111-1h7v4pd03mr884k
https://infogram.com/9750b16d-1b80-4cc3-936d-02e516e2b1cc
https://infogram.com/qfuw-1hnq41op5xwdk23
https://infogram.com/37559-irwk-1hnq41op5xwdk23
https://infogram.com/11054-knvp-25535-1hnq41op5xwdk23
https://infogram.com/3b5db484-9156-41ec-ac7a-761313c536c5
https://infogram.com/wkvm-1hnp27eqkxv9n4g
https://infogram.com/08592-pimh-1hnp27eqkxv9n4g
https://infogram.com/12406-ysxe-26735-1hnp27eqkxv9n4g
https://infogram.com/ae754fda-789a-4b8b-a4ad-220b7aa426dd
https://infogram.com/pqdl-1hxj48mq3rwkq2v
https://infogram.com/50351-jskp-1hxj48mq3rwkq2v
https://infogram.com/28149-ryfd-94729-1hxj48mq3rwkq2v
https://infogram.com/2b607485-0b83-4bee-a3ed-d98a0803a11e
https://infogram.com/nxca-1h0r6rzw08wpl4e
https://infogram.com/92080-fren-1h0r6rzw08wpl4e
https://infogram.com/55561-ogds-53675-1h0r6rzw08wpl4e
https://infogram.com/7ad1dff4-fa28-4a99-ba9a-51cf25f0632c
https://infogram.com/yccx-1h984wv1jxl9d2p
https://infogram.com/22113-qwek-1h984wv1jxl9d2p
https://infogram.com/94490-akdp-02860-1h984wv1jxl9d2p
https://infogram.com/baf4c8dc-d7aa-44b4-995e-b4fb40c98b11
https://infogram.com/gpka-1h1749wqkdqkq2z
https://infogram.com/55278-zmkw-1h1749wqkdqkq2z
https://infogram.com/42611-ixms-43697-1h1749wqkdqkq2z
https://infogram.com/a2b528ba-15df-4095-9aa4-817f9bfa91e1
https://infogram.com/ubmq-1h0n25opkxpml4p
https://infogram.com/03674-nzll-1h0n25opkxpml4p
https://infogram.com/18561-wkni-21898-1h0n25opkxpml4p
https://infogram.com/51ede4f0-e111-402e-9ae8-6a49d7bfc447
https://infogram.com/hvba-1h9j6q750m5jv4g
https://infogram.com/30049-zpdn-1h9j6q750m5jv4g
https://infogram.com/88974-bdcs-11691-1h9j6q750m5jv4g
https://infogram.com/c1cc216a-f653-495c-b89c-db4bcb32b0aa
https://infogram.com/xlgp-1hnq41op5xpxp23
https://infogram.com/51245-qjxk-1hnq41op5xpxp23
https://infogram.com/31341-zthh-39884-1hnq41op5xpxp23
https://infogram.com/9cd5ec15-6352-4810-9aac-a6172c667d38
https://infogram.com/myoa-1hnp27eqkxq1y4g
https://infogram.com/21999-fwgv-1hnp27eqkxq1y4g
https://infogram.com/23907-goqs-40692-1hnp27eqkxq1y4g
https://infogram.com/9d218a28-5a6e-4270-8f70-1c99bc72c7f0
https://infogram.com/kfsd-1hxj48mq3rqw52v
https://infogram.com/18830-czuq-1hxj48mq3rqw52v
https://infogram.com/64866-mntv-29408-1hxj48mq3rqw52v
https://infogram.com/e47f9d08-cd70-4d7d-8c10-fe4879e3d400
https://infogram.com/savk-1h984wv1jx11z2p
https://infogram.com/47473-kufy-1h984wv1jx11z2p
https://infogram.com/78062-uiec-48596-1h984wv1jx11z2p
https://infogram.com/7f56b0c6-4a95-411f-abec-b77f3b7b1ec4
https://infogram.com/otum-1h0r6rzw08wow4e
https://infogram.com/48959-gexz-1h0r6rzw08wow4e
https://infogram.com/57064-hbwe-37070-1h0r6rzw08wow4e
https://infogram.com/06ed2e0f-64ed-459d-b358-81af4c5ac538
https://infogram.com/lhyo-1hmr6g8jeyj3z2n
https://infogram.com/84407-gnbz-1hmr6g8jeyj3z2n
https://infogram.com/85150-npzg-97657-1hmr6g8jeyj3z2n
https://infogram.com/52c764fa-0faa-4f52-92af-525918550d62
https://infogram.com/bbor-1h1749wqkdqgl2z
https://infogram.com/05027-tvqe-1h1749wqkdqgl2z
https://infogram.com/51160-vkpj-15685-1h1749wqkdqgl2z
https://infogram.com/b4d9b8b8-6c6c-4383-8f76-f402264e9786
https://infogram.com/mntr-1h9j6q750m5k54g
https://infogram.com/72471-htpd-1h9j6q750m5k54g
https://infogram.com/59295-gvvj-85563-1h9j6q750m5k54g
https://infogram.com/1e13f8f6-b64c-46c7-81f1-fb587b109979
https://infogram.com/okna-1h7v4pd03m0784k
https://infogram.com/77219-hiev-1h7v4pd03m0784k
https://infogram.com/79780-qsos-04912-1h7v4pd03m0784k
https://infogram.com/e5ff3bf1-e520-45ce-80df-950ffc8b26df
https://infogram.com/rhab-1hnq41op5xpgk23
https://infogram.com/57626-lfrx-1hnq41op5xpgk23
https://infogram.com/10559-txbt-55267-1hnq41op5xpgk23
https://infogram.com/2b63a339-e57e-45b9-8584-add492ca2493
https://infogram.com/hqvz-1hnp27eqkxq8n4g
https://infogram.com/99158-bsbd-1hnp27eqkxq8n4g
https://infogram.com/39218-jyxs-72906-1hnp27eqkxq8n4g
https://infogram.com/8b4db144-5d8d-431e-93a9-d6a3438c73f6
https://infogram.com/jzrw-1hxj48mq3rqxq2v
https://infogram.com/45735-cxir-1hxj48mq3rqxq2v
https://infogram.com/77989-dhso-93971-1hxj48mq3rqxq2v
https://infogram.com/86b773d3-92fa-4929-a9de-f225c1262284
https://infogram.com/ukck-1h984wv1jxw3d2p
https://infogram.com/62061-meex-1h984wv1jxw3d2p
https://infogram.com/42777-wsdc-42800-1h984wv1jxw3d2p
https://infogram.com/0162dec9-345e-499c-af70-71141e49b7f3
https://infogram.com/ssvc-1hmr6g8jeymeo2n
https://infogram.com/89820-nyqo-1hmr6g8jeymeo2n
https://infogram.com/66645-miwv-02713-1hmr6g8jeymeo2n
https://infogram.com/84793eae-6962-4798-b5c9-663bd5a97008
https://infogram.com/ljed-1h1749wqkd0xq2z
https://infogram.com/97750-gpzo-1h1749wqkd0xq2z
https://infogram.com/52883-nzfv-71946-1h1749wqkd0xq2z
https://infogram.com/6ddb034d-a769-4a0f-926c-4803b14c1005
https://infogram.com/tdmg-1h0n25opkx03l4p
https://infogram.com/05427-nfak-1h0n25opkx03l4p
https://infogram.com/08124-vmny-10774-1h0n25opkx03l4p
https://infogram.com/878360ea-0e61-4de3-bc79-d9d4aff8a56e
https://infogram.com/hxgm-1h9j6q750moxv4g
https://infogram.com/92252-avxi-1h9j6q750moxv4g
https://infogram.com/47656-jfhe-19518-1h9j6q750moxv4g
https://infogram.com/264f7573-3c9e-40d1-b8e7-8ba59f9fa1a8
https://infogram.com/bzew-1h7v4pd03mvmj4k
https://infogram.com/62053-uxvr-1h7v4pd03mvmj4k
https://infogram.com/04544-cqfo-99198-1h7v4pd03mvmj4k
https://infogram.com/75a0383f-c924-4c21-8033-cccae76d2973
https://infogram.com/ugrz-1hnq41op5xylp23
https://infogram.com/85010-plvl-1hnq41op5xylp23
https://infogram.com/82171-wobr-88903-1hnq41op5xylp23
https://infogram.com/69b6e885-ee22-4e0d-8da7-5aad1c9a5b40
https://infogram.com/cveu-1hnp27eqkx0py4g
https://infogram.com/89097-vswq-1hnp27eqkx0py4g
https://infogram.com/68391-vdgm-57616-1hnp27eqkx0py4g
https://infogram.com/66c0f644-16bb-4eaa-8622-99d5d6adb877
https://infogram.com/frfr-1hxj48mq3r0q52v
https://infogram.com/96864-xlhf-1hxj48mq3r0q52v
https://infogram.com/15197-hhgj-37801-1hxj48mq3r0q52v
https://infogram.com/36000365-f76a-4574-876d-bd3897a93100
https://infogram.com/pujr-1h0r6rzw08oqw4e
https://infogram.com/86818-hole-1h0r6rzw08oqw4e
https://infogram.com/91244-rlkj-76904-1h0r6rzw08oqw4e
https://infogram.com/c12e7c89-511e-44f7-befb-ec3994e39d98
https://infogram.com/rlfn-1hmr6g8jeymnz2n
https://infogram.com/94871-mraz-1hmr6g8jeymnz2n
https://infogram.com/38656-ttgf-75867-1hmr6g8jeymnz2n
https://infogram.com/8e75b371-da49-4b58-817a-ac2cac2fd55f
https://infogram.com/yvnq-1h1749wqkd0zl2z
https://infogram.com/67532-rtel-1h1749wqkd0zl2z
https://infogram.com/89784-adoi-83666-1h1749wqkd0zl2z
https://infogram.com/b121a49f-10b8-4931-bcfe-be34de9beb64
https://infogram.com/uvwq-1h0n25opkx0lz4p
https://infogram.com/56398-nsom-1h0n25opkx0lz4p
https://infogram.com/07122-vdyi-93674-1h0n25opkx0lz4p
https://infogram.com/cd97597d-7a3c-42a0-b376-ce1ba6b808a5
https://infogram.com/rnkg-1h9j6q750mol54g
https://infogram.com/31866-mtgs-1h9j6q750mol54g
https://infogram.com/32935-tvmy-33096-1h9j6q750mol54g
https://infogram.com/e351b569-36dc-4db7-a116-cdbe002f4923
https://infogram.com/hoqw-1hnq41op5xyvk23
https://infogram.com/04216-amis-1hnq41op5xyvk23
https://infogram.com/33573-jwso-92418-1hnq41op5xyvk23
https://infogram.com/a4f55a54-04db-44a5-a089-4ae5af538774
https://infogram.com/bqog-1hnp27eqkx0wn4g
https://infogram.com/01377-tkrt-1hnp27eqkx0wn4g
https://infogram.com/59842-dzqy-73099-1hnp27eqkx0wn4g
https://infogram.com/771eca13-e51f-418b-ada3-3fd7d6d24841
https://infogram.com/auzw-1hxj48mq3rj5q2v
https://infogram.com/59304-vach-1hxj48mq3rj5q2v
https://infogram.com/17322-cdao-61413-1hxj48mq3rj5q2v
https://infogram.com/e49e1d98-940f-49c8-8862-41b53163986e
https://infogram.com/ozal-1h984wv1jxgod2p
https://infogram.com/05235-ibgo-1h984wv1jxgod2p
https://infogram.com/43102-qqbd-49604-1h984wv1jxgod2p
https://infogram.com/fda34582-0cc5-4629-90c0-c9c6e6cec67a
https://infogram.com/djvr-1h0r6rzw08q0l4e
https://infogram.com/75038-xlcv-1h0r6rzw08q0l4e
https://infogram.com/00806-xrxj-59123-1h0r6rzw08q0l4e
https://infogram.com/98ff8b69-ed3e-4ed5-ab29-f28b72a1786b
https://infogram.com/bizu-1h1749wqkdjoq2z
https://infogram.com/91791-ugqp-1h1749wqkdjoq2z
https://infogram.com/47824-dyam-30939-1h1749wqkdjoq2z
https://infogram.com/8c3f4794-c5f8-4ef0-b7e2-b342ab5c0ae5
https://infogram.com/vsxd-1h0n25opkxjzl4p
https://infogram.com/90496-oqoz-1h0n25opkxjzl4p
https://infogram.com/25865-pazw-18500-1h0n25opkxjzl4p
https://infogram.com/6758fccb-2edc-4636-9e74-409513aaf34c
https://infogram.com/cufg-1h9j6q750mqmv4g
https://infogram.com/18759-uoht-1h9j6q750mqmv4g
https://infogram.com/72891-elgy-26319-1h9j6q750mqmv4g
https://infogram.com/e192a61d-4819-457a-b961-d31ad7d73936
https://infogram.com/aben-1h7v4pd03mqej4k
https://infogram.com/75733-vhzy-1h7v4pd03mqej4k
https://infogram.com/96359-csff-86182-1h7v4pd03mqej4k
https://infogram.com/7e1b91f8-e971-49b9-813b-aeb3b8d96de7
https://infogram.com/qwmq-1hnq41op5xj1p23
https://infogram.com/16127-iqod-1hnq41op5xj1p23
https://infogram.com/12096-seni-06910-1hnq41op5xj1p23
https://infogram.com/7dcc9610-560d-4a19-a773-2a48c5971831
https://infogram.com/xrpf-1hnp27eqkxjvy4g
https://infogram.com/50055-rtdj-1hnp27eqkxjvy4g
https://infogram.com/70870-zzqy-15088-1hnp27eqkxjvy4g
https://infogram.com/8c3c65d6-25eb-4d6f-b17a-f00fa58b6618
https://infogram.com/hubf-1h984wv1jxggz2p
https://infogram.com/37975-assb-1h984wv1jxggz2p
https://infogram.com/31524-jdcx-55089-1h984wv1jxggz2p
https://infogram.com/c98a6922-f1cc-44a0-a8bd-ad17c8c88af9
https://infogram.com/lzog-1h0r6rzw08qdw4e
https://infogram.com/77077-exfc-1h0r6rzw08qdw4e
https://infogram.com/52512-mipz-14533-1h0r6rzw08qdw4e
https://infogram.com/5c7870dc-7fcc-4736-b368-838901dde0d8
> data = Arrays.asList(
> data 定义了一个模拟的数据源,代表多行记录。