替换pdf字段主要工具

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version>
</dependency>

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.owinfo.mpw.cash.service.entity.vo.DeclarationPdfVO;
import com.owinfo.mpw.cash.service.entity.vo.PdfAttributeVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.List;/*** <p>** @author * @version v1* @create 2020-09-30 11:18:11* */
public class PdfUtils {/**** @param fontPath 字体库的路径 C:\Windows\Fonts\simhei.ttf,simhei.ttf这个名字的来源,找个字体文件,右键属性,就可以看到这中名字了* @return* @throws Exception*/private static BaseFont getBaseFont(String fontPath) throws Exception{return BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);}/**** @param declarationPdfVO 替换信息* @param fontPathes 字体的文件路径,放在配置中心得* @param path 模本文件路径* @param tempFile 生成临时文件的路径* @return 返回生成文件的名称* @throws Exception*/public static String getPDF(DeclarationPdfVO declarationPdfVO, String[] fontPathes, String path, String tempFile) throws Exception {//模板文件String templatePath = path + "cashpdf.pdf";//生成的新文件String pdfName = declarationPdfVO.getFormSerialNum() + "-" + declarationPdfVO.getName() + BaseUtils.formatDateYMDHMss(new Date()) + ".pdf";String targetPath = tempFile + pdfName;Map<String, PdfAttributeVO> replaceMap = new HashMap<>(10);getReplaceMap(declarationPdfVO, replaceMap);getReplaceMap(declarationPdfVO.getBody1(), replaceMap);getReplaceMap(declarationPdfVO.getBody2(), replaceMap);getReplaceMap(declarationPdfVO.getBody3(), replaceMap);PdfReader reader = null;try {ByteArrayOutputStream bos = new ByteArrayOutputStream();FileOutputStream out = new FileOutputStream(targetPath);//读取PDF模板reader = new PdfReader(templatePath);PdfStamper stamper = new PdfStamper(reader, bos);//获取所有的表单域AcroFields form = stamper.getAcroFields();Iterator<String> it = form.getFields().keySet().iterator();while (it.hasNext()) {String name = it.next();PdfAttributeVO pdfAttribute = replaceMap.get(name);if (pdfAttribute == null) {continue;}if (name.startsWith("fill")) {//表示是字段setFieldAndFont(getBaseFont(fontPathes[pdfAttribute.getFontPathIndex()]), stamper, form, pdfAttribute.getValue(), pdfAttribute.getFontSize(), pdfAttribute.getFontPosition(), name);} else {//表示是复选框form.setField(name, pdfAttribute.getValue(), true);}}//如果为false那么生成的PDF文件还能编辑 但是不能编辑上面赋的值 可以研究一下//设置为true文档将不可以编辑stamper.setFormFlattening(true);stamper.close();//写一个新的PDFDocument doc = new Document();PdfCopy copy = new PdfCopy(doc, out);doc.open();PdfReader newReader = new PdfReader(bos.toByteArray());copy.addPage(copy.getImportedPage(newReader, 1));copy.addPage(copy.getImportedPage(newReader, newReader.getNumberOfPages()));doc.close();} catch (IOException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();} finally {if (reader != null) {reader.close();}}return pdfName;}/**** @param bf 字体* @param stamp* @param form* @param chunkStr* @param fontSize 字体大小* @param fontPosition 字体在上下方向的位置* @param property*/public static void setFieldAndFont(BaseFont bf, PdfStamper stamp, AcroFields form, String chunkStr, float fontSize, float fontPosition, String property) {try {Font font = new Font(bf, fontSize, -1, new BaseColor(0, 0, 0));List<AcroFields.FieldPosition> list = form.getFieldPositions(property);int page = list.get(0).page;PdfContentByte pdfContentByte = stamp.getOverContent(page);ColumnText columnText = new ColumnText(pdfContentByte);Rectangle rectangle = list.get(0).position;columnText.setSimpleColumn(rectangle);Chunk chunk = null;chunk = new Chunk(chunkStr);Paragraph paragraph = new Paragraph(fontPosition, chunk);columnText.addText(paragraph);paragraph.setFont(font);columnText.addElement(paragraph);columnText.go();} catch (DocumentException e) {e.printStackTrace();}}//映射字段@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Mapping {//pdf表单字段String field();//文字在上下方向的位置float fontPosition() default 14f;//文字大小float fontSize() default 8.52f;//是否需要做字体大小缩放boolean flag() default false;//字符串数量判断范围int[] range() default {};//根据字符串数量判断范围来取的字体大小float[] rangeValue() default {};//字体路径,这里是配置文件的下标int fontPathIndex() default 0;}/*** 将表单上的字段和实体值对应上,返回map,做替换** @param obj pdf表单上的字段映射到实体对象*/public static void getReplaceMap(Object obj, Map<String, PdfAttributeVO> replaceMap) throws Exception {if (obj == null) {return;}Class<PdfUtils.Mapping> mapping = PdfUtils.Mapping.class;Class<?> aClass = obj.getClass();Field[] declaredFields = aClass.getDeclaredFields();for (Field field : declaredFields) {field.setAccessible(true);Object value = field.get(obj);if (field.isAnnotationPresent(mapping)) {PdfUtils.Mapping mapping1 = field.getAnnotation(mapping);if (value != null && (field.getType() == String.class || field.getType() == Integer.class)) {//判断是否检测字符串长度replaceMap.put(mapping1.field(), fontZoom(mapping1, value.toString()));}}}}/*** 判断字体是否缩放** @param mapping*/public static PdfAttributeVO fontZoom(PdfUtils.Mapping mapping, String value) {float fontSize = mapping.fontSize();float fontPosition = mapping.fontPosition();if (mapping.flag()) {int length = BaseUtils.strLength(value);int[] range = mapping.range();float[] rangeValue = mapping.rangeValue();if (length > range[0] && length <= range[1]) {fontSize = rangeValue[0];//fontPosition = fontPosition + 0.6f;} else if (length > range[1]) {fontSize = rangeValue[1];//fontPosition = fontPosition + 1.3f;}}return new PdfAttributeVO(value.toString(), fontPosition, fontSize, mapping.fontPathIndex());}
}

/*** pdf模板的各种属性*/
@Setter
@Getter
@ToString
public class PdfAttributeVO {private String value;/** 字体位置*/private float fontPosition;/** 字体大小*/private float fontSize;/** 字体路径,配置文件中的下标*/private int fontPathIndex;public PdfAttributeVO() {}public PdfAttributeVO(String value, float fontPosition, float fontSize, int fontPathIndex) {this.value = value;this.fontPosition = fontPosition;this.fontSize = fontSize;this.fontPathIndex = fontPathIndex;}
}

注解的用法

/*** 永久居住地* 地址过长,会根据长度缩小字体显示* fill_12:pdf模板中代表地址的字段* flag = true表示要做字体缩放* range = {86, 104} 表示在三个区间缩放,range<=86 或 86<range<=104 或 range >104 ,对应的字体大小分别为:8(默认)/7/6* fontPathIndex:这个参数还未使用,是防止不同的字段会用到不同的字体,我是吧这个放在配置文件中读取的。*/@PdfUtils.Mapping(field = "fill_12", flag = true, range = {86, 104}, rangeValue = {7, 6})private String address;

Pdf文本域替换,iText替换pdf文本域相关推荐

  1. itext生成pdf间距_使用itext生成pdf

    在企业的信息系统中,报表处理一直占比较重要的作用,本文将介绍一种生成PDF报表的Java组件--iText.通过 在服务器端使用Jsp或JavaBean生成PDF报表,客户端采用超级连接显示或下载得到 ...

  2. 【PDF】java使用Itext生成pdf文档--详解

    [API接口] 一.Itext简介 API地址:javadoc/index.html:如 D:/MyJAR/原JAR包/PDF/itext-5.5.3/itextpdf-5.5.3-javadoc/i ...

  3. java设置pdf不可编辑_Java动态生成pdf文件(使用itext编辑pdf)

    一.创建pdf模板 使用PDFelement制作pdf模板(数据域的名称对应后面插入的key) 二.导入maven依赖 com.itextpdf itextpdf 5.5.13 com.itextpd ...

  4. java maven 读写pdf_Java动态生成pdf文件(使用itext编辑pdf)

    一.创建pdf模板 使用PDFelement制作pdf模板(数据域的名称对应后面插入的key) 二.导入maven依赖 com.itextpdf itextpdf 5.5.13 com.itextpd ...

  5. java生成pdf加密_java使用iText 生成PDF全攻略(表格,加密)

    java使用iText 生成PDF全攻略,包括创建文档,设置字体,添加表格(PdfPTable),创建新页(newPage),设置布局,加密 主要使用的jar包: itextpdf-5.4.2.jar ...

  6. java 取pdf 文本域_Java iText填写PDF模版文本域空白问题

    public static void main(String[] args) throws DocumentException, IOException { PdfReader reader = ne ...

  7. java 写数据到pdf模板_java利用itext填写pdf模板并导出

    1.先用word做出界面 2.再转换成pdf格式 3.用Adobe Acrobat 打开你刚刚用word转换成的pdf 会出现如下界面 下一步 点击浏览,选择刚才你转换好的pdf 下一步 4.打开后它 ...

  8. java动态生成pdf文件(使用itext编辑pdf)

  9. itex将html转成pdf加水印,itext操作PDF文件添加水印

    功能描述:添加图片和文字水印 /** * * [功能描述:添加图片和文字水印] [功能详细描述:功能详细描述] * @param srcFile 待加水印文件 * @param destFile 加水 ...

  10. java 生成pdf itext_使用Java组件itext 生成pdf介绍

    iText是一个能够快速产生PDF文件的Java类库.iText的java类对于那些要产生包含文本,表格,图形的只读文档是很有用的.它的类库尤其与java Servlet有很好的给合.使用iText与 ...

最新文章

  1. debian+pxe+preseed.cfg 安装配置
  2. golang 包含 数组_golang 数组
  3. 如何在windows上玩转redis的最新特性?
  4. Pycharm Matplotlib 图像不显示问题
  5. 2015结束,2016开始
  6. java自动转换_java类型转换详解(自动转换和强制转换)
  7. python 定时执行 爬虫 模块_浅析python实现scrapy定时执行爬虫
  8. qt绘图事件(画刷的填充)
  9. oracle 11g ocp 笔记(14)--数据库备份和恢复配置
  10. python创建字符串数组_python – 如何为多处理初始化字符串数组
  11. centos6.8 hugepage设置
  12. 云南省工信厅洪正华一行莅临红谷滩区·高通中国·影创联合创新中心考察调研
  13. 教你配电脑:电脑小白如何选购笔记本电脑,笔记本性能知识,干货来了
  14. 【算法与数据结构】分治(Divid Conquer)算法——以快排,归并排序,二分查找为例
  15. 苹果蓝牙耳机平替哪个好用?苹果蓝牙耳机平替推荐
  16. 嵌入式—LM3S1138介绍
  17. 激活时显示图片上传资源服务器失败,720全景图上传时提示“切图失败”的处理办法...
  18. 微软紧急发布Windows XP/7 WannaCry漏洞补丁
  19. [附源码]计算机毕业设计JAVA旅游网站
  20. 实施化工厂人员定位的原因详解--新导智能

热门文章

  1. Windwos下搭建MongoDB集群
  2. 达人评测 华为MateBook13、14、13s、14s、D14、D15选哪个好 参数对比区别大吗
  3. java中重写的目的是什么_Java课后简答题
  4. pandas 读取excel文件的指定列
  5. 值传递和引用传递,看这篇就够了!!!
  6. 前端布局之移动端布局相关
  7. 我的世界卸载java_《我的世界:地下城》出现恶性BUG 卸载会清空SSD
  8. MySQL体系结构与存储引擎
  9. Collaborative learning network for head pose estimation【Image and Vision Computing 2022】
  10. 前端开发中79条不可忽视的知识点汇总