web项目PDF导出---freemarker 与 ITextRenderer--加页码

南笙酒味 提交于 2019-12-03 18:58:50

最近项目中又遇到pdf导出的需求,以前一直都是用phantomjs-2.1.1-windows.exe插件做的pdf导出,运用插件优点是直接可以把html页面直接转换成pdf导出,缺点是它需要安装,windows、linux、mac等环境下需要的插件安装都不一样,中文字体还需要单独安装;查询了一些文档后就决定采用freemarker 与 ITextRenderer来实现了;偶然间在git看到了flying saucer项目;发现思路基本一致就在其基础上开发了(^_^) 。

freemarker 模板能很好的支持html、css样式;但是运用之前需要小小的学习一下freemarker ftl模板的一些固定语法,这对一般的开发者而言应该都没什么难度(^^)。

下面记录一下用到的方法与运用freemarker 与 ITextRenderer过程的一些坑

  1. ftl模板中中文字体显示
  2. ftl模板中静态资源引入
  3. ftl模板中img显示

@RequestMapping("/createPdf/{corpid}")
    public ResponseEntity<byte[]> createPdf(@PathVariable(value="corpid")String corpid,HttpServletRequest request)
            throws Exception {
Map<Object, Object> o = new HashMap<Object, Object>();
。。。。
//此处省略对o获取数据的过程
//获取ftl模板路径
    String path = request.getSession().getServletContext().getRealPath("WEB-INF/views/page/favorable");
        String uuid = UUID.randomUUID().toString().replace("-", "");

        //设置图片路径,解决找不到图片问题
        String imgUrl = request.getSession().getServletContext().getRealPath("WEB-INF/views/img/cx");

        PdfUtils.generateToFile(request, path, "favorable.ftl", imgUrl + "/", o, path + "/" + uuid + ".pdf");

        File file = new File(path + "/" + uuid + ".pdf");
        // 更改下载名称
        HttpHeaders headers = new HttpHeaders();
        String entName=dto.getEnt_name()+".pdf";
        String fileName = new String(entName.getBytes("GBK"), "iso-8859-1");// 为了解决中文名称乱码问题
        headers.setContentDispositionFormData("attachment", fileName);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        ResponseEntity<byte[]>bytes=     new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
        if (file.isFile() && file.exists()) {
            file.delete();   //删除掉pdf文件
        }
        return bytes;
    }

PdfUtils 生成PDF到文件

/**
     * 生成PDF到文件
     * @param ftlPath 模板文件路径(不含文件名)
     * @param ftlName 模板文件吗(不含路径)
     * @param imageDiskPath 图片的磁盘路径
     * @param data 数据
     * @param outputFile 目标文件(全路径名称)
     * @throws Exception
     */
    public static void generateToFile(HttpServletRequest request,String ftlPath,String ftlName,String imageDiskPath,Object data,String outputFile) throws Exception {
        String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
        OutputStream out = null;
        ITextRenderer render = null;
        out = new FileOutputStream(outputFile);
        render = PdfHelper.getRender(request);
        render.setDocumentFromString(html);
        if(imageDiskPath!=null&&!imageDiskPath.equals("")){
            //render.getSharedContext().setBaseURL("file:/"+imageDiskPath);
//在linux下file:/无法被识别,运用file:///来声明img根目录        

render.getSharedContext().setBaseURL("file:///"+imageDiskPath);
        }
        render.layout();

        render.createPDF(out);
        render.finishPDF();
        render = null;
        out.close();
    }

PdfHelper PDF生成辅助类

    public static ITextRenderer getRender(HttpServletRequest request) throws DocumentException, IOException {

        ITextRenderer render = new ITextRenderer();

         String path = request.getSession().getServletContext()
                .getRealPath("WEB-INF/views/page/resource");
        //添加字体,以支持中文
        render.getFontResolver().addFont(path + "/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        render.getFontResolver().addFont(path + "/SIMSUN.TTC", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);


        return render;
    }

2017-08-28更新—静态打印pdf(pdf内容已知)加页码:

body里加入
        <div id="footer" style="">  Page <span id="pagenumber"/> of <span id="pagecount"/> </div>
样式上加入
@page {
size:210mm 297mm;//纸张大小A4
margin: 0.25in;
-fs-flow-bottom: "footer";
-fs-flow-left: "left";
-fs-flow-right: "right";
border: thin solid black;
padding: 1em;
}
#footer {
font-size: 90%; font-style: italic;
position: absolute; top: 0; left: 0;
-fs-move-to-flow: "footer";
}
#pagenumber:before {
content: counter(page);
}
#pagecount:before {content: counter(pages);
}

以上部分的pdf添加页码,只适合对静态页面添加(知道内容或者页数固定的页面);对于动态页面的页码添加需要对添加页眉页脚了,还在研究中

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!