zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    上下文管理器
    创建项目与介绍(2)
    虚拟环境的安装(1)
    爬虫-selenium(14-2)扩展
    爬虫10-1(协程)
    Python3笔记038
    Python3笔记037
    Python3笔记036
    Python3笔记035
    Python3笔记034
  • 原文地址:https://www.cnblogs.com/lookupthesky/p/9897373.html
Copyright © 2011-2022 走看看