Pdf文本域替换,iText替换pdf文本域

替换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();
            //写一个新的PDF
            Document 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)
    @Documented
    public @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;
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是Java itextpdf设置pdf文本行间距的示例代码: ```java import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Font; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.AcroFields; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import java.io.FileOutputStream; import java.io.IOException; public class SetTextFieldLineSpacing { public static void main(String[] args) throws IOException, DocumentException { // 读取pdf模板文件 PdfReader reader = new PdfReader("template.pdf"); // 创建输出流 FileOutputStream out = new FileOutputStream("output.pdf"); // 创建pdf文档对象 Document document = new Document(); // 创建pdf写入器 PdfStamper stamper = new PdfStamper(reader, out); // 获取pdf表单 AcroFields form = stamper.getAcroFields(); // 设置字体 BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font f = new Font(font, 12); // 设置文本内容 form.setField("text_field", "这是一段测试文本,\n第二行,\n第三行。"); // 设置文本字体 form.setFieldProperty("text_field", "textfont", font, null); // 设置文本字体大小 form.setFieldProperty("text_field", "textsize", 12f, null); // 设置文本字体颜色 form.setFieldProperty("text_field", "textcolor", new java.awt.Color(0, 0, 0), null); // 设置文本行间距 form.setFieldProperty("text_field", "leading", 20f, null); // 关闭pdf写入器 stamper.close(); // 关闭输出流 out.close(); // 关闭pdf模板文件 reader.close(); } } ``` 在上述代码中,我们使用了`setFieldProperty()`方法来设置文本的行间距,其中`"leading"`参数用于设置行间距的大小,单位为磅(pt)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT界的老菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值