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

来源:互联网 发布:网络拓扑结构形状 编辑:程序博客网 时间:2024/05/20 14:20

最近项目中又遇到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;//纸张大小A4margin: 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添加页码,只适合对静态页面添加(知道内容或者页数固定的页面);对于动态页面的页码添加需要对添加页眉页脚了,还在研究中

原创粉丝点击