根据模板导出或预览pdf文件(导出一个pdf文件,多页内容,每页可以使用不用模板)

maven引入itextpdf依赖

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

PDF导出需要的数据,利用反射封装数据

     /**
     *
     * @param obj   需要转换的数据
     * @param templateList  模板集合
     * @return  List<Map<String, String>>
     * @throws IllegalAccessException
     */
    public List<Map<String, String>> dataList(Object obj, List<String> templateList) throws IllegalAccessException {
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        List<Map<String, String>> dataList = new ArrayList<Map<String, String>>();

        for (String template : templateList) {
            Map<String, String> map = new HashMap<String, String>();
            //设置模板
            map.put("template", template);

            //设置数据
            for (Field field : fields) {
                field.setAccessible(true);

                //数据对象成员对象的名字
                String key = field.getName();
                //数据对象成员对象的值
                String value = field.get(obj).toString();
                map.put(key, value);

                field.setAccessible(false);
            }

            dataList.add(map);
        }
        return dataList;
    }

在Resources下获取模板需要注意

错误方法

        /**
         * 错误方法,在本地环境下是正常的,但是打包上生产之后是找不到模板的
         */
        String path1 = getClass().getClassLoader().getResource("resources下的路径").toURI().getPath();

        /**
         * 错误方法,打包后可以获取模板,但是获取的路径,可能会出现 “%” 的乱码,导致最终获取模板失败
         */
        String path2 = new ClassPathResource("resources下的路径").getURL().getPath();

正确的方法

        /**
         * 正确方法,获取的相对路径
         */
        String path1 = new ClassPathResource("resources下的路径").getPath();

        /**
         * 正确的方法,获取的是绝对路径
         */
        String path2 = new ClassPathResource("resources下的路径").getURI().getPath();

PDF工具类代码

public class PdfUtil {
    //导出PDF文件
    public static final int TYPE_OF_EXPORT = 0;
    //预览PDF文件
    public static final int TYPE_OF_PREVIEW = 1;

    /**
     *
     * @param dataList 数据集合
     * @param fileName  文件名
     * @param type  操作类型,导出或者预览
     * @param response HttpServletResponse
     */
    public static void exportOrPreviewPdf(List<Map<String, String>> dataList, String fileName, int type, HttpServletResponse response) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        Document doc = new Document();

        ServletOutputStream out = null;
        PdfCopy copy ;

        try {
            //设置浏览器输出相关配置
            response.reset();
            response.setContentType("application/pdf");

            //设置是否导出PDF文件
            if (type == TYPE_OF_EXPORT) {
                response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".pdf").getBytes(), "iso-8859-1"));
            }

            // 输出流
            out = response.getOutputStream();
            copy = new PdfCopy(doc, out);
            doc.open();

            for (Map<String, String> map : dataList) {
                // 读取pdf模板
                PdfReader reader = new PdfReader(map.get("template"));
                PdfStamper stamper = new PdfStamper(reader, bos);

                AcroFields form = stamper.getAcroFields();

                //读取数据设置到PDF模板中
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    form.setField(entry.getKey(), entry.getValue());
                }
                // 如果为false那么生成的PDF文件还能编辑,一定要设为true
                stamper.setFormFlattening(true);

                stamper.flush();
                stamper.close();
                reader.close();

                PdfReader pdfReader = new PdfReader(bos.toByteArray());
                PdfImportedPage importPage = copy.getImportedPage(pdfReader, 1);

                copy.addPage(importPage);
                pdfReader.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            doc.close();
            try {
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                bos.flush();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

参考文章:https://blog.youkuaiyun.com/zhangxg_cq/article/details/80923056

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值