itext 5 根据模板生成PDF util类

 是根据pdf模板生成的 ,pdf模板需配置文本域 ,这个可以去看下其他博客

这个是根据 itext 5.4

	            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>5.4.3</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itext-asian</artifactId>
                <version>5.2.0</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf.tool</groupId>
                <artifactId>xmlworker</artifactId>
                <version>5.4.1</version>
            </dependency>

目前提供了两个生成的方式,一个是直接导出,一个是生成到固定路径

util可直接使用,util包含字体大小自适应

package com.cfam.utils;


import com.cfam.config.BaseException;
import com.cfam.enums.RunExceptionEnum;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;


import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Map;

/**
 * @Description: PDF生成
 * @author:yjt
 * @date:2021/10/12 10:34
 */
@Slf4j
public class PDFUtil {


    /**
     * 字体大小
     */
    private static final float TEXT_SIZE = 6.3f;
    /**
     * 自适应字体大小
     */
    private static final float TEXT_SIZE_ADAPT = 0f;

    /**
     * @param fontPath     字体路径
     * @param templatePath 模板路径
     * @param name         文件名称
     * @param sourceMap    数据MAP
     * @param response     HttpServletResponse
     * @Description: 导出PDF
     * @Return: void
     * @Author: yjt
     * @Date: 2021/10/26
     */
    public static void exportPdf(String fontPath, String templatePath, String name, Map<String, Object> sourceMap, HttpServletResponse response) {
        OutputStream toClient = null;
        try {
            byte[] pdf = createPdf(fontPath, templatePath, sourceMap);
            if (pdf == null) {
                log.info("生成PDF字节数据为空");
                throw new BaseException(RunExceptionEnum.PDF_CREATE_NULL);
            }
            //下载文件
            response.reset();
            // 设置response的Header
            String fileName = URLEncoder.encode((name + "." + "pdf"), "UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.addHeader("Content-Length", "" + pdf.length);
            toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(pdf);
            toClient.flush();
            toClient.close();
        } catch (Exception e) {
            log.error("exportPdf 异常 ==> ", e);
        } finally {
            try {
                if (null != toClient) {
                    toClient.close();
                }
            } catch (Exception e) {
                log.error("finally时 exportPdf 异常 ==> ", e);
            }
        }

    }


    /**
     * @param fontPath     字体路径
     * @param templatePath 模板路径
     * @param filePath     生成文件路径
     * @param fileName     生成文件名称
     * @param sourceMap    数据MAP
     * @Description: 根据路径生成PDF
     * @Return: void
     * @Author: yjt
     * @Date: 2021/10/26
     */
    public static void pathPdf(String fontPath, String templatePath, String filePath, String fileName, Map<String, Object> sourceMap) {
        FileOutputStream fos = null;
        try {
            byte[] pdf = createPdf(fontPath, templatePath, sourceMap);
            if (pdf == null) {
                log.info("生成PDF字节数据为空");
                throw new CustomException("生成PDF字节数据为空");
            }
            File path = new File(filePath);
            if (!path.isDirectory()) {
                path.mkdirs();
            }
            //最终生成的文件,
            fos = new FileOutputStream(filePath + "\\" + fileName + "." + "pdf");
            fos.write(pdf);
         
        } catch (Exception e) {
            log.error(" pathPdf 异常 ==> ", e);
           
        } finally {
            try {
                if (null != fos) {
                    fos.close();
                }
            } catch (Exception e) {
                log.error("finally时 pathPdf 异常 ==> ", e);
            }
        }
    }

    /**
     * @param fontPath     字体路径
     * @param templatePath 模板路径
     * @param sourceMap    数据Map
     * @Description: 创建pdf
     * @Return: 返回一个数据字节数组
     * @Author: yjt
     * @Date: 2021/10/26
     */
    public static byte[] createPdf(String fontPath, String templatePath, Map<String, Object> sourceMap) {
        PdfStamper ps = null;
        PdfReader reader = null;
        ByteArrayOutputStream bos = null;
        try {
            // pdf模板所在路径
            try {
                reader = new PdfReader(templatePath);
            } catch (IOException e) {
                log.error("pdf 模板路径异常 ==> ", e);
                throw new BaseException(RunExceptionEnum.PDF_TEMPLATES_PATH_NULL);
            }
            bos = new ByteArrayOutputStream();
            ps = new PdfStamper(reader, bos);
            //这是设置字体
            BaseFont bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            ArrayList<BaseFont> fontList = new ArrayList<>();
            fontList.add(bf);
            AcroFields fields = ps.getAcroFields();
            fields.setSubstitutionFonts(fontList);
            fillData(bf,fields, sourceMap);
            //必须要调用这个,否则文档不会生成的
            ps.setFormFlattening(true);
            ps.close();
            return bos.toByteArray();
        } catch (Exception e) {
            log.error("创建pdf 异常 ==> ", e);
        } finally {
            try {
                if (null != ps) {
                    ps.close();
                }
                if (null != reader) {
                    reader.close();
                }
                if(null != bos){
                    bos.close();
                }
            } catch (Exception e) {
                log.error("finally时 创建pdf 异常 ==> ", e);
            }
        }
        return null;
    }


    /**
     * 填充模板中的数据
     */
    public static void fillData(BaseFont bf,AcroFields fields, Map<String, Object> dataMap) {
        try {
            for (String key : dataMap.keySet()) {
                // 为字段赋值,注意字段名称是区分大小写的
                String value = String.valueOf(dataMap.get(key));
                fields.setFieldProperty(key, "textsize",  getFontSize( bf, fields,key,value,TEXT_SIZE), null);
                fields.setField(key, (null != value && !"".equals(value) ? value : "------"));

            }
        } catch (Exception e) {
            log.error("pdf 数据放入异常 ==> ", e);
            throw new BaseException(RunExceptionEnum.PDF_DATA_ERROR);
        }
    }

    /**
     * 获取字体大小
     * @param bf 字体
     * @param fields 通过方法调用或 FDF 合并查询和更改现有文档中的字段
     * @param key 数据 key
     * @param value 数据 value
     * @param fontSize 字体要求大小
     * @return 字体计算大小
     */
    public static float getFontSize(BaseFont bf,AcroFields fields,String key,String value,float fontSize){
        Rectangle position = null;
        try {
            position = fields.getFieldPositions(key).get(0).position;
        } catch (Exception e) {
        }
        if(position != null){
            // 文本框宽度
            float textBoxWidth = position.getWidth();
            // 文本框高度
            float textBoxHeight = position.getHeight();
            // 文本单行行高
            float ascent = bf.getFontDescriptor(BaseFont.ASCENT,fontSize);
            // baseFont渲染后的文字宽度
            float textWidth = bf.getWidthPoint(value, fontSize);

            if((textBoxWidth * textBoxHeight)/value.length() < (ascent*(textWidth/value.length())*1.7f)){
                //TEXT_SIZE_ADAPT == 0f;
                return TEXT_SIZE_ADAPT;
            }
        }
        return fontSize;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值