基于Java的Word文档自动生成与排版实战

简介:在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依赖配置示例



    org.apache.poi


    poi-ooxml


    5.2.3



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 = new HashMap<>();


data.put("${client_name}", "张三科技有限公司");


data.put("${sign_date}", "2025-04-05");


data.put("${amount}", "88,000");


 


for (XWPFParagraph p : document.getParagraphs()) {


    List runs = p.getRuns();


    if (runs == null || runs.isEmpty()) continue;


 


    String text = p.getText();


    for (Map.Entry entry : data.entrySet()) {


        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 placeholders = Map.of(


                "${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 paragraphs, Map map) {


        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 e : map.entrySet()) {


                            if (rText.contains(e.getKey())) {


                                rText = rText.replace(e.getKey(), e.getValue());


                                run.setText(rText, 0);


                            }


                        }


                    }


                }


            }


        }


    }


 


    private static void replaceInTable(XWPFTable table, Map 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 都对应一个 XML 元素,其子元素包括 (行)和 (单元格)。这种设计使得开发者无需直接操作 XML,即可完成语义清晰的表格构造。




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> data = Arrays.asList(


    Arrays.asList("张三", "28", "研发部", "高级工程师", "2020-01-01"),


    Arrays.asList("李四", "32", "市场部", "项目经理", "2019-05-15")


);


 


for (List rowData : data) {


    XWPFTableRow row = table.createRow();


    for (int i = 0; i < rowData.size(); i++) {


        row.getCell(i).setText(rowData.get(i));


    }


}


AI写代码


java


运行




代码逻辑逐行解析:




List> data 定义了一个模拟的数据源,代表多行记录。


外层 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 chartCache = new ConcurrentHashMap<>();


 


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 data) {


    // 替换普通段落


    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 data) {


    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 runs = paragraph.getRuns();


        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 batch = dataList.subList(i, Math.min(i + 50, dataList.size()));


    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


请使用浏览器的分享功能分享到微信等