赞
踩
原文链接:https://blog.csdn.net/oAXuHui/article/details/109726036
#、接上篇
我们前面对水印填充方法进行了简单介绍,本章描述的模板填充,可以是正文的填充,也可以是水印填充,水印填充可参考上一篇《OFD开发系列(一)-添加水印》。
一、什么是模板填充
模板填充是指基于固定的模板文档,在指定的位置(坐标/百分比)或文本替换填入所需的图片、文本、日期等内容,最后生成一个可用的文档以供用户存档、检索、签署等。我们知道,PDF可以使用表单填充,并且可以设置文字的字体、颜色、字号、对齐方式等。而在OFD版式文档里,没有表单的概念,我们需要采用其它方法进行填充。如下所示:
基于关键字填充:此处需要查找关键字,然后增加相对应的偏移值进行填充。
基于坐标填充:此处可以指定坐标x/y值(单位mm)或百分比进行填充,这种填充方法需要模板编辑系统的支持,例如:在页面上标注好填充坐标或填充百分比位置。
基于文本替换:此处可以基于模板引擎进行文本替换或自定义标识符,该方法可能会对版式文档的阅读版式产生影响,需要定义好字符长度、字体、字号等参数。
二、模板填充的场景
常见的填充场景有如下几类:电子保单、电子合同、取证报告、调查问卷、电子发票等。总之,关键内容需要变更的电子文档,都需要具备模板填充能力。
三、ofdrw实现填充
3.1、模板填充准备
我们将上文提到的模板填充方法(关键字填充、坐标填充)进行模板填充演示,文本替换各位可以基于模板引擎直接实现文本替换,此处不进行详细说明。
首先,我们需要在maven引入ofdrw的jar包(注意此处由于ofdrw功能优化升级和上一篇的版本不一致):
- <!--junit-->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.6</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- ofdrw -->
- <dependency>
- <groupId>org.ofdrw</groupId>
- <artifactId>ofdrw-full</artifactId>
- <version>1.6.10</version>
- </dependency>

其次,我们准备一个待填充的模板文档,第一列为A列,第二列为B列,其中事项标题为A1,A1旁边为B1,以此类推,如下所示:
3.2、关键字填充
我们需要对事项标题后面的文本框填入“基于ofdrw的关键字模板填充实现”,申请依据后面填入“新版本演示”。代码如下:
- /**
- * 模板处理
- */
- @Test
- public void testTemplateTextBaseKeyword() throws IOException, DocumentException {
- Path inP = Paths.get("src/test/resources/z.ofd");
- Path outP = Paths.get("target/Canvas-fillText.ofd");
-
- try (OFDReader reader = new OFDReader(inP);
- OFDDoc ofdDoc = new OFDDoc(reader, outP)) {
- String t1 = "事项标题", t2 = "申请依据";
- String f1 = "基于ofdrw的关键字模板填充实现", f2 = "新版本演示";
-
- String[] keywords = {t1, t2};
- List<KeywordPosition> positionList = KeywordExtractor.getKeyWordPositionList(reader, keywords);
- //偏移量需要模板制作确认
- float offset = 25;
- for (KeywordPosition position : positionList) {
- //创建可追加的虚拟页面
- AdditionVPage page = ofdDoc.getAVPage(position.getPage());
-
- //创建一个可以自动换行的段落
- Paragraph paragraph = new Paragraph();
- paragraph.setPosition(Position.Absolute)
- .setWidth(f1.length() * 5.0).setHeight(10D) //设置外接矩形宽高
- .setX(position.getBox().getTopLeftX() + position.getBox().getWidth() + offset) //设置x坐标
- .setY(position.getBox().getTopLeftY()); //设置y坐标
-
- //创建 Span 文本控件对象
- Span span;
- if (t1.equals(position.getKeyword())) {
- span = new Span(f1);
- } else {
- span = new Span(f2);
- }
-
- //设置Span的属性
- span.setFontSize(5.0);
- span.setColor(0, 0, 0);
- //段落添加Span文本控件
- paragraph.add(span);
-
- //页面添加段落
- page.add(paragraph);
- }
- }
- System.out.println("生成文档位置:" + outP.toAbsolutePath().toString());
- }

此处通过KeywordExtractor检索到两个关键字的坐标,制作确认模板偏移量,通过循环创建,完成模板填充。特别指出:需要创建可追加的虚拟页面和需要计算好外接矩形的x/y坐标和宽高,文本控件对象Span支持的设置很多,如下所示,在此不在详述:
- public class Span implements TextFontInfo {
- private Font font;
- private Double fontSize;
- private Double letterSpacing;
- private boolean bold;
- private boolean italic;
- private boolean underline;
- private String text;
- private int[] fillColor;
- private boolean linebreak;
- private Boolean integrity;
- }
填充效果如下:
3.3、坐标填充
我们需要对事项依据下面的单元格A3 和 A3右边的单元格B3进行坐标填充,同样的,我们需要制作填充模板,确提前确定坐标位置,A3使用毫米单位,B3使用百分比单位。代码如下所示:
- /**
- * 模板处理
- */
- @Test
- public void testTemplateTextBaseKeyword() throws IOException, DocumentException {
- Path inP = Paths.get("src/test/resources/z.ofd");
- Path outP = Paths.get("target/Canvas-fillText.ofd");
-
- try (OFDReader reader = new OFDReader(inP);
- OFDDoc ofdDoc = new OFDDoc(reader, outP)) {
- String key = "申请人", value = "ofdrw";
-
- /*
- * 此处参数值需要模板确定
- */
- double A3_X = 30, A3_Y = 60.77;
- //此处为36%和20.33%
- double B3_X = 0.36 * ofdDoc.getPageLayout().getWidth(),
- B3_Y = 0.2033 * ofdDoc.getPageLayout().getHeight();
-
- //创建可追加的虚拟页面(指定第1页)
- AdditionVPage page = ofdDoc.getAVPage(1);
- //1、添加A3
- {
- //创建一个可以自动换行的段落
- Paragraph paragraph = new Paragraph();
- paragraph.setPosition(Position.Absolute)
- .setWidth(key.length() * 5.0).setHeight(10D) //设置外接矩形宽高
- .setX(A3_X) //设置x坐标
- .setY(A3_Y); //设置y坐标
-
- //创建 Span 文本控件对象
- Span span = new Span(key);
-
- //设置Span的属性
- span.setFontSize(5.0);
- span.setColor(0, 0, 0);
- //段落添加Span文本控件
- paragraph.add(span);
-
- //页面添加段落
- page.add(paragraph);
- }
- //2、添加B3
- {
- //创建一个可以自动换行的段落
- Paragraph paragraph = new Paragraph();
- paragraph.setPosition(Position.Absolute)
- .setWidth(value.length() * 5.0).setHeight(10D) //设置外接矩形宽高
- .setX(B3_X) //设置x坐标
- .setY(B3_Y); //设置y坐标
-
- //创建 Span 文本控件对象
- Span span = new Span(value);
-
- //设置Span的属性
- span.setFontSize(5.0);
- span.setColor(0, 0, 0);
- //段落添加Span文本控件
- paragraph.add(span);
-
- //页面添加段落
- page.add(paragraph);
- }
- }
- System.out.println("生成文档位置:" + outP.toAbsolutePath().toString());
- }

和3.2结果类似,此处生成了一个新的文档,如下所示:
到此,填充方法演示完成,这些在ofd里其实都是基本的功能。
四、遗留问题
上文提到的模板填充遗留两个问题:第一、填充模板制作;第二、是否支持表单填充;第三、没有日期、图片和图形的填充,各位可以基于此编写相关demo。目前没有开源的模板制作方案,各位有兴趣的同学可以自行研究并开源贡献。
————————————————
版权声明:本文为CSDN博主「阿徐汇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/oAXuHui/article/details/109726036
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。