itext根据模版生成PDF与合并多个PDF以及向已存在PDF增加水印设置权限等操作


声明:本文转载自https://my.oschina.net/itazi/blog/1822301,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

    我之前写了一篇文章讲了itext的基础操作常用方法(https://my.oschina.net/itazi/blog/1812042),但是有时涉及到比较复杂的PDF生成,手工操作就很复杂,可以使用模板生成方式。有时还要涉及合并等,于是将用到的略作记载。

   首先要用到的依赖:

 <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> 		 		<dependency> 		    <groupId>org.bouncycastle</groupId> 		    <artifactId>bcprov-jdk15on</artifactId> 		    <version>1.54</version> 		</dependency> 		 		<!-- https://mvnrepository.com/artifact/com.lowagie/itext --> 		<dependency> 		    <groupId>com.lowagie</groupId> 		    <artifactId>itext</artifactId> 		    <version>2.1.7</version> 		</dependency>

    首先我们来讲讲制作模板,可以查考这个https://www.cnblogs.com/LUA123/p/5108007.html,这里面感觉很详细了,另外特别提到一点,由于要用Adobe制作的话需要购买,所以作为代提方案,你还可以使用福晰PDF软件制作,也可以实现相同效果,亲测可用。制作好模板之后接下来就是根据模板生成PDF,代码如下:

/**      * 根据模版生成pdf      *       * @param templateFile 模板路径      * @param targetFile 将要生成的pdf路径      * @param fieldMap 填充字段      */     public static Boolean createPdfFromTemplate(String templateFile, String targetFile, Map<String, String> fieldMap) {         Boolean retValue = false;         try {             /* 打开已经定义好字段以后的pdf模板 */             com.itextpdf.text.pdf.PdfReader reader = new com.itextpdf.text.pdf.PdfReader(templateFile);              /* 将要生成的目标PDF文件名称 */             PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(targetFile));              PdfContentByte under = stamp.getUnderContent(1);              /* 使用中文字体 */             BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);             Font fontChinese = new Font(bf, 12, Font.NORMAL);              /* 取出报表模板中的所有字段 */             AcroFields form = stamp.getAcroFields();             form.addSubstitutionFont(bf);//这行必须添加否则中文不显示              /* 为字段赋值,注意字段名称是区分大小写的 */             for (String key : fieldMap.keySet()) {                 form.setField(key, fieldMap.get(key));             }              stamp.setFormFlattening(true);             /* 必须要调用这个,否则文档不会生成的 */             stamp.close();             reader.close();             retValue = true;         } catch (DocumentException de) {             System.err.println(de.getMessage());         } catch (IOException ioe) {             System.err.println(ioe.getMessage());         } finally {             return retValue;         }          }

    测试代码如下(注意:关于路径你要改成你自己本地的路径,要正确,特别是你制作模板的路径,要填写正确,要不然模板都找不到,谈何制作pdf呢):

Map<String, String> map = new HashMap<String, String>();         map.put("projectname", "map填充");//这里的projectname是你制作PDF时填入的字段         map.put("applyname", "shishui??");//同上         System.out.println(PdfUtils.createPdfFromTemplate("/Users/hxm/Documents/pdf/project_detail_model_wrapper_2.pdf",                  "/Users/hxm/Documents/pdf/tempalte.pdf", map));

    结果:

填充成功。

    接下来我们来谈谈合并PDF,有时候你有多个PDF,正好需要合并成一个,你可能就需要这个方法了(部分内容参考:https://www.cnblogs.com/pocketbook/p/6427579.html)。代码如下:

/**      * 合并pdf      * @param files 要合并的pdf文件      * @param newfile 生成的文件名      * @return      */     public static Boolean mergePdfFiles(String[] files, String newfile) {         Boolean retValue = false;           Document document = null;          try {              document = new Document(new PdfReader(files[0]).getPageSize(1));            PdfCopy copy = new PdfCopy(document, new FileOutputStream(newfile));             document.open();              for (int i = 0; i < files.length; i++) {                  PdfReader 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);                  }              }              retValue = true;          } catch (Exception e) {              e.printStackTrace();          } finally {              document.close();          }          return retValue;      }  

    测试代码(路径要能和你自己的pdf地址对上):

String[] files = { "/Users/hxm/Documents/pdf/audit.pdf", "/Users/hxm/Documents/pdf/template.pdf"};           String savepath = "/Users/hxm/Documents/pdf/newmerge"+ System.currentTimeMillis() +".pdf";           PdfTemplateUtil.mergePdfFiles(files, savepath);

结果:

合并成功。

    如果已经存在一个PDF,你想添加某些属性再生成一个新的PDF文件,如增加水印,加密,设置权限等,这时你就又需要一个方法了,代码如下(其中部分参考一个外国小哥的代码):

public static Boolean addAttributeToPdfFile(String strFileLocation, String strFileLocationOut) {         Boolean isSuccess = false;         try {             // read existing pdf             com.itextpdf.text.pdf.PdfReader reader = new com.itextpdf.text.pdf.PdfReader(strFileLocation);             PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(strFileLocationOut));              stamper.setEncryption(null, null, PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);             // text watermark             Font FONT = new Font(Font.FontFamily.HELVETICA, 34, Font.BOLD, new GrayColor(0.5f)); //            Phrase p = new Phrase("Memorynotfound (watermark)", FONT);             BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);             Font font = new Font(bfChinese, 30, Font.BOLD, new GrayColor(0.90f));             Phrase p = new Phrase("(watermark)", font);              // image watermark //            Image img = Image.getInstance(imgUrl); //            float w = img.getScaledWidth(); //            float h = img.getScaledHeight();              // properties             PdfContentByte over;             Rectangle pagesize;             float x, y;              // loop over every page             int n = reader.getNumberOfPages();             for (int i = 1; i <= n; i++) {                 // get page size and position //                pagesize = reader.getPageSizeWithRotation(i); //                x = (pagesize.getLeft() + pagesize.getRight()) / 2; //                y = (pagesize.getTop() + pagesize.getBottom()) / 2;                 over = stamper.getUnderContent(i);                 over.saveState();                  // set transparency                 PdfGState state = new PdfGState();                 state.setFillOpacity(0.2f);                 over.setGState(state);  //                ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, x, y, 0);                 //控制水印的显示效果,可以自己调整看看                 float beginPositionX = 10, beginPositionY = 70, distance = 175;                 for (int i2 = 0; i2 < 4; i2++) {                     for (int j = 0; j < 4; j++) {                         ColumnText.showTextAligned(over, Element.ALIGN_LEFT,                                 p, beginPositionX + distance*i2, beginPositionY + distance*j, 25);                                              }                 }                 // add watermark text and image //                if (i % 2 == 1) { //                    ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, x, y, 0); //                } else { //                    over.addImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2)); //                }                  over.restoreState();             }             stamper.close();             reader.close();             isSuccess = true;         } catch (DocumentException e) {             // TODO Auto-generated catch block             e.printStackTrace();         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         } finally {             return isSuccess;         }     }

测试代码:

 PdfUtils.addAttributeToPdfFile("/Users/hxm/Documents/pdf/newmerge1527731906780.pdf",                 "/Users/hxm/Documents/pdf/mytemplate.pdf");

效果如下:

    另外注意点是我上面的几个方法都放在一个叫PdfUtils的类中。大概结构如下:

package pdf;  import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import java.util.Map;  import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.Font; import com.itextpdf.text.Phrase; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.AcroFields; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.ColumnText; import com.itextpdf.text.pdf.GrayColor; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfGState; import com.itextpdf.text.pdf.PdfStamper; import com.itextpdf.text.pdf.PdfWriter; import com.lowagie.text.Document; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; /**  * pdf工具类  *  * @author hxm  */ public class PdfUtils { }

    上面就是这些常用方法了,因为要用到本人也网上搜索了很多资料,看了很多,最后特地整理一下,也以备自己以后查询之用处。

本文发表于2018年06月01日 12:00
(c)注:本文转载自https://my.oschina.net/itazi/blog/1822301,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2816 讨论 1 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1