java生成pdf

java生成pdf

  • 说明
  • 使用Adobe acrobat pro DC制作pdf模板表单
  • 使用java生成pdf

说明

先利用Adobe acrobat pro DC对pdf进行表单制作,再通过利用java对模板数据进行填充,并生成新的pdf

使用Adobe acrobat pro DC制作pdf模板表单

下载地址参考:Adobe acrobat pro DC2018解决方案

  1. 打开模板pdf
    java生成pdf_第1张图片
  2. 点击准备表单
    java生成pdf_第2张图片
  3. 添加文本域
    java生成pdf_第3张图片
  4. 设置对应属性
    java生成pdf_第4张图片
    java生成pdf_第5张图片
  5. 保存

使用java生成pdf

  1. 依赖

    com.itextpdf
    itextpdf
    5.5.10



    com.itextpdf
    itext-asian
    5.2.0

  1. 生成pdf工具类
import cn.hutool.core.collection.CollUtil;
import com.intellsite.digital.dto.SealPosition;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * desc: pdf 生成工具
 *
 * @author qts
 * @date 2022/3/18 0018
 */
@Slf4j
public class PdfGenerateUtil {

    private PdfGenerateUtil() {
    }

    /**
     * 获取字段对应的坐标信息
     * 

{@link com.intellsite.digital.dto.SealPosition}

中只返回了:页码和x,y坐标 * * @param templatePdfByteArray 模板pdf字节数组 * @param paramsName 参数名称 * @return 映射 key:字段名 value:坐标信息 */ public static Map getPositions(byte[] templatePdfByteArray, Set paramsName) { PdfReader reader = null; ByteArrayOutputStream bos = null; try { Map sealMap = new HashMap(); //创建书写器,用于往document中书写信息 // 通过本地文件路径获取资源 reader = new PdfReader(templatePdfByteArray); bos = new ByteArrayOutputStream(); PdfStamper stamper = new PdfStamper(reader, bos); // pdf表单字段 AcroFields form = stamper.getAcroFields(); // 通过名字获取位置 SealPosition sealPosition; for (String name : paramsName) { List positions = form.getFieldPositions(name); if (CollUtil.isEmpty(positions)) { sealMap.put(name, null); continue; } // 页码 int pageNo = positions.get(0).page; // 矩形 Rectangle rectangle = positions.get(0).position; // x/y坐标 BigDecimal right = new BigDecimal(String.valueOf(rectangle.getRight())); BigDecimal left = new BigDecimal(String.valueOf(rectangle.getLeft())); BigDecimal top = new BigDecimal(String.valueOf(rectangle.getTop())); BigDecimal bottom = new BigDecimal(String.valueOf(rectangle.getBottom())); float x = right.subtract(left).divide(new BigDecimal("2"),3,BigDecimal.ROUND_HALF_UP).floatValue(); float y = top.subtract(bottom).divide(new BigDecimal("2"),3,BigDecimal.ROUND_HALF_UP).floatValue(); sealPosition = new SealPosition().setPageNum(pageNo).setPosX(x).setPosY(y); sealMap.put(name, sealPosition); } stamper.setFormFlattening(false); stamper.close(); return sealMap; } catch (Exception e) { log.error("通过模板生成PDF失败", e.getMessage()); return null; } finally { try { if (null != reader) { reader.close(); } if (null != bos) { bos.close(); } } catch (IOException e) { log.error("close resource error", e.getMessage()); } } } /** * 生成填充了模板参数的pdf * * @param templatePdfInputStream 模板pdf流 * @param paramsMap 填充参数 * @return */ public static byte[] generatePdf(InputStream templatePdfInputStream,Map paramsMap) throws IOException { byte[] templatePdfByteArray = readBytes(templatePdfInputStream); return generatePdf(templatePdfByteArray, paramsMap); } /** * 生成填充了模板参数的pdf * * @param templatePdfByteArray 模板pdf字节数组 * @param paramsMap 填充参数 * @return */ public static byte[] generatePdf(byte[] templatePdfByteArray, Map paramsMap) { PdfReader reader = null; ByteArrayOutputStream bos = null; try { //创建书写器,用于往document中书写信息 // 通过本地文件路径获取资源 reader = new PdfReader(templatePdfByteArray); bos = new ByteArrayOutputStream(); PdfStamper stamper = new PdfStamper(reader, bos); //使用中文字体 BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); ArrayList fontList = new ArrayList<>(); fontList.add(baseFont); AcroFields form = stamper.getAcroFields(); form.setSubstitutionFonts(fontList); for (String fieldName : paramsMap.keySet()) { if (paramsMap.get(fieldName) == null) { continue; } if (fieldName.indexOf("Image") > 0) { String imgPath = paramsMap.get(fieldName).toString(); int pageNo = form.getFieldPositions(fieldName).get(0).page; Rectangle rectangle = form.getFieldPositions(fieldName).get(0).position; float x = rectangle.getLeft(); float y = rectangle.getTop(); //根据路径读取图片 Image image = Image.getInstance(imgPath); //获取图片页面 PdfContentByte under = stamper.getOverContent(pageNo); //图片大小自适应 image.scaleToFit(rectangle.getWidth(), rectangle.getHeight()); //添加图片 image.setAbsolutePosition(x, y - rectangle.getHeight()); under.addImage(image); } else { // 设置占位字段 form.setField(fieldName, paramsMap.get(fieldName).toString()); } } stamper.setFormFlattening(false); stamper.close(); } catch (Exception e) { log.error("通过模板生成PDF失败", e.getMessage()); return null; } finally { try { if (null != reader) { reader.close(); } if (null != bos) { bos.close(); } } catch (IOException e) { log.error("close resource error", e.getMessage()); } } return bos.toByteArray(); } /** * 读取输入流到字节数组 * * @param in * @return * @throws IOException */ private static byte[] readBytes(InputStream in) throws IOException { //读取字节的缓冲 byte[] buffer = new byte[1024]; //最终的数据 byte[] result = new byte[0]; int size = 0; while ((size = in.read(buffer)) != -1) { int oldLen = result.length; byte[] tmp = new byte[oldLen + size]; if (oldLen > 0) {//copy 旧字节 System.arraycopy(result, 0, tmp, 0, oldLen); } //copy 新字节 System.arraycopy(buffer, 0, tmp, oldLen, size); result = tmp; } return result; } }
  1. 对应实体
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * @description: 签章位置信息
 * @author: wkh
 * @create: 2022-03-17 11:29
 */
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class SealPosition {
    /**
     * 签章id
     */
    private Long sealId;
    /**
     * x
     */
    private Float posX;
    /**
     * y
     */
    private Float posY;
    /**
     * 关键字
     */
    private String keyword;

    /**
     * 页码
     */
    private int pageNum;
}
  1. 使用工具类
    以下为关键代码
InputStream pdfInputStream = null;
try {
    // pdf模板
    pdfInputStream = new FileInputStream("D:\\监理日志模板.pdf");

    // 设置pdf模板参数  engineeringLog为实体类,其中的字段对应pdf表单中的字段名称
    JSONObject paramsMap = JSONObject.parseObject(JSON.toJSONString(engineeringLog));
    paramsMap.put("dairyDate", DateUtil.format(engineeringLog.getDairyDate(),"yyyy年MM月dd日"));

    // 生成pdf字节数组
    byte[] pdf = PdfGenerateUtil.generatePdf(pdfInputStream, paramsMap);
	
	// 准换成MultipartFile 
	MultipartFile multipartFile = new MockMultipartFile("file","模板.pdf","text/plain", pdf);
	
	// todo 后续处理 ,可以上传到文件服务器或其他操作
    

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}   finally {

    try {
        if (null != pdfInputStream) {
            pdfInputStream.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}

你可能感兴趣的:(问题解决,常用,java)