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
    评论
根据提供的引用内容,可以使用Java实现根据模板生成并导出PDF的功能。具体步骤如下: 1.使用JavaPDF库,例如iText或Apache PDFBox,读取PDF模板文件。 2.使用模板文件中的参数,填充PDF表单字段或者在PDF页面上添加文本、图片等内容。 3.将填充后的PDF文件导出到指定的路径。 下面是一个使用iText库实现根据模板导出PDF的示例代码: ```java import com.itextpdf.text.Document; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import java.io.FileOutputStream; import java.util.Map; public class PdfGenerator { public static void generatePdf(String templatePath, String outputPath, Map<String, String> params) throws Exception { // 读取PDF模板文件 PdfReader reader = new PdfReader(templatePath); // 创建输出流 FileOutputStream fos = new FileOutputStream(outputPath); // 创建PDF文档对象 Document document = new Document(); // 创建PDF写入器 PdfCopy copy = new PdfCopy(document, fos); // 打开文档 document.open(); // 填充PDF表单字段 PdfStamper stamper = new PdfStamper(reader, fos); for (Map.Entry<String, String> entry : params.entrySet()) { stamper.getAcroFields().setField(entry.getKey(), entry.getValue()); } stamper.setFormFlattening(true); stamper.close(); // 将填充后的PDF文件导出到指定的路径 for (int i = 1; i <= reader.getNumberOfPages(); i++) { PdfImportedPage page = copy.getImportedPage(new PdfReader(reader), i); copy.addPage(page); } document.close(); reader.close(); fos.close(); } } ``` 其中,`templatePath`为PDF模板文件的路径,`outputPath`为导出的PDF文件的路径,`params`为填充PDF表单字段的参数。可以根据实际需求修改代码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值