一 测试:
private static final String PDF_KEY = "GENERATEPDF";
FileGenerator pdfGenServ = (FileGenerator) getBean("pdfGenServ");
Result result = pdfGenServ.genFile(PDF_KEY, pdfModelVo);
二 操作步骤:
2.1 实体类
实体类:PdfModelVo 自己添加get()和set();属性名称如下:
public class PdfModelVo implements Serializable {
private static final long serialVersionUID = 1645865443L;
/** 用户名(出借方/投资人) */
private String invest_username;
/** 用户身份证号(出借方/投资人) */
private String invest_useridcard;
/** 借款方真实姓名 **/
private String loan_username;
/** 组织机构代码 **/
private String org_code;
/** 地址 **/
private String contact_address;
/** 法人姓名 **/
private String legal_username;
/** 项目编号 **/
private String project_code;
/** 借款总额(显示万元) **/
private String loan_funds;
/** 借款总额(显示大写万元) **/
private String loan_big_funds;
/** 项目开始时间 (年) **/
private String gmt_start_year;
/** 项目开始时间 (月) **/
private String gmt_start_month;
/** 项目开始时间 (日) **/
private String gmt_start_day;
/** 项目结束时间(年) **/
private String gmt_end_year;
/** 项目结束时间 (月) **/
private String gmt_end_month;
/** 项目结束时间 (日) **/
private String gmt_end_day;
/** 还款期数 **/
private Long repay_order;
/** 借款用途 **/
private String loan_use_name;
/** 担保物 **/
private String assure_goods;
/** 担保方式 **/
private String assure_type_name;
/** 付息日 **/
private Long pay_day;
/** 借款利率 **/
private BigDecimal loan_apr;
}
2.2 service层接口
public interface FileGenerator<T> {
/**
* 根据模板key和数据model生成文件
*
* 1. 根据模板key找到模板文件,并加载文件
* 2. 调用Itext的生成对应类型的文件,并将该文件在服务器上落地
* 3. 返回服务器上的存放地址
*
* @param templateKey 模板key
* @param model
* @return
*/
public Result genFile(String templateKey,T model);
}
2.3 service层接口实现类
@Service("pdfGenServ")
@Transactional
public class PdfGenServImpl implements FileGenerator<Serializable>{
/** 记录日志的接口 */
private Logger log = Logger.getLogger(getClass());
private String templetPrefix;
private String templetSuffix;
private String genFileSuffix;
private String templetDirPath;
private String genFileDir;
private String logoPath;
private String fontPath;
private String fontPath_hei;
private FileRootPathServ fileRootPathServ;
/**
* 创建文件所需数据.
*
* @param model 生成文件所需的数据对象
* @param templateKey 模板key
* @return 返回生成结果
*/
@Override
public Result genFile(String templateKey,Serializable model) {
Result result = new Result();
if (null == model) {
result.setSuccess(false);
result.setMessage("数据对象为空,不能下载");
return result;
}
if (StringUtils.isBlank(templateKey)) {
result.setSuccess(false);
result.setMessage("模板KEY为空,不能下载");
return result;
}
templateKey = templateKey.trim();
/* 创建配置 */
Configuration cfg = new Configuration();
Map<String, Serializable> rootMap = new HashMap<String, Serializable>();
rootMap.put("model", model);
CharArrayWriter writer = null;
OutputStream outputStream = null;
/* 指定模板存放的路径 */
try {
cfg.setDirectoryForTemplateLoading(new File(templetDirPath));
/* 创建数据模型 */
cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
/* 从上面指定的模板目录中加载对应的模板文件 */
Template template = cfg.getTemplate(genTempletFileName(templateKey), "UTF-8");
File file = new File(genFileDir);
if (!file.exists()) {
file.mkdirs();
}
String pdfAbsolutePath = getGenFilePath(templateKey);
ITextRenderer renderer = new ITextRenderer();
writer = new CharArrayWriter();
outputStream = new FileOutputStream(new File(pdfAbsolutePath));
template.process(rootMap, writer);
renderer.setDocumentFromString(writer.toString());
// 解决图片路径问题
renderer.getSharedContext().setBaseURL("file:" + logoPath);
// 解决中文问题
renderer.getFontResolver().addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.getFontResolver().addFont(fontPath_hei, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(outputStream);
renderer.finishPDF();
result.setValue("pdfAbsolutePath", pdfAbsolutePath);
} catch (Exception e) {
log.error(e.getMessage(), e);
result.setSuccess(false);
result.setMessage("生成PDF失败");
} finally {
if(null != writer) {
writer.flush();
writer.close();
}
if(null != outputStream) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
result.setSuccess(false);
result.setMessage("生成PDF失败");
}
}
}
return result;
}
/**
* 获取pdf配置目录
* @param templateKey
* @return
*/
private String getGenFilePath(String templateKey) {
if(genFileDir.endsWith("/")) {
return genFileDir + "GEN_" + fileRootPathServ.getTemplateName(templateKey) + genFileSuffix;
}
return genFileDir + "/"+ "GEN_" + fileRootPathServ.getTemplateName(templateKey) + genFileSuffix;
}
/**
* 获取模板配置名称
* @param templateKey
* @return
*/
private String genTempletFileName(String templateKey) {
return templetPrefix + fileRootPathServ.getTemplateName(templateKey) + templetSuffix;
}
public void setTempletDirPath(String templetDirPath) {
this.templetDirPath = templetDirPath;
}
public void setTempletSuffix(String templetSuffix) {
this.templetSuffix = templetSuffix;
}
public void setGenFileSuffix(String genFileSuffix) {
this.genFileSuffix = genFileSuffix;
}
public void setGenFileDir(String genFileDir) {
this.genFileDir = genFileDir;
}
public void setTempletPrefix(String templetPrefix) {
this.templetPrefix = templetPrefix;
}
public void setLogoPath(String logoPath) {
this.logoPath = logoPath;
}
public void setFontPath(String fontPath) {
this.fontPath = fontPath;
}
public void setFontPath_hei(String fontPath_hei) {
this.fontPath_hei = fontPath_hei;
}
public void setFileRootPathServ(FileRootPathServ fileRootPathServ) {
this.fileRootPathServ = fileRootPathServ;
}
}
2.4 其他接口(共用)
接口: FileRootPathServ
public interface FileRootPathServ {
/**
* 获取文件根目录路径.
*
* @param saveFolder 文件夹名
* @return 根目录路径
*/
public String getRealPath(String saveFolder);
public String getCwbbRootPath();
public String getTemplateName(String templateKey);
}
@Service("fileRootPathServ")
@Transactional
public class FileRootPathServImpl implements FileRootPathServ {
private String uploadRootPath;
private String cwbbRootPath;
private Map<String, String> templateMap;
/**
* 获取文件根目录路径.
*
* @param saveFolder 文件夹名
* @return 根目录路径
*/
public String getRealPath(String saveFolder) {
if(StringUtils.isBlank(saveFolder)) {
return uploadRootPath;
} else {
saveFolder = saveFolder.trim();
if(saveFolder.startsWith("/")) {
return uploadRootPath + saveFolder;
} else {
return uploadRootPath + "/" + saveFolder;
}
}
}
public String getTemplateName(String templateKey) {
if(StringUtils.isBlank(templateKey)) {
return null;
}
return templateMap.get(templateKey);
}
public String getCwbbRootPath() {
return cwbbRootPath;
}
public void setCwbbRootPath(String cwbbRootPath) {
this.cwbbRootPath = cwbbRootPath;
}
public void setUploadRootPath(String uploadRootPath) {
this.uploadRootPath = uploadRootPath;
}
public void setTemplateMap(Map<String, String> templateMap) {
this.templateMap = templateMap;
}
}
spring配置:
<span style="white-space:pre"> </span><bean id="fileRootPathServ" class="com.yht.wxt.facade.impl.file.generator.FileRootPathServImpl">
<property name="uploadRootPath" value="${uploadFilePath}" />
<property name="cwbbRootPath" value="${templateDirPath}${cwbbTempletDirName}" />
<property name="templateMap">
<map>
<entry key="RECHARGE" value="RECHARGE" />
<entry key="CASH" value="CASH" />
<entry key="RECASH" value="RECASH" />
<entry key="INTEREST" value="INTEREST" />
<entry key="ACCOUNT" value="ACCOUNT" />
<entry key="GENERATEPDF" value="GENERATEPDF" />
</map>
</property>
</bean>
<!-- 生成PDF文件 -->
<bean id="pdfGenServ" class="com.yht.wxt.facade.impl.file.generator.PdfGenServImpl" >
<property name="templetPrefix" value="PDF_" />
<property name="templetSuffix" value=".ftl" />
<property name="genFileSuffix" value=".pdf" />
<property name="templetDirPath" value="${templateDirPath}${pdfTempletDirName}" />
<property name="genFileDir" value="${genTempDirPath}${pdfGenFileDirName}" />
<property name="logoPath" value="${logoPath}" />
<property name="fontPath" value="${fontPath}" />
<property name="fontPath_hei" value="${fontPath_hei}" />
</bean>
<!-- 文件下载参数配置开始 -->
<logoPath><![CDATA[F:/conf/download/wxt_dev/templet/img/]]></logoPath>
<fontPath><![CDATA[F:/conf/download/wxt_dev/templet/font/SIMSUN.TTC]]></fontPath>
<fontPath_hei><![CDATA[F:/conf/download/wxt_dev/templet/font/SimHei.ttf]]></fontPath_hei>
<!-- 下载文件模板目录 -->
<templateDirPath><![CDATA[F:/conf/download/wxt_dev/templet/]]></templateDirPath>
<!-- 下载文件目录 -->
<genTempDirPath><![CDATA[F:/conf/download/wxt_dev/temp/]]></genTempDirPath>
<previewGenFileDir><![CDATA[F:/conf/tomcat/wxt/jsp/temp/preview]]></previewGenFileDir>
<!--模板配置信息-->
<previewTempletDirName>HTMLModel</previewTempletDirName>
<pdfTempletDirName>PDFModel</pdfTempletDirName>
<wordTempletDirName>WordModel</wordTempletDirName>
<excelTempletDirName>ExcelModel</excelTempletDirName>
<wordGenFileDirName>word</wordGenFileDirName>
<qrCodeGenFileDirName>qrCode</qrCodeGenFileDirName>
<snapshotGenFileDirName>snapshot</snapshotGenFileDirName>
<excelGenFileDirName>excel</excelGenFileDirName>
<pdfGenFileDirName>pdf</pdfGenFileDirName>
2.5 模板配置
目录: F:\conf\download\wxt_dev\templet\PDFModel\PDF_GENERATEPDF.ftl
注: ${(model.project_code)!""}中project_code必须是PdfModelVo的属性。
<?xml version="1.0" encoding="UTF-8"?>
<!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" />
<title>title</title>
<style>
body {
PADDING-BOTTOM: 0px;
LINE-HEIGHT: 14px;
BACKGROUND-COLOR: #fff;
MARGIN: 0px;
PADDING-LEFT: 0px;
WIDTH: 100%;
PADDING-RIGHT: 0px;
FONT-FAMILY: SimSun;
HEIGHT: 100%;
COLOR: #000;
FONT-SIZE: 10px;
FONT-WEIGHT: 400;
PADDING-TOP: 0px
}
span{
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
.mainbody {
PADDING-BOTTOM: 10px;
BACKGROUND-COLOR: #fff;
PADDING-LEFT: 10px;
WIDth: 650px;
PADDING-RIGHT: 10px;
HEIGHT: 100%;
MARGIN-LEFT: auto;
MARGIN-RIGHT: auto;
PADDING-TOP: 10px
}
.head_top {
margin-top: 20px;
}
.head_top2{
margin-top: 80px;
}
.head_middle {
margin-top: 250px;
}
.page_one {
width: 650px;
line-height: 24px;
height: 1000px;
}
.page_two {
line-height: 24px;
width: 650px;
height: 900px;
}
.page_three {
line-height: 24px;
width: 650px;
height: 1000px;
}
.two_myhead {
margin: 0 auto;
width: 650px;
text-align: center;
}
.f_size_14 {
font-size: 14px;
}
.f_size_16 {
font-size: 16px;
}
.f_size_18 {
font-size: 18px;
}
.f_size_20 {
font-size: 20px;
}
.f_size_24 {
font-size: 24px;
}
.f_size_36 {
font-size: 36px;
}
.f_size_48 {
font-size: 48px;
}
.f_size_60 {
font-size: 60px;
}
.f_bold {
font-weight: bold;
}
.f_family_song {
font-family: SimSun;
}
.f_family_hei {
font-family: SimHei;
}
.f_color_blue {
color: blue;
}
.f_color_red {
color: red;
}
.footer {
TEXT-ALIGN: center; WIDth: 100%; HEIGHT: 100px
}
.fn_fl{
height:50px;
float:left;
}
/* 清理浮动 */
.fn-clear:after {
visibility:hidden;
display:block;
font-size:0;
content:" ";
clear:both;
height:0;
}
.ui_hr{
width="100%"
margin-top:0px;
border:1px solid #0070C0;
}
.ui_underline{
text-decoration:underline;
}
</style>
</head>
<body>
<div class='mainbody'>
<div class="page_one">
<div class="two_myhead">
<p><span class="f_size_24 f_family_hei f_bold">借 款 合 同</span></p>
</div>
<p>
<span class="f_size_14">合同编号:</span>
<span class="f_size_14 "> ${(model.project_code)!""} </span>
</p>
<p><span class="f_size_14 f_bold">甲方(出借方):</span>
<span class="f_size_14 "> ${(model.invest_username)!""} </span> </p>
<p><span class="f_size_14 f_bold">身份证号:</span><span class="f_size_14 "> ${(model.invest_useridcard)!""} </span></p>
<p><span class="f_size_14 f_bold">乙方(借款方):</span>
<span class="f_size_14 "> ${(model.loan_username)!""} </span> </p>
<p><span class="f_size_14 f_bold">地 址:</span><span class="f_size_14 "> ${(model.contact_address)!""} </span> </p>
<p><span class="f_size_14 f_bold">组织机构代码证:</span><span class="f_size_14 "> ${(model.org_code)!""} </span></p>
<p><span class="f_size_14 f_bold">法定代表人:</span><span class="f_size_14 ">${(model.legal_username)!""}</span> </p>
<p><span class="f_size_14 f_bold f_color_red">甲、乙双方经“信义仓”平台撮合,根据有关法律、法规,在平等、自愿的基础上,经充分协商一致签订</span>
<span class="f_size_14 f_bold f_color_red">本线上借款合同共同遵守。</span>
</p>
<p><span class="f_size_14 f_bold f_family_hei">第一条 借款金额</span></p>
<p><span class="f_size_14">人民币(大写):</span><span class="f_size_14 ">【 ${(model.loan_big_funds)!""} 】</span><span class="f_size_14">,(小写)¥:</span><span class="f_size_14 ">【 ${(model.loan_funds)!""} 】</span><span class="f_size_14">万元。</span></p>
<p><span class="f_size_14 f_bold f_family_hei">第二条 借款期限</span></p>
<p>
<!--代码压缩片段-->
<span class="f_size_14">借款期限为</span><span class="f_size_14 ">【 ${(model.repay_order)!""} 】</span><span class="f_size_14">个月,自</span><span class="f_size_14 ">【 ${(model.gmt_start_year)!""} 】</span><span class="f_size_14">年</span><span class="f_size_14 ">【 ${(model.gmt_start_month)!""} 】</span><span class="f_size_14">月</span><span class="f_size_14 ">【 ${(model.gmt_start_day)!""} 】</span><span class="f_size_14">日起至</span><span class="f_size_14 ">【 ${(model.gmt_end_year)!""} 】</span><span class="f_size_14">年</span><span class="f_size_14 ">【 ${(model.gmt_end_month)!""} 】</span><span class="f_size_14">月</span><span class="f_size_14 ">【 ${(model.gmt_end_day)!""} 】</span><span class="f_size_14">日止</span><span class="f_size_14">,</span><span class="f_size_14">用</span><span class="f_size_14">途</span><span class="f_size_14 ">【 ${(model.loan_use_name)!""} 】。</span><span class="f_size_14">实</span><span class="f_size_14">际</span><span class="f_size_14">借</span><span class="f_size_14">款</span><span class="f_size_14">日</span><span class="f_size_14">期</span><span class="f_size_14">与</span><span class="f_size_14">上</span><span class="f_size_14">述</span><span class="f_size_14">约</span><span class="f_size_14">定</span><span class="f_size_14">不</span><span class="f_size_14">一</span><span class="f_size_14">致</span><span class="f_size_14">的</span><span class="f_size_14">,</span><span class="f_size_14">以</span><span class="f_size_14">借</span><span class="f_size_14">款</span><span class="f_size_14">到</span><span class="f_size_14">账</span><span class="f_size_14">日</span><span class="f_size_14">或</span><span class="f_size_14">借</span><span class="f_size_14">款</span><span class="f_size_14">借</span><span class="f_size_14">据</span><span class="f_size_14">为</span><span class="f_size_14">准</span><span class="f_size_14">。</span>
<!--代码压缩片段-->
</p>
<p><span class="f_size_14 f_bold f_family_hei">第三条 借款利率</span></p>
<p>
<span class="f_size_14">本合同执行利率为年利率</span>
<span class="f_size_14 ">【 ${(model.loan_apr)!""} 】</span>
<span class="f_size_14">%。</span>
</p>
<p><span class="f_size_14 f_bold f_family_hei">第四条 还款方式</span></p>
<p><span class="f_size_14">1、还款和付息方式按以下第【 1 】项</span></p>
<p>
<span class="f_size_14">(1)每月的</span>
<span class="f_size_14 ">【 ${(model.pay_day)!""} 】</span>
<span class="f_size_14"> 日为付息日,最后一个月利息和借款本金至借款期限届满时一次性归还。</span></p>
<p><span class="f_size_14">(2)到期一次性归还全部本息。</span></p>
<p><span class="f_size_14">2、乙方在本合同约定的还款、付息日<span class="f_size_14 ">【 24 】</span>时前将相应本金、利息归还给甲方。</span></p>
<p><span class="f_size_14 f_bold f_family_hei">第五条 乙方的权利和义务</span></p>
<p><span class="f_size_14">1、向“信义仓”平台提供有关证照、证明和其他材料,并对所提供的材料真实性、合法性负责;</span></p>
<p><span class="f_size_14">2、保证借款用途真实,严禁用于非法活动;</span></p>
<p><span class="f_size_14">3、按照约定取得借款本金,按时偿还借款本息及相关费用。</span></p>
</div>
<div class="page_two">
<p><span class="f_size_14 f_bold f_family_hei">第六条 甲方的权利和义务</span></p>
<p><span class="f_size_14">1、有权对乙方在“信义仓”平台上提供的信息进行查询和核实;</span></p>
<p><span class="f_size_14">2、按照本协议约定发放借款及按期收回本金、利息。</span></p>
<p><span class="f_size_14 f_bold f_family_hei">第七条 担保</span></p>
<p>
<span class="f_size_14"> 1、本合同项下的借款本息及其他一切相关费用由</span>
<span class="f_size_14 ">【 】</span>
<span class="f_size_14">(</span><span class="f_size_14">保</span><span class="f_size_14">证</span><span class="f_size_14">人</span><span class="f_size_14">)</span><span class="f_size_14">提</span><span class="f_size_14">供</span><span class="f_size_14">连</span><span class="f_size_14">带</span><span class="f_size_14">责</span><span class="f_size_14">任</span><span class="f_size_14">担</span><span class="f_size_14">保</span><span class="f_size_14">,</span><span class="f_size_14">该</span><span class="f_size_14">保</span><span class="f_size_14">证</span><span class="f_size_14">人</span><span class="f_size_14">另</span><span class="f_size_14">行</span><span class="f_size_14">出</span><span class="f_size_14">具</span><span class="f_size_14">《</span><span class="f_size_14">担</span><span class="f_size_14">保</span><span class="f_size_14">函</span><span class="f_size_14">》</span><span class="f_size_14">。</span>
</p>
<p>
<!--代码压缩片段-->
<span class="f_size_14">2、本合同项下的借款本息及其他一切相关费用由</span><span class="f_size_14 ">【 】</span><span class="f_size_14">(</span><span class="f_size_14">出</span><span class="f_size_14">质</span><span class="f_size_14">人</span><span class="f_size_14">)</span><span class="f_size_14">以</span><span class="f_size_14">其</span><span class="f_size_14">所</span><span class="f_size_14">有</span><span class="f_size_14">或</span><span class="f_size_14">依</span><span class="f_size_14">法</span><span class="f_size_14">有</span><span class="f_size_14">权</span><span class="f_size_14">处</span><span class="f_size_14">分</span><span class="f_size_14">的</span><span class="f_size_14 ">【 ${(model.assure_goods)!""} 】</span><span class="f_size_14">作</span><span class="f_size_14">质</span><span class="f_size_14">押</span><span class="f_size_14">,</span><span class="f_size_14">出</span><span class="f_size_14">质</span><span class="f_size_14">人</span><span class="f_size_14">另</span><span class="f_size_14">行</span><span class="f_size_14">出</span><span class="f_size_14">具</span><span class="f_size_14">《</span><span class="f_size_14">质</span><span class="f_size_14">押</span><span class="f_size_14">担</span><span class="f_size_14">保</span><span class="f_size_14">函</span><span class="f_size_14">》</span><span class="f_size_14">或</span><span class="f_size_14">签</span><span class="f_size_14">订</span><span class="f_size_14">《</span><span class="f_size_14">质</span><span class="f_size_14">押</span><span class="f_size_14">合</span><span class="f_size_14">同</span><span class="f_size_14">》</span><span class="f_size_14">。</span>
<!--代码压缩片段-->
</p>
<p>
<span class="f_size_14">3、其他担保方式:</span>
<span class="f_size_14 ">【 ${(model.assure_type_name)!""} 】</span>
</p>
<p><span class="f_size_14">4、担保范围为本合同项下的借款本金、利息、逾期利息、违约金以及实现债权的所有费用。</span></p>
<p><span class="f_size_14 f_bold f_family_hei">第八条 违约责任</span></p>
<p><span class="f_size_14">乙方未能按本合同约定足额偿还借款本息的,每日另行按未清偿本金部分万分之五支付违约金。</span></p>
<p><span class="f_size_14 f_bold f_family_hei">第九条 合同成立及生效</span></p>
<p><span class="f_size_14 ">甲方在“信义仓”平台网站或手机APP本协议网页点击“同意”,本合同成立。
</span></p>
<p><span class="f_size_14 ">甲方借款资金进入乙方指定账户后本合同生效,一经生效即不可撤销。
</span></p>
<p><span class="f_size_14 f_bold f_family_hei">第十条 <strong>争议解决</strong></span> </p>
<p>
<span class="f_size_14">凡由本合同引起的或与本合同有关的一切争议和纠纷,各方应当协商解决;若协商不成,应向杭州市江干</span>
<span class="f_size_14">区人民法院提起诉讼。</span>
</p>
<p><span class="f_size_14 f_bold f_family_hei">第十一条 其他</span></p>
<p>
<span class="f_size_14">各方同意本合同利用互联网信息技术以数据电文形式订立并认同其效力。各方均承诺遵守国家信息安全等</span>
<span class="f_size_14">级保护的相关规定和标准,遵守国家互联网技术规范和安全规范。本合同线下汇总,形成的书面合同后与</span>
<span class="f_size_14">互联网上订立的合同具有同等法律效力。</span>
</p>
</div>
</div>
</body>
</html>
效果图展示: