Velocity + flying sauser生成pdf

    很多时候,我们在项目中会碰到报表用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 htmlCode	HTML源码
	 * @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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值