使用Velocity模板作为导出PDF的模板

工作中经常需要导出PDF,如果在Java代码中生成HTML代码,需要进行各种字符串拼接,相当的蛋疼,后来发现Velocity可以很好的起到模板的作用。使用Velocity作为模板写好HTML,我们只需要传我们的对数对象到模板即可渲染我们预期的HTML,然后将该内容生成PDF,简单便捷,更重要的是没了讨厌的HTML字符串拼接的过程。

1、写好Velocity模板

我们新建一个模板文件,比如xx.vm,里面就是HTML内容,使用Velocity语法直接使用传入的对象数据。

<html>
<head>
    <meta htp-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<style>
    .positive{
        color: green;
        font-size: 32px;
    }
    .negative{
        color: grey;
        font-size: 20px;
    }

</style>
<body>
    <div>
        你好,${user.name},
        #if(${user.age} > 18)
            <span class="positive">恭喜你,你已经成年了~</span>
        #else
            <span class="negative">小朋友,你慢慢喊你回家吃饭了~</span>
        #end
    </div>
</body>
</html>

2 、解析模板帮助类

该类将我们的对象数据注入到模板中,模板会解析,然后我们返回渲染后的HTML文本内容。

public class VelocityHelper {

    public static String getVelocity(String pdfTempName,Map<String,Object> data,HttpServletRequest request){

       try {
           VelocityEngine ve = new VelocityEngine();
           Properties properties = new Properties();
           properties.put("file.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
           ve.init(properties);
           Template template = ve.getTemplate(pdfTempName,"UTF-8");
           VelocityContext context = new VelocityContext();
           Set<String> keySet = data.keySet();
           for(String key : keySet){
               context.put(key,data.get(key));
           }
           StringWriter writer = new StringWriter();
           template.merge(context,writer);
           return writer.toString();
       }catch (Exception e){
           throw new ServiceException("获取模板错误,信息:"+e.getMessage());
       }

    }

}

3、提供PDF的下载

public void exportPDF(HttpServletRequest request, HttpServletResponse response, @RequestParam int demandId) throws IOException {
    try {

            User user = getCurrentUser();
            String fileName = user.getName() + "-" + DateUtils.getDateString(0);
            Document document = new Document(PageSize.A4.rotate());
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            PdfWriter writer = PdfWriter.getInstance(document, os);
            document.open();
            document.addTitle(fileName);
            document.addSubject("你好");
            document.addCreationDate();
            Map<String, Object> data = Maps.newHashMap();
            data.put("user", user);
            String content = VelocityHelper.getVelocity("xx.vm", data,request);
            InputStream htmlStream = new ByteArrayInputStream(content.getBytes());
            XMLWorkerHelper.getInstance().parseXHtml(writer, document, htmlStream, XMLWorkerHelper.class.getResourceAsStream("/default.css"), new XMLWorkerFontProvider() {
                @Override
                public Font getFont(final String fontname, final String encoding, final boolean embedded, final float size, final int style, final BaseColor color) {
                    BaseFont bf = null;
                    try {
                        bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                    } catch (DocumentException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    Font font = new Font(bf, size, style, color);
                    font.setColor(color);
                    return font;
                }
            });
            document.close();
            response.setHeader("Content-Disposition", "attachment; filename=" + new String((fileName + ".pdf").getBytes("UTF-8"), "iso-8859-1"));
            response.setContentType("application/pdf");
            response.setContentLength(os.size());

            OutputStream out = response.getOutputStream();

            os.writeTo(out);
            out.flush();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

使用Velocity我们可以处理除了简单的文本,也可以处理非常复杂的对象,比如循环展示列表,根据条件判断展示,等等。

© 2019 FunGa技术札记 All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero