Velocity + flying sauser生成pdf

来源:互联网 发布:淘宝代购网店 注册 编辑:程序博客网 时间:2024/04/30 15:38

    很多时候,我们在项目中会碰到报表用pdf形式的方式展示,特别是在企业应用中,碰到的比较多的PDF的需求,可能是针对某个比较典型的具备文档特性的内容,导出成为PDF进行存档。由于我们在实际开发过程中往往使用一些开源框架,诸如ssh,ssi来构建我们的应用,所以我们相对熟悉的方案是针对具体的业务逻辑设计实体,使用开源框架来实现我们的业务逻辑。而PDF的导出,最好不要破坏现有的程序框架,甚至能复用我们业务逻辑层的代码,尽量做到高内聚低耦合的java编程规范。因为如果把PDF作为一种特殊的表现形式的话,实际上它有点类似模板。最佳的情况,是我们能够通过编写某种模板,把PDF的大概样子确定下来,然后把数据和模板做一次整合,得到最后的结果,此文就是在这样的背景下提出的解决方案。

   flying sauser,一种基于iText自身的问题,让我们开始寻求可以真正意义上模版技术,那么flying sauser就是为了这个问题出现的产品能解析HTML和CSS,而且能输出成image,PDF等格式

       那么我们如何去做呢,很简单,只需要如下几步:

1.引入所需要的jar包;

2.通过配置将velocity托管给spring;

3.使用velocity生成html代码;

4. 利用flying sauser生成pdf;

       下面就让我们来看看代码:

1.在spring配置文件中配置模版对象:
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"><property name="velocityProperties"><props><prop key="resource.loader">class</prop><prop key="class.resource.loader.class">org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader</prop><prop key="velocimacro.library"></prop></props></property></bean>

         2.使用velocity生成html源码;
/** *  * @Title: getHtmlCodeByVelocity * @Description: 使用velocity生成HTML源码 * @param templatePath模版存放路径(建议在WebRoot下创建一个目录,传递如../../template/sjy_zjcj_pdf.vm) * @param dataMap组装数据 * @param velocityEnginespring托管对象,请注入到servicd  * @return * String * @throws * * @Author dyp * @Create Date: 2014-4-17 下午04:18:48 */ private String getHtmlCodeByVelocity(String templatePath,Map<String, Object> dataMap) throws Exception{String htmlCode = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, templatePath, "UTF-8", dataMap);return htmlCode; }

3.WebRoot/template/jdy_cjtz_pdf.vm模版;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><style type="text/css" mce_bogus="1">body {font-family: SimSun;}</style><title>无标题文档</title><style type="text/css">@page{size:A4;#**@top-center {width:650px; height:100px; background:url(header1.png) no-repeat center 2px ;/*border-bottom: solid 0.01mm #000; width:650px; height:100px; padding-bottom:50px; background:url(header1.png) center no-repeat;*/   }@bottom-right{width:500px; height:45px; background:url(footer.png) no-repeat right;}*#} body {font-size:12px;background: #fff;color: #888888;}html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}.content{ width:650px; margin:0 auto; margin-top:20px; background:#fff;}h2{ height:56px; line-height:56px; font-size:22px; text-align:center; color:#000; font-weight:normal;}h3{ text-align:center; font-weight:normal;}.hello{ padding:10px; color:#000; font-size:12px; line-height:32px;}.hello p span{text-decoration:underline;}.table-t{ text-align:center;}.table-t tr td{ border:1px solid #000;}.company{ width:260px; height:170px; margin:30px 0 0 400px;}#**印章.company{ width:260px; height:170px; margin:30px 0 0 400px; background:url(yz.png) no-repeat}#*.footer{ text-align:right; padding:10px;}.c-name{ color:#000; font-size:14px; font-weight:bold;}</style></head><body><div class="content">        <h2>XXXXXX单</h2>      <div class="hello">        <p>尊敬的 <span>   ${user_name}   </span>先生/女士,您好!<br/></p>        <p style="text-indent: 2em;">XXXXXX有限公司(以下简称“XXXXXX”)XXXXXXXXXXXXXXXXX<br/>让获取了如下XXXXXXX,XXXXXXXXX信息如下:<br/></p>        <p>货币单位:人民币(元)</p>        <table class="table-t" width="630" border="0">          <tr>            <td>XXXXXXXX</td>            <td>XXXXXXXX</td>            <td>XXXXXXXX</td>            <td>XXXXXXXX</td>            <td>XXXXXXXX</td>            <td>XXXXXXXX</td>            <td>XXXXXXXX</td>          </tr>          <tr>            <td>${agreement_no}</td>            <td>${loan_num}</td>            <td>${initial_loan_date}</td>            <td>${product}</td>            <td>${real_loan_amount}</td>            <td>${close_period_on_amount}</td>            <td>${close_period_end_date}</td>          </tr>        </table>        <p>注:XXXXXXXX最后一自然日。XXXXXXXX将于XXXXXXX后5个工作日内为您寄送或发送《XXXXXXXXXX报告》。<br/><br/></p>        <h3>XXXXXXXX列表</h3>        <table class="table-t" width="630" border="0">          <tr>            <td>XXXXXXXXXX编号</td>            <td>XXXXX<br/>姓名</td>            <td>XXXXXXX份证号码</td>            <td>XXXXX金额</td>            <td>XXXX职业<br/>情况</td>            <td>XXXX<br/>用途</td>            <td>备注</td>            <td>XXXXX期限<br/>(月)</td>            <td>XXXXX<br/>月数</td>          </tr>          #foreach($condition in $borrower_list)          <tr>            <td>$condition.get("loan_agreement_num")</td>            <td>$condition.get("real_name")</td>            <td>$condition.get("id_card_no")</td>            <td>$condition.get("loan_amount")</td>            <td>$condition.get("occupation")</td>            <td>$condition.get("loan_purpose")</td>            <td>$condition.get("remark")</td>            <td>$condition.get("repayment_period")</td>            <td>$condition.get("surplus_repayment_period")</td>        </tr>  #end  #if($borrower_list.size() > 0)          <tr>            <td colspan="3">合计</td>            <td>$borrower_list.get(0).get("total_amount")</td>            <td colspan="5"> </td>          </tr>  #else      <tr>          无      </tr>  #end        </table>        <p class="company">XXXXXXXXXXXXXXXXX有限公司<br/>盖章:<br/>日期:${stamp_date}</p>        </div>    </div></body></html>

      4.根据html源码通过flying sauser生成pdf;

/** *  * @Title: doPdfByFS * @Description: 使用Flying sauser生成PDF * @param htmlCodeHTML源码 * @param outPath文件保存路径 * @param fileName  文件保存名称 * void * @throws * * @Author dyp * @Create Date: 2014-4-17 下午04:19:36 */private void doPdfByFS(String htmlCode,String outPath, String fileName) throws Exception{String fontFamily = PropertyUtil.getInfo("FONT_FAMILY"); //字体存放路径String imgPath    = PropertyUtil.getInfo("IMG_PATH");; //图片存放路径 OutputStream os = new FileOutputStream(outPath + fileName);ITextRenderer renderer = new ITextRenderer();               ITextFontResolver fontResolver = renderer.getFontResolver();               fontResolver.addFont(fontFamily, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);               // DOCTYPE 必需写否则类似于 这样的字符解析会出现错误               renderer.setDocumentFromString(htmlCode);               // 解决图片的相对路径问题               renderer.getSharedContext().setBaseURL(imgPath);             renderer.layout();        renderer.createPDF(os);        os.close();<span style="font-size:14px;">}</span>

5.在这里我们也将使用velocity生成静态页面的方法放置于此:

private String doHtmlByVelocity(String htmlCode,String outPath, String fileName){String path = outPath + fileName;File file = new File(path); if(file.exists()) file.mkdirs();        try {        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), "UTF-8"));//BufferedWriter o = new BufferedWriter(new FileWriter(file),"");         out.write(htmlCode);         out.close();} catch (Exception e) {e.printStackTrace();return "";}        return "";}
以上就是生成pdf的源码,jar在此下载,如有披露请多多指教,对了,velocity引入css文件本人还没找到好的方法,如果那位大神有用过,请留言。


0 0
原创粉丝点击