Itextpdf + Adobe Acrobat DC填充模板生成pdf快速入门

 

Itextpdf + Adobe Acrobat DC填充模板生成pdf快速入门

 

生成pdf有很多种方法,如通过freemarker,或 使用itextpdf。本文将使用itextpdf生成pdf

 

1.下载Adobe Acrobat DC 并安装

从官网http://get.adobe.com/cn/reader/otherversions/下载

或者下载绿色版本

安装完之后又如下图标:

 

 

 

2.将word文件通过Adobe Acrobat DC生成pdf模板

 

 

 

 

 

 

 

 

如需要填充的是姓名和身份信息,如设置属性为realName 和idNo

 

3.运行结果如下

 

 

 

 

 4.添加依赖

 1  <dependency>
 2       <groupId>commons-io</groupId>
 3       <artifactId>commons-io</artifactId>
 4       <version>2.4</version>
 5     </dependency>
 6 
 7     <dependency>
 8       <groupId>commons-codec</groupId>
 9       <artifactId>commons-codec</artifactId>
10       <version>1.10</version>
11     </dependency>
12 
13    <!-- <dependency>
14       <groupId>commons-collections</groupId>
15       <artifactId>commons-collections</artifactId>
16       <version>3.2.1</version>
17     </dependency>-->
18 
19     <!-- itextpdf 依赖包start -->
20     <dependency>
21       <groupId>com.itextpdf</groupId>
22       <artifactId>itextpdf</artifactId>
23       <version>5.5.10</version>
24     </dependency>
25 
26     <dependency>
27       <groupId>com.itextpdf</groupId>
28       <artifactId>itext-asian</artifactId>
29       <version>5.2.0</version>
30     </dependency>
31     <!-- itextpdf 依赖包end -->
32 
33       <!--pdf 转图片 start -->
34       <dependency>
35           <groupId>org.apache.pdfbox</groupId>
36           <artifactId>pdfbox</artifactId>
37           <version>2.0.11</version>
38       </dependency>
39 
40     <dependency>
41       <groupId>net.coobird</groupId>
42       <artifactId>thumbnailator</artifactId>
43       <version>0.4.2</version>
44     </dependency>
45       <!--pdf 转图片 end -->
View Code

5.填充代码

PdfUtils 如下:

  1 /**
  2  * Project Name:mk-project <br>
  3  * Package Name:com.suns.pdf <br>
  4  *
  5  * @author mk <br>
  6  * Date:2018-11-2 14:32 <br>
  7  */
  8 
  9 package com.suns.pdf;
 10 
 11 import com.itextpdf.text.Document;
 12 import com.itextpdf.text.pdf.*;
 13 import org.apache.commons.io.FileUtils;
 14 import org.apache.commons.io.IOUtils;
 15 import org.apache.pdfbox.pdmodel.PDDocument;
 16 import org.apache.pdfbox.rendering.PDFRenderer;
 17 
 18 import javax.imageio.ImageIO;
 19 import java.awt.*;
 20 import java.awt.image.BufferedImage;
 21 import java.io.*;
 22 import java.util.*;
 23 import java.util.List;
 24 
 25 /**
 26  * Description: PdfUtils <br>
 27  * 依赖的包:itextpdf    itext-asian
 28  * commons-io,commons-codec
 29  * @author mk
 30  * @Date 2018-11-2 14:32 <br>
 31  * @Param
 32  * @return
 33  */
 34 public class PdfUtils {
 35 
 36 
 37     public static void main(String[] args) throws IOException {
 38         HashMap map = new HashMap<String, String>();
 39         map.put("realName","对应pdf中的表单名为realName");
 40         map.put("idNo","对应pdf中的表单名为idNo");
 41 //        String path = PdfUtils.class.getResource("/template").getPath();
 42 //        System.out.println("path:"+path);
 43 //        String sourceFile = path + File.separator + "test.pdf";
 44         String sourceFile = "d:/pdf/test.pdf";
 45         String targetFile = "d:/pdf/test_fill.pdf";
 46         String imageFilePath = "d:/pdf/test_fill.jpg";
 47 
 48 //        genPdf(map,sourceFile,targetFile);
 49 
 50 //        System.out.println("获取pdf表单中的fieldNames:"+getTemplateFileFieldNames(sourceFile));
 51 //        System.out.println("读取文件数组:"+fileBuff(sourceFile));
 52 //        System.out.println("pdf转图片:"+pdf2Img(new File(targetFile),imageFilePath));
 53     }
 54 
 55     private static void genPdf(HashMap map, String sourceFile, String targetFile) throws IOException {
 56         File templateFile = new File(sourceFile);
 57         fillParam(map, FileUtils.readFileToByteArray(templateFile), targetFile);
 58     }
 59 
 60     /**
 61      * Description: 使用map中的参数填充pdf,map中的key和pdf表单中的field对应 <br>
 62      * @author mk
 63      * @Date 2018-11-2 15:21 <br>
 64      * @Param
 65      * @return
 66      */
 67     public static void fillParam(Map<String, String> fieldValueMap, byte[] file, String contractFileName) {
 68         FileOutputStream fos = null;
 69         try {
 70             fos = new FileOutputStream(contractFileName);
 71             PdfReader reader = null;
 72             PdfStamper stamper = null;
 73             BaseFont base = null;
 74             try {
 75                 reader = new PdfReader(file);
 76                 stamper = new PdfStamper(reader, fos);
 77                 stamper.setFormFlattening(true);
 78                 base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
 79                 AcroFields acroFields = stamper.getAcroFields();
 80                 for (String key : acroFields.getFields().keySet()) {
 81                     acroFields.setFieldProperty(key, "textfont", base, null);
 82                     acroFields.setFieldProperty(key, "textsize", new Float(9), null);
 83                 }
 84                 if (fieldValueMap != null) {
 85                     for (String fieldName : fieldValueMap.keySet()) {
 86                         acroFields.setField(fieldName, fieldValueMap.get(fieldName));
 87                     }
 88                 }
 89             } catch (Exception e) {
 90                 e.printStackTrace();
 91             } finally {
 92                 if (stamper != null) {
 93                     try {
 94                         stamper.close();
 95                     } catch (Exception e) {
 96                         e.printStackTrace();
 97                     }
 98                 }
 99                 if (reader != null) {
100                     reader.close();
101                 }
102             }
103 
104         } catch (Exception e) {
105             System.out.println("填充参数异常");
106             e.printStackTrace();
107         } finally {
108             IOUtils.closeQuietly(fos);
109         }
110     }
111 
112     /**
113      * Description: 获取pdf表单中的fieldNames<br>
114      * @author mk
115      * @Date 2018-11-2 15:21 <br>
116      * @Param
117      * @return
118      */
119     public static Set<String> getTemplateFileFieldNames(String pdfFileName) {
120         Set<String> fieldNames = new TreeSet<String>();
121         PdfReader reader = null;
122         try {
123             reader = new PdfReader(pdfFileName);
124             Set<String> keys = reader.getAcroFields().getFields().keySet();
125             for (String key : keys) {
126                 int lastIndexOf = key.lastIndexOf(".");
127                 int lastIndexOf2 = key.lastIndexOf("[");
128                 fieldNames.add(key.substring(lastIndexOf != -1 ? lastIndexOf + 1 : 0, lastIndexOf2 != -1 ? lastIndexOf2 : key.length()));
129             }
130         } catch (IOException e) {
131             e.printStackTrace();
132         } finally {
133             if (reader != null) {
134                 reader.close();
135             }
136         }
137 
138         return fieldNames;
139     }
140 
141 
142     /**
143      * Description: 读取文件数组<br>
144      * @author mk
145      * @Date 2018-11-2 15:21 <br>
146      * @Param
147      * @return
148      */
149     public static byte[] fileBuff(String filePath) throws IOException {
150         File file = new File(filePath);
151         long fileSize = file.length();
152         if (fileSize > Integer.MAX_VALUE) {
153             //System.out.println("file too big...");
154             return null;
155         }
156         FileInputStream fi = new FileInputStream(file);
157         byte[] file_buff = new byte[(int) fileSize];
158         int offset = 0;
159         int numRead = 0;
160         while (offset < file_buff.length && (numRead = fi.read(file_buff, offset, file_buff.length - offset)) >= 0) {
161             offset += numRead;
162         }
163         // 确保所有数据均被读取
164         if (offset != file_buff.length) {
165             throw new IOException("Could not completely read file " + file.getName());
166         }
167         fi.close();
168         return file_buff;
169     }
170 
171     /**
172      * Description: 合并pdf <br>
173      * @author mk
174      * @Date 2018-11-2 15:21 <br>
175      * @Param
176      * @return
177      */
178     public static void mergePdfFiles(String[] files, String savepath) {
179         Document document = null;
180         try {
181             document = new Document(); //默认A4大小
182             PdfCopy copy = new PdfCopy(document, new FileOutputStream(savepath));
183             document.open();
184             for (int i = 0; i < files.length; i++) {
185                 PdfReader reader = null;
186                 try {
187                     reader = new PdfReader(files[i]);
188                     int n = reader.getNumberOfPages();
189                     for (int j = 1; j <= n; j++) {
190                         document.newPage();
191                         PdfImportedPage page = copy.getImportedPage(reader, j);
192                         copy.addPage(page);
193                     }
194                 } finally {
195                     if (reader != null) {
196                         reader.close();
197                     }
198                 }
199             }
200         } catch (Exception e) {
201             e.printStackTrace();
202         } finally {
203             //关闭PDF文档流,OutputStream文件输出流也将在PDF文档流关闭方法内部关闭
204             if (document != null) {
205                 document.close();
206             }
207 
208         }
209     }
210 
211 
212 
213     /**
214      * pdf转图片
215      * @param file pdf
216      * @return
217      */
218     public static boolean pdf2Img(File file,String imageFilePath) {
219         try {
220             //生成图片保存
221             byte[] data = pdfToPic(PDDocument.load(file));
222             File imageFile = new File(imageFilePath);
223             ImageThumbUtils.thumbImage(data, 1, imageFilePath); //按比例压缩图片
224             System.out.println("pdf转图片文件地址:" + imageFilePath);
225             return true;
226         } catch (Exception e) {
227             System.out.println("pdf转图片异常:");
228             e.printStackTrace();
229         }
230 
231         return false;
232     }
233 
234     /**
235      * pdf转图片
236      */
237     private static byte[] pdfToPic(PDDocument pdDocument) {
238         ByteArrayOutputStream baos = new ByteArrayOutputStream();
239         List<BufferedImage> piclist = new ArrayList<BufferedImage>();
240         try {
241             PDFRenderer renderer = new PDFRenderer(pdDocument);
242             for (int i = 0; i < pdDocument.getNumberOfPages(); i++) {//
243                 // 0 表示第一页,300 表示转换 dpi,越大转换后越清晰,相对转换速度越慢
244                 BufferedImage image = renderer.renderImageWithDPI(i, 108);
245                 piclist.add(image);
246             }
247             // 总高度 总宽度 临时的高度 , 或保存偏移高度 临时的高度,主要保存每个高度
248             int height = 0, width = 0, _height = 0, __height = 0,
249                     // 图片的数量
250                     picNum = piclist.size();
251             // 保存每个文件的高度
252             int[] heightArray = new int[picNum];
253             // 保存图片流
254             BufferedImage buffer = null;
255             // 保存所有的图片的RGB
256             List<int[]> imgRGB = new ArrayList<int[]>();
257             // 保存一张图片中的RGB数据
258             int[] _imgRGB;
259             for (int i = 0; i < picNum; i++) {
260                 buffer = piclist.get(i);
261                 heightArray[i] = _height = buffer.getHeight();// 图片高度
262                 if (i == 0) {
263                     // 图片宽度
264                     width = buffer.getWidth();
265                 }
266                 // 获取总高度
267                 height += _height;
268                 // 从图片中读取RGB
269                 _imgRGB = new int[width * _height];
270                 _imgRGB = buffer.getRGB(0, 0, width, _height, _imgRGB, 0, width);
271                 imgRGB.add(_imgRGB);
272             }
273 
274             // 设置偏移高度为0
275             _height = 0;
276             // 生成新图片
277             BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
278             int[] lineRGB = new int[8 * width];
279             int c = new Color(128, 128, 128).getRGB();
280             for (int i = 0; i < lineRGB.length; i++) {
281                 lineRGB[i] = c;
282             }
283             for (int i = 0; i < picNum; i++) {
284                 __height = heightArray[i];
285                 // 计算偏移高度
286                 if (i != 0)
287                     _height += __height;
288                 imageResult.setRGB(0, _height, width, __height, imgRGB.get(i), 0, width); // 写入流中
289 
290                 // 模拟页分隔
291                 if (i > 0) {
292                     imageResult.setRGB(0, _height + 2, width, 8, lineRGB, 0, width);
293                 }
294             }
295             // 写流
296             ImageIO.write(imageResult, "jpg", baos);
297         } catch (Exception e) {
298             System.out.println("pdf转图片异常:");
299             e.printStackTrace();
300         } finally {
301             IOUtils.closeQuietly(baos);
302             try {
303                 pdDocument.close();
304             } catch (Exception ignore) {
305             }
306         }
307 
308         return baos.toByteArray();
309     }
310 }
View Code

 ImageThumbUtils如下:

  1 /**  
  2  * @Project: hehenian-biz-common
  3  * @Package com.hehenian.biz.common.filesaving.utils
  4  * @Title: ImageThumbUtils.java
  5  * @Description: TODO
  6  * @author: zhangyunhua
  7  * @date 2015年1月20日 下午3:57:59
  8  * @Copyright: HEHENIAN Co.,Ltd. All rights reserved.
  9  * @version V1.0  
 10  */
 11 package com.suns.pdf;
 12 
 13 import net.coobird.thumbnailator.Thumbnails;
 14 import net.coobird.thumbnailator.geometry.Positions;
 15 
 16 import javax.imageio.ImageIO;
 17 import java.io.ByteArrayInputStream;
 18 import java.io.File;
 19 import java.io.FileInputStream;
 20 import java.io.InputStream;
 21 
 22 /**
 23  * 图片缩略、裁剪、添加水印。
 24  */
 25 public class ImageThumbUtils {
 26 
 27     /**
 28      * 缩略图片,图片质量为源图的80%
 29      * 
 30      * @param originalImgPath
 31      *            源图片存储路径
 32      * @param w
 33      *            图片压缩后的宽度
 34      * @param h
 35      *            图片压缩后的高度
 36      * @param targetImgPath
 37      *            缩略图的存放路径
 38      */
 39     public static void thumbImage(String originalImgPath, int w, int h, String targetImgPath) throws Exception {
 40         thumbImage(new FileInputStream(originalImgPath), w, h, targetImgPath, 0.8);
 41     }
 42 
 43     /**
 44      * 缩略图片,图片质量为源图的80%
 45      * 
 46      * @param originalImgData
 47      *            源图片字节数
 48      * @param w
 49      *            图片压缩后的宽度
 50      * @param h
 51      *            图片压缩后的高度
 52      * @param targetImgPath
 53      *            缩略图的存放路径
 54      */
 55     public static void thumbImage(byte[] originalImgData, int w, int h, String targetImgPath) throws Exception {
 56         thumbImage(new ByteArrayInputStream(originalImgData), w, h, targetImgPath, 0.8);
 57     }
 58      
 59     /** 
 60      * 按比例压缩文件
 61      * @param originalImgData 源文件
 62      * @param compressQalitiy 压缩比例
 63      * @param targetImgPath 目标路径
 64      */
 65     public static void thumbImage(byte[] originalImgData, double compressQalitiy, String targetImgPath) throws Exception {
 66         Thumbnails.of(new ByteArrayInputStream(originalImgData)).scale(1f).outputQuality(compressQalitiy).toFile(targetImgPath);
 67     }
 68 
 69     /**
 70      * 按尺寸比例缩略
 71      * 
 72      * @param originalInputSteam
 73      *            源图输入流
 74      * @param w
 75      *            缩略宽
 76      * @param h
 77      *            缩略高
 78      * @param targetImgPath
 79      *            缩略图存储路径
 80      * @param compressQalitiy
 81      *            缩略质量比例,0~1之间的数
 82      */
 83     public static void thumbImage(InputStream originalInputSteam, int w, int h, String targetImgPath, double compressQalitiy) throws Exception {
 84         thumbImage(originalInputSteam, w, h, targetImgPath, compressQalitiy, true);
 85     }
 86 
 87     /**
 88      * 
 89      * @param originalImgInputSteam
 90      *            源图片输入流
 91      * @param w
 92      *            图片压缩后的宽度
 93      * @param h
 94      *            图片压缩后的高度
 95      * @param targetImgPath
 96      *            缩略图的存放路径
 97      * @param compressQalitiy
 98      *            压缩比例,0~1之间的double数字
 99      * @param keepAspectRatio
100      *            是否保持等比例压缩,是true,不是false
101      */
102     public static void thumbImage(InputStream originalImgInputSteam, int w, int h, String targetImgPath, double compressQalitiy,
103             boolean keepAspectRatio) throws Exception {
104         Thumbnails.of(originalImgInputSteam).size(w, h).outputQuality(Double.valueOf(compressQalitiy)).keepAspectRatio(true).toFile(targetImgPath);
105     }
106 
107     /**
108      * 图片裁剪
109      * 
110      * @param originalImgPath
111      *            源图片路径
112      * @param targetImgPath
113      *            新图片路径
114      * @param position
115      *            位置 0正中间,1中间左边,2中间右边,3底部中间,4底部左边,5底部右边,6顶部中间,7顶部左边,8顶部右边,
116      *            其他为默认正中间
117      * @param w
118      *            裁剪宽度
119      * @param h
120      *            裁剪高度
121      * @throws Exception
122      */
123     public static void crop(String originalImgPath, int position, int w, int h, String targetImgPath) throws Exception {
124         Thumbnails.of(originalImgPath).sourceRegion(getPositions(position), w, h).size(w, h).outputQuality(1).toFile(targetImgPath);
125     }
126 
127     /**
128      * 给图片添加水印
129      * 
130      * @param originalImgPath
131      *            将被添加水印图片 路径
132      * @param targetImgPath
133      *            含有水印的新图片路径
134      * @param watermarkImgPath
135      *            水印图片
136      * @param position
137      *            位置 0正中间,1中间左边,2中间右边,3底部中间,4底部左边,5底部右边,6顶部中间,7顶部左边,8顶部右边,
138      *            其他为默认正中间
139      * @param opacity
140      *            不透明度,取0~1之间的float数字,0完全透明,1完全不透明
141      * @throws Exception
142      */
143     public static void watermark(String originalImgPath, String watermarkImgPath, int position, float opacity, String targetImgPath)
144             throws Exception {
145         Thumbnails.of(originalImgPath).watermark(getPositions(position), ImageIO.read(new File(watermarkImgPath)), opacity).scale(1.0)
146                 .outputQuality(1).toFile(targetImgPath);
147     }
148 
149     private static Positions getPositions(int position) {
150         Positions p = Positions.CENTER;
151         switch (position) {
152         case 0: {
153             p = Positions.CENTER;
154             break;
155         }
156         case 1: {
157             p = Positions.CENTER_LEFT;
158             break;
159         }
160         case 2: {
161             p = Positions.CENTER_RIGHT;
162             break;
163         }
164         case 3: {
165             p = Positions.BOTTOM_CENTER;
166             break;
167         }
168         case 4: {
169             p = Positions.BOTTOM_LEFT;
170             break;
171         }
172         case 5: {
173             p = Positions.BOTTOM_RIGHT;
174             break;
175         }
176         case 6: {
177             p = Positions.TOP_CENTER;
178             break;
179         }
180         case 7: {
181             p = Positions.TOP_LEFT;
182             break;
183         }
184         case 8: {
185             p = Positions.TOP_RIGHT;
186             break;
187         }
188         default: {
189             p = Positions.CENTER;
190             break;
191         }
192         }
193         return p;
194     }
195 
196     public static void main(String[] args) throws Exception {
197         thumbImage("d:/pdf/1.jpg", 600, 600, "d:/pdf/2.jpg");
198         crop("d:/pdf/1.jpg", 7, 200, 300, "d:/pdf/2.jpg");
199         watermark("d:/pdf/1.jpg", "d:/pdf/2.jpg", 7, 1, "d:/pdf/3.jpg");
200     }
201 }
View Code

 

posted on 2018-11-02 17:17  sgyi06  阅读(3834)  评论(0编辑  收藏  举报

导航