ITPub博客

首页 > 应用开发 > Java > java 利用pdf模板生成PDF文件

java 利用pdf模板生成PDF文件

Java 作者:xz43 时间:2023-03-09 22:45:36 0 删除 编辑

首先如果是 maven 项目的话需要添加以下依赖,普通项目的话在官网( http://itextpdf.com/ )下载对应的jar包加入即可。若是maven项目,添加依赖如下:

<!-- pdf 操作 -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.3</version>
        </dependency>
        <!-- 条码生成与二维码生成 -->
        <dependency>
            <groupId>net.sf.barcode4j</groupId>
            <artifactId>barcode4j</artifactId>
            <version>2.1</version>
        </dependency>

操作工具类1:

package com.hong.webTest.common.util;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Description  可实现单个PDF模板重复使用生成同一个PDF文件
 * @Author
 * @Date
 * @Version 1.0
 **/
// @Slf4j
public class PdfUtil {
    /**
     * 模板阅读器
     */
    private String templatePath;
    /**
     *
     */
    private List<byte[]> outList;
    /**
     * 基准字体
     */
    private BaseFont bf;
    /**
     * 创建PDF处理对象
     * @param templatePath
     * @param fontPath
     * @return
     */
    @SneakyThrows
    public static PdfUtil create(String templatePath,String fontPath){
        PdfUtil pdf = new PdfUtil();
        // 读取pdf模板
        pdf.templatePath = templatePath;
        pdf.bf = BaseFont.createFont(fontPath , BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        return pdf;
    }
    /**
     * 获取结果
     * @return
     */
    @SneakyThrows
    public ByteArrayOutputStream getOutputStream(){
        if (outList == null) {
            return null;
        }
        Document doc = new Document();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PdfCopy copy = new PdfCopy(doc, out);
        doc.open();
        for (byte[] array:outList) {
            PdfReader reader = new PdfReader(array);
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                PdfImportedPage importPage = copy.getImportedPage(reader,i);
                copy.addPage(importPage);
            }
            reader.close();
        }
        doc.close();
        return out;
    }
    @SneakyThrows
    public void copyPage(Map<String,String> strMap, Map<String,Image> imgMap){
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        PdfReader reader = new PdfReader(templatePath);
        PdfStamper stamper = new PdfStamper(reader, bos);
        AcroFields form = stamper.getAcroFields();
        //文字类的内容处理
        form.addSubstitutionFont(bf);
        strMap.forEach((k,v)->{
            try {
                form.setField(k,v);
            } catch (Exception e) {}
        });
        // 图片类的内容处理
        imgMap.forEach((k,v)->{
            try {
                int pageNo = form.getFieldPositions(k).get(0).page;
                Rectangle signRect = form.getFieldPositions(k).get(0).position;
                float x = signRect.getLeft();
                float y = signRect.getBottom();
                //读取图片
                Image image = v;
                //获取图片页面
                PdfContentByte under = stamper.getOverContent(pageNo);
                //图片大小自适应
                image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                //添加图片
                image.setAbsolutePosition(x, y);
                under.addImage(image);
            } catch (Exception e) {}
        });
        // 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
        stamper.setFormFlattening(true);
        stamper.close();
        reader.close();
        if (outList == null){
            outList = new ArrayList<>(8);
        }
        outList.add(bos.toByteArray());
    }
    /*public static void main(String[] args) throws IOException {
        PdfUtil pdfUtil = PdfUtil.create("static/temp/code.pdf", "static/fonts/simhei.ttf");
        for (int i = 0; i < 10; i++) {
            Map<String,String> map = new HashMap();
            map.put("local","0101013A0"+i);
            map.put("count","第 "+i+" 次");
            map.put("boxNo","201901010407600009"+i);
            map.put("deptCode","01010407"+i);
            map.put("deptName","雁塔支行");
            map.put("actCount",i+"");
            Map<String,Image> map1 = new HashMap();
            map1.put("code",Image.getInstance(BarCodeUtil.getInstanceImage("201901010407600009"+i)));
            pdfUtil.copyPage(map,map1);
        }
        ByteArrayOutputStream outputStream = pdfUtil.getOutputStream();
        FileOutputStream fileOutputStream = new FileOutputStream("G:/Test/code123.pdf");
        fileOutputStream.write(outputStream.toByteArray());
        fileOutputStream.close();
    }*/
}

操作工具类2:

package com.hong.webTest.common.util;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.SneakyThrows;
import java.io.ByteArrayOutputStream;
import java.util.Map;
/**
 * @Description 单个模板单个生成
 * @Author
 * @Date
 * @Version 1.0
 **/
public class PdfUtil1 {
    @SneakyThrows
    public static byte[] pdfCreate(String templatePath, String fontPath, Map<String,String> strMap, Map<String,Image> imgMap){
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        PdfReader reader = new PdfReader(templatePath);
        PdfStamper stamper = new PdfStamper(reader, bos);
        AcroFields form = stamper.getAcroFields();
        //文字类的内容处理
        BaseFont bf = BaseFont.createFont(fontPath , BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        form.addSubstitutionFont(bf);
        strMap.forEach((k,v)->{
            try {
                form.setField(k,v);
            } catch (Exception e) {}
        });
        // 图片类的内容处理
        imgMap.forEach((k,v)->{
            try {
                int pageNo = form.getFieldPositions(k).get(0).page;
                Rectangle signRect = form.getFieldPositions(k).get(0).position;
                float x = signRect.getLeft();
                float y = signRect.getBottom();
                //读取图片
                Image image = v;
                //获取图片页面
                PdfContentByte under = stamper.getOverContent(pageNo);
                //图片大小自适应
                image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                //添加图片
                image.setAbsolutePosition(x, y);
                under.addImage(image);
            } catch (Exception e) {}
        });
        // 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
        stamper.setFormFlattening(true);
        stamper.close();
        reader.close();
        Document doc = new Document();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PdfCopy copy = new PdfCopy(doc, out);
        doc.open();
        PdfReader pdfReader = new PdfReader(bos.toByteArray());
        for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
            PdfImportedPage importPage = copy.getImportedPage(pdfReader, i);
            copy.addPage(importPage);
        }
        pdfReader.close();
        doc.close();
        return out.toByteArray();
    }
}

推荐使用第一种工具。
本文实现对内存使用量较大,待后期优化

说明: 因itextpdf5 本身不支持中文,若无中文字体包,会导致生成的PDF文件中文字体显示空白,因此必须引入中文支持。

PDF模板制作


模板制作

1.先用word制作原型模板,如:

模板

制作好后另存为PDF文件。


2.利用Adobe Acrobat X Pro打开原型PDF,制作PDF模板

依次点击 文件>>创建>>创建表单>>选择本文件>>确认

编辑

右键增加文本域并设置key值

在这里插入图片描述

在这里插入图片描述

保存后,模板制作完成。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9399028/viewspace-2938963/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: Swagger Edit介绍
下一篇: JVM优化配置
请登录后发表评论 登录
全部评论
鱼儿的学习空间

注册时间:2010-11-16

  • 博文量
    433
  • 访问量
    1863699