近况
好长时间没有写博客了,前几个月都在准备软考,白天上班敲代码,晚上回家学软考,确实有点累啊
没有太多时间专门去学习,当然也是我太懒了,我从写博客中得到的快乐越来越少了,因为我想要的更清楚了
唯一让我坚持下去的可能是,单纯当做笔记记录一下,以免以后忘记又要重新找资料学习。
之后我大概会写一些类库的使用,网上一大堆类似的博客,我收集一些写的不错的博客贴上来,
另外我也自己尝试使用一下这些类库,文章最末尾的链接就是一些测试代码
市面上PDF类库介绍
目前行业内有很多类库可以使得Java去操作PDF,例如PDFBox,iText5,iText7,OpenPDF
这些类库区别如下:
1. PDFBox的功能相对较弱,iText5和iText7的功能非常强悍;
2. iText5的资料网上相对较多,如果出现问题容易找到解决方案;PDFBox和iText7的网上资料相对较少,如果出现问题不易找到相关解决方案;
3. 通过阅读PDFBox代码目前PDFBox还没提供自定义签章的相关接口;iText5和iText7提供了处理自定义签章的相关实现
4. PDFBox只能实现把签章图片加签到PDF文件;iText5和iText7除了可以把签章图片加签到PDF文件,还可以实现直接对签章进行绘制,把文件绘制到签章上。
5. PDFBox和iText5/iText7使用的协议不一样。PDFBox免费使用,AGPL商用收费
6. OpenPDF是基于itext4开发的开源的jar,itext5也是基于itext4开发,itext5是部分开源,部分收费,且官方不再更新维护,需要引入的包多,itext7绝大部分功能收费了
Maven依赖
导入iText7依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.7</version>
<type>pom</type>
</dependency>
导入iText5依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.10</version>
</dependency>
<!--中文支持-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
导入pdfbox依赖,pdfbox也需要导入iText5的依赖
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
</dependency>
iText库中常用类

PDFBox的使用
使用pdfBox填充PDF模板是个不错的方式
1.制作PDF模板,使用Acrobat DC软件制作,下面是阿里云盘的资源
Adobe Acrobat DC 2021 SP.exe https://www.aliyundrive.com/s/WBdUC3oCgh5 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。
安装好软件后,搜索功能:表单工具或者准备表单,打开待制作的pdf,在需要填充数据的地方添加文本域
设置变量名,之后代码中会根据文本域的变量名去填充数据,也可以对文本域设置一些样式。2.编写代码
public class iText5 { public static void main(String[] args) { //往map中填充数据,键就是我们在生成模版的时候,里面的fieldName,value就是要填充的数据 HashMap map = new HashMap<String, String>(30); //填充图片,传入的是一个图片的url地址,但实际上,是要传下图片的byte[]数据, // 在工具类中,会先获取图片的byte数据,然后,再往pdf里面填充,具体可以参照工具方法中的备注 //map.put("signImage", "https://ls.resource.penrose.com.cn/"); //模版PDF文件的地址 String sourceFile = "C:\\Users\\Coco\\Desktop\\template2.pdf"; //填充以后,生成的PDF文件 String targetFile = "C:\\Users\\Coco\\Desktop\\testForm_fill2.pdf"; //调用工具方法 try { genPdf(map, sourceFile, targetFile); } catch (IOException e) { e.printStackTrace(); } } /** * 生成PDF文件 * @param map 要往模版中填充的数据 * @param sourceFile 模版PDF文件的路径 * @param targetFile 填充数据以后,生成的PDF的文件路径 * @throws IOException */ 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对应 */ public static void fillParam(Map<String, String> fieldValueMap, byte[] file, String contractFileName) { FileOutputStream fos = null; String TTF_PATH = "C:\\WINDOWS\\Fonts\\SimHei.ttf"; try { fos = new FileOutputStream(contractFileName); PdfReader reader = null; PdfStamper stamper = null; BaseFont base; try { reader = new PdfReader(file); stamper = new PdfStamper(reader, fos); stamper.setFormFlattening(true); //获取字体文件,TTF_PATH表示字体文件的路径 base = BaseFont.createFont(TTF_PATH, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); //获取模板中待填充的字段并设置字体样式 AcroFields acroFields = stamper.getAcroFields(); /*for (Object key : acroFields.getFields().keySet()) { //设置字体 acroFields.setFieldProperty((String) key, "textfont", base, null); //设置字体大小 acroFields.setFieldProperty((String) key, "textsize", new Float(8), null); }*/ if (fieldValueMap != null) { for (String fieldName : fieldValueMap.keySet()) { //填充其它文本数据 acroFields.setField(fieldName, fieldValueMap.get(fieldName)); //填充图片 /*if (fieldName.equals("signImage")) { //这里先获取图片的byte数据 byte[] bytes = PDFUtil.getImage(fieldValueMap.get(fieldName)); if (bytes != null) { int pageNo = acroFields.getFieldPositions(fieldName).get(0).page; Rectangle signRect = acroFields.getFieldPositions(fieldName).get(0).position; float x = signRect.getLeft(); float y = signRect.getBottom(); // 读图片 Image image = Image.getInstance(bytes); // 获取操作的页面 PdfContentByte under = stamper.getOverContent(pageNo); // 根据域的大小缩放图片 image.scaleToFit(signRect.getWidth(), signRect.getHeight()); // 添加图片 image.setAbsolutePosition(x, y); under.addImage(image); stamper.setFormFlattening(true); } } else { }*/ } } } 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) { e.printStackTrace(); } finally { IOUtils.closeQuietly(fos); } } }
文章推荐