声明:由于业务场景需要,所以根据一个网友的完成的。

1、既然要使用PDF模板填充,那么就需要制作PDF模板,可以使用Adobe Acrobat DC,下载地址:https://carrot.ctfile.com/dir/11269771-27158812-194d66/29433907/ (使用特别破解版),安装步骤就省略了。

2、开始制作模板

  a)使用wps制作一个表格,并转为PDF文件保存

  

  b)使用Adobe Acrobat DC打开保存的PDF文件,然后搜索 "准备表单" ,点击 ”准备表单“,然后出来表单域

3、程序部分

  a)依赖

     <dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency> <dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency> <!-- itextpdf 依赖包start -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency> <dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- itextpdf 依赖包end --> <!--pdf 转图片 start -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.11</version>
</dependency> <dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.2</version>
</dependency>
<!--pdf 转图片 end -->

  b)工具类 ImageThumbUtils,该类主要是用于将pdf转为图片,如果不需要可以不添加

package com.yangwj.demo.controller;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions; import javax.imageio.ImageIO;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream; /**
* 图片缩略、裁剪、添加水印。
*/
public class ImageThumbUtils { /**
* 缩略图片,图片质量为源图的80%
*
* @param originalImgPath
* 源图片存储路径
* @param w
* 图片压缩后的宽度
* @param h
* 图片压缩后的高度
* @param targetImgPath
* 缩略图的存放路径
*/
public static void thumbImage(String originalImgPath, int w, int h, String targetImgPath) throws Exception {
thumbImage(new FileInputStream(originalImgPath), w, h, targetImgPath, 0.8);
} /**
* 缩略图片,图片质量为源图的80%
*
* @param originalImgData
* 源图片字节数
* @param w
* 图片压缩后的宽度
* @param h
* 图片压缩后的高度
* @param targetImgPath
* 缩略图的存放路径
*/
public static void thumbImage(byte[] originalImgData, int w, int h, String targetImgPath) throws Exception {
thumbImage(new ByteArrayInputStream(originalImgData), w, h, targetImgPath, 0.8);
} /**
* 按比例压缩文件
* @param originalImgData 源文件
* @param compressQalitiy 压缩比例
* @param targetImgPath 目标路径
*/
public static void thumbImage(byte[] originalImgData, double compressQalitiy, String targetImgPath) throws Exception {
Thumbnails.of(new ByteArrayInputStream(originalImgData)).scale(1f).outputQuality(compressQalitiy).toFile(targetImgPath);
} /**
* 按尺寸比例缩略
*
* @param originalInputSteam
* 源图输入流
* @param w
* 缩略宽
* @param h
* 缩略高
* @param targetImgPath
* 缩略图存储路径
* @param compressQalitiy
* 缩略质量比例,0~1之间的数
*/
public static void thumbImage(InputStream originalInputSteam, int w, int h, String targetImgPath, double compressQalitiy) throws Exception {
thumbImage(originalInputSteam, w, h, targetImgPath, compressQalitiy, true);
} /**
*
* @param originalImgInputSteam
* 源图片输入流
* @param w
* 图片压缩后的宽度
* @param h
* 图片压缩后的高度
* @param targetImgPath
* 缩略图的存放路径
* @param compressQalitiy
* 压缩比例,0~1之间的double数字
* @param keepAspectRatio
* 是否保持等比例压缩,是true,不是false
*/
public static void thumbImage(InputStream originalImgInputSteam, int w, int h, String targetImgPath, double compressQalitiy,
boolean keepAspectRatio) throws Exception {
Thumbnails.of(originalImgInputSteam).size(w, h).outputQuality(Double.valueOf(compressQalitiy)).keepAspectRatio(true).toFile(targetImgPath);
} /**
* 图片裁剪
*
* @param originalImgPath
* 源图片路径
* @param targetImgPath
* 新图片路径
* @param position
* 位置 0正中间,1中间左边,2中间右边,3底部中间,4底部左边,5底部右边,6顶部中间,7顶部左边,8顶部右边,
* 其他为默认正中间
* @param w
* 裁剪宽度
* @param h
* 裁剪高度
* @throws Exception
*/
public static void crop(String originalImgPath, int position, int w, int h, String targetImgPath) throws Exception {
Thumbnails.of(originalImgPath).sourceRegion(getPositions(position), w, h).size(w, h).outputQuality(1).toFile(targetImgPath);
} /**
* 给图片添加水印
*
* @param originalImgPath
* 将被添加水印图片 路径
* @param targetImgPath
* 含有水印的新图片路径
* @param watermarkImgPath
* 水印图片
* @param position
* 位置 0正中间,1中间左边,2中间右边,3底部中间,4底部左边,5底部右边,6顶部中间,7顶部左边,8顶部右边,
* 其他为默认正中间
* @param opacity
* 不透明度,取0~1之间的float数字,0完全透明,1完全不透明
* @throws Exception
*/
public static void watermark(String originalImgPath, String watermarkImgPath, int position, float opacity, String targetImgPath)
throws Exception {
Thumbnails.of(originalImgPath).watermark(getPositions(position), ImageIO.read(new File(watermarkImgPath)), opacity).scale(1.0)
.outputQuality(1).toFile(targetImgPath);
} private static Positions getPositions(int position) {
Positions p = Positions.CENTER;
switch (position) {
case 0: {
p = Positions.CENTER;
break;
}
case 1: {
p = Positions.CENTER_LEFT;
break;
}
case 2: {
p = Positions.CENTER_RIGHT;
break;
}
case 3: {
p = Positions.BOTTOM_CENTER;
break;
}
case 4: {
p = Positions.BOTTOM_LEFT;
break;
}
case 5: {
p = Positions.BOTTOM_RIGHT;
break;
}
case 6: {
p = Positions.TOP_CENTER;
break;
}
case 7: {
p = Positions.TOP_LEFT;
break;
}
case 8: {
p = Positions.TOP_RIGHT;
break;
}
default: {
p = Positions.CENTER;
break;
}
}
return p;
} public static void main(String[] args) throws Exception {
thumbImage("d:/pdf/1.jpg", 600, 600, "d:/pdf/2.jpg");
crop("d:/pdf/1.jpg", 7, 200, 300, "d:/pdf/2.jpg");
watermark("d:/pdf/1.jpg", "d:/pdf/2.jpg", 7, 1, "d:/pdf/3.jpg");
}
}

  c)实现数据填充PDF模板

package com.yangwj.demo.controller;

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer; import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.List; /**
* Description: PdfUtils <br>
* 依赖的包:itextpdf itext-asian
* commons-io,commons-codec
* @author mk
* @Date 2018-11-2 14:32 <br>
* @Param
* @return
*/
public class PdfUtils { public static void main(String[] args) throws IOException {
HashMap map = new HashMap<String, String>();
map.put("name","杨杰");
map.put("sex","男");
map.put("age","");
map.put("phone","");
map.put("email","812406fdf@qq.com");
map.put("idCard","");
map.put("hobby","跑步");
map.put("time","2019年5月22日");
// String path = PdfUtils.class.getResource("/template").getPath();
// System.out.println("path:"+path);
// String sourceFile = path + File.separator + "test.pdf";
String sourceFile = "C:\\Users\\yangwj\\Desktop\\test.pdf";
String targetFile = "C:\\Users\\yangwj\\Desktop\\test_fill.pdf";
genPdf(map,sourceFile,targetFile); // System.out.println("获取pdf表单中的fieldNames:"+getTemplateFileFieldNames(sourceFile));
// System.out.println("读取文件数组:"+fileBuff(sourceFile));
// System.out.println("pdf转图片:"+pdf2Img(new File(targetFile),imageFilePath));
} private static void genPdf(HashMap map, String sourceFile, String targetFile) throws IOException {
File templateFile = new File(sourceFile);
fillParam(map, FileUtils.readFileToByteArray(templateFile), targetFile);
} /**
* Description: 使用map中的参数填充pdf,map中的key和pdf表单中的field对应 <br>
* @author mk
* @Date 2018-11-2 15:21 <br>
* @Param
* @return
*/
public static void fillParam(Map<String, String> fieldValueMap, byte[] file, String contractFileName) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(contractFileName);
PdfReader reader = null;
PdfStamper stamper = null;
BaseFont base = null;
try {
reader = new PdfReader(file);
stamper = new PdfStamper(reader, fos);
stamper.setFormFlattening(true);
base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
AcroFields acroFields = stamper.getAcroFields();
for (String key : acroFields.getFields().keySet()) {
acroFields.setFieldProperty(key, "textfont", base, null);
acroFields.setFieldProperty(key, "textsize", new Float(9), null);
}
if (fieldValueMap != null) {
for (String fieldName : fieldValueMap.keySet()) {
acroFields.setField(fieldName, fieldValueMap.get(fieldName));
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stamper != null) {
try {
stamper.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (reader != null) {
reader.close();
}
} } catch (Exception e) {
System.out.println("填充参数异常");
e.printStackTrace();
} finally {
IOUtils.closeQuietly(fos);
}
} /**
* Description: 获取pdf表单中的fieldNames<br>
* @author mk
* @Date 2018-11-2 15:21 <br>
* @Param
* @return
*/
public static Set<String> getTemplateFileFieldNames(String pdfFileName) {
Set<String> fieldNames = new TreeSet<String>();
PdfReader reader = null;
try {
reader = new PdfReader(pdfFileName);
Set<String> keys = reader.getAcroFields().getFields().keySet();
for (String key : keys) {
int lastIndexOf = key.lastIndexOf(".");
int lastIndexOf2 = key.lastIndexOf("[");
fieldNames.add(key.substring(lastIndexOf != -1 ? lastIndexOf + 1 : 0, lastIndexOf2 != -1 ? lastIndexOf2 : key.length()));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
} return fieldNames;
} /**
* Description: 读取文件数组<br>
* @author mk
* @Date 2018-11-2 15:21 <br>
* @Param
* @return
*/
public static byte[] fileBuff(String filePath) throws IOException {
File file = new File(filePath);
long fileSize = file.length();
if (fileSize > Integer.MAX_VALUE) {
//System.out.println("file too big...");
return null;
}
FileInputStream fi = new FileInputStream(file);
byte[] file_buff = new byte[(int) fileSize];
int offset = 0;
int numRead = 0;
while (offset < file_buff.length && (numRead = fi.read(file_buff, offset, file_buff.length - offset)) >= 0) {
offset += numRead;
}
// 确保所有数据均被读取
if (offset != file_buff.length) {
throw new IOException("Could not completely read file " + file.getName());
}
fi.close();
return file_buff;
} /**
* Description: 合并pdf <br>
* @author mk
* @Date 2018-11-2 15:21 <br>
* @Param
* @return
*/
public static void mergePdfFiles(String[] files, String savepath) {
Document document = null;
try {
document = new Document(); //默认A4大小
PdfCopy copy = new PdfCopy(document, new FileOutputStream(savepath));
document.open();
for (int i = 0; i < files.length; i++) {
PdfReader reader = null;
try {
reader = new PdfReader(files[i]);
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
} finally {
if (reader != null) {
reader.close();
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭PDF文档流,OutputStream文件输出流也将在PDF文档流关闭方法内部关闭
if (document != null) {
document.close();
} }
} /**
* pdf转图片
* @param file pdf
* @return
*/
public static boolean pdf2Img(File file,String imageFilePath) {
try {
//生成图片保存
byte[] data = pdfToPic(PDDocument.load(file));
File imageFile = new File(imageFilePath);
ImageThumbUtils.thumbImage(data, 1, imageFilePath); //按比例压缩图片
System.out.println("pdf转图片文件地址:" + imageFilePath);
return true;
} catch (Exception e) {
System.out.println("pdf转图片异常:");
e.printStackTrace();
} return false;
} /**
* pdf转图片
*/
private static byte[] pdfToPic(PDDocument pdDocument) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
List<BufferedImage> piclist = new ArrayList<BufferedImage>();
try {
PDFRenderer renderer = new PDFRenderer(pdDocument);
for (int i = 0; i < pdDocument.getNumberOfPages(); i++) {//
// 0 表示第一页,300 表示转换 dpi,越大转换后越清晰,相对转换速度越慢
BufferedImage image = renderer.renderImageWithDPI(i, 108);
piclist.add(image);
}
// 总高度 总宽度 临时的高度 , 或保存偏移高度 临时的高度,主要保存每个高度
int height = 0, width = 0, _height = 0, __height = 0,
// 图片的数量
picNum = piclist.size();
// 保存每个文件的高度
int[] heightArray = new int[picNum];
// 保存图片流
BufferedImage buffer = null;
// 保存所有的图片的RGB
List<int[]> imgRGB = new ArrayList<int[]>();
// 保存一张图片中的RGB数据
int[] _imgRGB;
for (int i = 0; i < picNum; i++) {
buffer = piclist.get(i);
heightArray[i] = _height = buffer.getHeight();// 图片高度
if (i == 0) {
// 图片宽度
width = buffer.getWidth();
}
// 获取总高度
height += _height;
// 从图片中读取RGB
_imgRGB = new int[width * _height];
_imgRGB = buffer.getRGB(0, 0, width, _height, _imgRGB, 0, width);
imgRGB.add(_imgRGB);
} // 设置偏移高度为0
_height = 0;
// 生成新图片
BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] lineRGB = new int[8 * width];
int c = new Color(128, 128, 128).getRGB();
for (int i = 0; i < lineRGB.length; i++) {
lineRGB[i] = c;
}
for (int i = 0; i < picNum; i++) {
__height = heightArray[i];
// 计算偏移高度
if (i != 0)
_height += __height;
imageResult.setRGB(0, _height, width, __height, imgRGB.get(i), 0, width); // 写入流中 // 模拟页分隔
if (i > 0) {
imageResult.setRGB(0, _height + 2, width, 8, lineRGB, 0, width);
}
}
// 写流
ImageIO.write(imageResult, "jpg", baos);
} catch (Exception e) {
System.out.println("pdf转图片异常:");
e.printStackTrace();
} finally {
IOUtils.closeQuietly(baos);
try {
pdDocument.close();
} catch (Exception ignore) {
}
} return baos.toByteArray();
}
}

 4、针对复选框的填充

只需要在相应的字段(现金付费)设置值为"On"。

5、针对属性值太长,可以对填充框进行换行

java之数据填充PDF模板的更多相关文章

  1. 使用iTextSharp来填充PDF模板文件

    需求简介:     遇到了这样一个需求:某公司需要为所有用户的培训生成一个培训记录,过程如下:     (1)用户在培训完之后会进入到一个填写信息的界面.     (2)用户填写信息.     (3) ...

  2. 不会吧不会吧,还有开发不会Java填充PDF模板数据的,赶紧看看吧

    思路 根据业务需求,获取实际业务数据,借助itext库功能,将业务数据填充入提前制作好的PDF模板中 操作步骤 制作PDF模板:提前下载好Adobe Acrobat Pro DC 效果展示 准备PDF ...

  3. Java 创建、填充PDF表单域

    表单域,可以按用途分为多种不同的类型,常见的有文本框.多行文本框.密码框.隐藏域.复选框.单选框和下拉选择框等,目的是用于采集用户的输入或选择的数据.下面的示例中,将分享通过Java编程在PDF中添加 ...

  4. 新知识:Java 利用itext填写pdf模板并导出(昨天奋战到深夜四点,知道今天两点终于弄懂)

    废话少说,不懂itext干啥用的直接去百度吧. ***************制作模板******************* 1.先用word做出界面 2.再转换成pdf格式 3.用Adobe Acr ...

  5. [转载]java实现word转pdf

    最近遇到一个项目需要把word 转成pdf,百度了一下网上的方案有很多,比如虚拟打印.给word 装扩展插件等,这些方案都依赖于ms word 程序,在java代码中也得使用诸如jacob或jcom这 ...

  6. [原创]java实现word转pdf

    最近遇到一个项目需要把word 转成pdf,百度了一下网上的方案有很多,比如虚拟打印.给word 装扩展插件等,这些方案都依赖于ms word 程序,在java代码中也得使用诸如jacob或jcom这 ...

  7. 整理关于Java进行word文档的数据动态数据填充

    首先我们看下,别人整理的关于Java生成doc 的 资料. java生成word的几种方案 1. Jacob是Java-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁.使用 ...

  8. java 导出数据为word文档(保持模板格式)

    导出数据到具体的word文档里面,word有一定的格式,需要保持不变 这里使用freemarker来实现: ①:设计好word文档格式,需要用数据填充的地方用便于识别的长字符串替换  如  aaaaa ...

  9. PDF模板报表导出(Java+Acrobat+itext)

    1. 首先要安装Adobe Acrobat,装好之后用Acrobat从一个word,excel或者pdf中转换一个pdf模板,我做的模板很简单,直接写一个简单的word再生成一个pdf表单,之后编辑文 ...

随机推荐

  1. selenium:能够模拟人类打开浏览器的爬虫利器

    介绍 selenium相当于是一个机器人,可以模拟人类登陆浏览器的行为,比如点击.填充数据.删除cookie等等.Chromedriver是一个驱动Chrome的程序,使用它才可以驱动浏览器,其实Ch ...

  2. 网络初级篇之VLAN间路由(原理与配置)

    一.VLAN间的路由 由于VLAN隔离了二层广播域,也间接的隔离了各个VLAN之间的其他二层流量交换,这样导致属于不同VLAN之间的用户不能进行二层的通信.只能经过三层的路由转发才能将报文从一个VLA ...

  3. Mysql(四)-2:多表查询

    一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 准备表 #建表 create table department( id int, name varchar(20) ); create ta ...

  4. Python lambda 知识点

    作者说学会了lambda后,你会用上瘾的,因为让代码复用和简洁. 初识lamdba不太好理解,尤其是它能当着一个变量传递给函数,不过多学着写几个例子就好了,下面是我的学习笔记. lambda 操作符( ...

  5. 第二章 Vue快速入门--10-11 跑马灯效果制作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  6. java WebSocket HTML页面

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. VUE-文本-事件-属性指令

    一.Vue文本指令 文本指令: 1.{{ }} 2.v-text:不能解析html语法的文本,会原样输出 3.v-html:能解析html语法的文本 4.v-once:处理的标签的内容只能被解析一次 ...

  8. Nuxt 服务端渲染

    前言 Nuxt.js 是一个基于 Vue.js 的通用应用框架. ssr 渲染服务端 可以看官方文档 https://zh.nuxtjs.org/guide/ nuxt 与平常 jsonp 不一样 , ...

  9. Qt 多线程使用moveToThread

    Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类用moveToThread函数转移到一个Thread里. Qt4.8之前都是使用继承QThre ...

  10. redis实现排行榜功能

    目录 加入排行榜 操作排行榜 redis的zset可以很方便地用来实现排行榜功能,下面简单介绍python如何使用redis实现排行榜功能 加入排行榜 获取redis实例 import redis m ...