使用IText5+Freemarker生成PDF(模板可以使用CCS3分页效果)
(1)com.itextpdf是必须的。
(2)com.itextpdf.tool是为了Freemarker的模板。
(3)org.xhtmlrenderer是为模板可以使用css3。
iText + Freemarker实现pdf的导出,支持中文、css以及图片,页眉页脚,页眉添加图片
使用IText5+Freemarker生成PDF(模板可以使用CCS3分页效果)
PS:上次有同学分页有些东西会被隔开怎么办
CCS可以幫到你page-break-inside:avoid;這個是可以避免分頁的
iText + Freemarker实现pdf的导出,支持中文、css以及图片,页眉页脚,页眉添加图片
有页眉的包,有分页
D:\gitee\pdf-kit
有页眉的包,有分页
D:\github\itextpdf
有分页
D:\gitee\freemarker-page-demo
EMS快递
D:\gitee\printPdf_freemarker
效果:EMS快递
ems.ftl
<!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>ems面单10*15打印</title>
<style>
@page {size:100mm 150mm;margin: 0mm;-fs-flow-top: 'header';-fs-flow-bottom: 'footer';-fs-flow-left: 'left';-fs-flow-right: 'right';padding: 0; }
</style>
</head>
<body style="font-family:'Microsoft YaHei';word-break:break-all;font-size:2.3mm;width:10cm;margin:0cm 0cm 0cm 0cm;">
[#list orderInfos as o]
<div style="width:9.7cm;height:14.5cm;margin:1.5mm;margin-top:2mm;border:0.1mm dashed #000000;[#if o_index!=0]page-break-before:always;[/#if]">
<div style="border-bottom:0.1mm dashed #000000;height:2cm;">
<div style="float:left;width:4cm;border-right:0.1mm dashed #000000;font-size:24px;height:2cm;line-height:2.5cm;text-align:center;">
EMS标准快递
</div>
<div style="float:left;width:5.6cm;">
<div><img src="${base}/barCode/getBarCodeByCode.html?code=${(o.trackNo)!"0"}&noText=true&hahaha=1" style="width:5.5cm;height:1.4cm;margin-top:0.1cm;"/></div>
<div style="text-align:center;">${(o.trackNo)!"0"}</div>
</div>
</div>
<div style="border-bottom:0.1mm dashed #000000;height:2cm;">
<div style="float:left;width:5.2cm;height:1.8cm;border-right:0.1mm dashed #000000;font-size:2.6mm;padding:0.1cm;">
<div style="float:left;width:0.8cm;">
寄件:
</div>
<div style="float:left;width:4.3cm;">
<div>${(o.sendName)!} ${(o.sendTel)!}</div>
<div>${(sendlvs[o_index].provinceName)!} ${(sendlvs[o_index].cityName)!} ${(sendlvs[o_index].areaName)!}</div>
<div>${(o.sendAddress)!}</div>
<div>${(customerNames[o_index])!}</div>
</div>
</div>
<div style="float:left;width:4.2cm;font-size:24px;line-height:1.5cm;text-align:center;overflow:hidden;height:1.7cm;">
${(sendlvs[o_index].areaName)!}
</div>
</div>
<div style="border-bottom:0.1mm dashed #000000;height:1.8cm;">
<div style="float:left;width:0.8cm;padding:1mm;font-size:2.6mm;">
收件:
</div>
<div style="float:left;width:8.5cm;font-size:3.1mm;font-weight:800;padding:0.5mm;">
<div>${(o.receiverName)!} ${(o.receiverTel)!}</div>
<div>${(receiverlvs[o_index].provinceName)!} ${(receiverlvs[o_index].cityName)!} ${(receiverlvs[o_index].areaName)!}</div>
<div>${(o.receiverAddress)!}</div>
</div>
</div>
<div style="border-bottom:0.1mm dashed #000000;height:1.5cm;">
<div style="float:left;width:3.8cm;border-right:0.1mm dashed #000000;padding:1mm;height:1.5cm">
<div>付款方式:</div>
<div>计费重量(KG):${weight(o.weight)!}</div>
<div>保价金额(元):</div>
</div>
<div style="float:left;width:5.5cm;padding:0.5mm;">
<div>收件人\代收人:</div>
<div>签收时间: 年 月 日</div>
<div style="font-size:2.3mm;">快递送达收货人地址,经收件人或收件人允许的代收人签字,视为送达</div>
</div>
</div>
<div style="border-bottom:0.1mm dashed #000000;height:1.8cm;overflow:hidden;">
<div style="padding:0.5mm;">
<div style="float:left;">订单号:</div>
<div style="float:left;">
<div><img src="${base}/barCode/getBarCodeByCode.html?code=${(o.orderNo)!}&noText=true&hahaha=1" style="width:4.5cm;height:0.8cm;vertical-align:middle;"/></div>
<div style="text-align:center;">${(o.orderNo)!"0"}</div>
</div>
<div style="float:left;"> 件数:1 重量(KG):1</div>
</div>
<div style="clear:both;">
品名:${(o.productName)!}
</div>
<div>
备注:${(o.proNameRemark)!}
</div>
</div>
<div style="border-bottom:0.1mm dashed #000000;height:0.2cm;overflow:hidden;">
</div>
<div style="border-bottom:0.1mm dashed #000000;height:1.3cm;">
<div style="float:left;width:5.2cm;padding:0.5mm;">
<div><img src="${base}/barCode/getBarCodeByCode.html?code=${(o.trackNo)!"0"}&noText=true&hahaha=2" style="width:5cm;height:0.9cm;"/></div>
<div style="text-align:center;">${(o.trackNo)!"0"}</div>
</div>
<div style="float:left;width:4cm;padding:0.5mm;">
<img src="${base}/resources/img/EMS.jpg" style="width:4cm;height:1.1cm;"/>
</div>
</div>
<div style="border-bottom:0.1mm dashed #000000;height:2cm;">
<div style="float:left;width:4.2cm;height:1.9cm;border-right:0.1mm dashed #000000;font-size:2.3mm;padding:0.5mm;">
<div style="float:left;width:0.8cm;">
寄件:
</div>
<div style="float:left;width:3.1cm;">
<div>${(o.sendName)!} ${(o.sendTel)!}</div>
<div>${(sendlvs[o_index].provinceName)!} ${(sendlvs[o_index].cityName)!} ${(sendlvs[o_index].areaName)!} </div>
<div>${(o.sendAddress)!}</div>
<div>${(customerNames[o_index])!}</div>
</div>
</div>
<div style="float:left;width:5.2cm;height:1.7cm;font-size:2.3mm;padding:0.5mm;">
<div style="float:left;width:0.8cm;">
收件:
</div>
<div style="float:left;width:3.1cm;">
<div>${(o.receiverName)!} ${(o.receiverTel)!}</div>
<div>${(receiverlvs[o_index].provinceName)!} ${(receiverlvs[o_index].cityName)!} ${(receiverlvs[o_index].areaName)!}</div>
<div>${(o.receiverAddress)!}</div>
</div>
</div>
</div>
<div style="border-bottom:0.1mm dashed #000000;">
<div style="width:5.8cm;height:100%;border-right:0.1mm dashed #000000;">
<div style="height:1.3cm;border-bottom:0.1mm dashed #000000;padding:0.5mm;">
<div>
品名:${(o.productName)!}
</div>
<div>
备注:${(o.proNameRemark)!}
</div>
</div>
<div style="height:0.4cm;padding:0.2mm;">
网址:www.ems.com.cn 客服电话:11183
</div>
</div>
</div>
<div style="clear:both;"></div>
</div>
[/#list]
</body>
</html>
applicationcontent.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.zb" />
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
<context:property-placeholder location="classpath*:/properties/*.properties" ignore-resource-not-found="true" ignore-unresolvable="true" />
<bean id="freeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPaths" value="${template.loader_path}" />
<property name="freemarkerSettings">
<props>
<prop key="defaultEncoding">${template.encoding}</prop>
<prop key="url_escaping_charset">${url_escaping_charset}</prop>
<prop key="locale">${locale}</prop>
<prop key="template_update_delay">${template.update_delay}</prop>
<prop key="tag_syntax">auto_detect</prop>
<prop key="whitespace_stripping">true</prop>
<prop key="classic_compatible">true</prop>
<prop key="number_format">${template.number_format}</prop>
<prop key="boolean_format">${template.boolean_format}</prop>
<prop key="datetime_format">${template.datetime_format}</prop>
<prop key="date_format">${template.date_format}</prop>
<prop key="time_format">${template.time_format}</prop>
<prop key="object_wrapper">freemarker.ext.beans.BeansWrapper</prop>
<prop key="auto_import"></prop>
</props>
</property>
<property name="freemarkerVariables">
<map>
<entry key="systemName" value="${system.name}" />
<entry key="systemVersion" value="${system.version}" />
<entry key="systemDescription" value="${system.description}" />
<entry key="systemShowPowered" value="#{${system.show_powered}}" />
<entry key="base" value="#{servletContext.contextPath}" />
<entry key="money" value-ref="moneyMethod" />
<entry key="weight" value-ref="weightMethod" />
<entry key="dateUtil" value-ref="dateUtilMethod" />
<entry key="locale" value="${locale}" />
</map>
</property>
</bean>
</beans>
config.properties
#freemarker的相关配置
template.number_format=0.\#\#\#\#\#\#
template.datetime_format=yyyy-MM-dd HH:mm:ss
template.time_format=HH\:mm\:ss
template.boolean_format=true,false
template.date_format=yyyy-MM-dd
template.update_delay=0
template.encoding=UTF-8
template.loader_path=/WEB-INF/page
template.suffix=.ftl
system.version=1.0
system.description=lgl-erp
system.name=lgl-erp
system.show_powered=true
locale=zh_CN
url_escaping_charset=UTF-8
LocationVo
package com.zb.vo;
/**
* 测试的bean
*
* 创建日期:2016年7月22日 下午1:16:54
* 操作用户:zhoubang
*
*/
public class LocationVo {
private String areaName;// 区名字
private String cityName;// 城市名称
private String provinceName;// 省名称
public String getAreaName() {
return areaName;
}
public void setAreaName(String areaName) {
this.areaName = areaName;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getProvinceName() {
return provinceName;
}
public void setProvinceName(String provinceName) {
this.provinceName = provinceName;
}
}
OrderInfo
package com.zb.vo;
/**
* 测试的bean
*
* 创建日期:2016年7月22日 下午1:16:25
* 操作用户:zhoubang
*
*/
public class OrderInfo {
private String orderNo;// 订单号
private String storeName;// 门店名称
private String sendName;// 发件人姓名
private String sendTel;// 发件人电话
private String sendAddress;// 发件人地址
private String receiverName;// 收件人姓名
private String receiverTel;// 收件人电话
private String receiverAddress;// 收件人地址
private String productName;// 品名
private String proNameRemark;// 备注
private long weight;// 计费重量(克)
private String trackNo;// 快递单号
private String backRemark;// 后台备注
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getStoreName() {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
public String getSendName() {
return sendName;
}
public void setSendName(String sendName) {
this.sendName = sendName;
}
public String getSendTel() {
return sendTel;
}
public void setSendTel(String sendTel) {
this.sendTel = sendTel;
}
public String getSendAddress() {
return sendAddress;
}
public void setSendAddress(String sendAddress) {
this.sendAddress = sendAddress;
}
public String getReceiverName() {
return receiverName;
}
public void setReceiverName(String receiverName) {
this.receiverName = receiverName;
}
public String getReceiverTel() {
return receiverTel;
}
public void setReceiverTel(String receiverTel) {
this.receiverTel = receiverTel;
}
public String getReceiverAddress() {
return receiverAddress;
}
public void setReceiverAddress(String receiverAddress) {
this.receiverAddress = receiverAddress;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProNameRemark() {
return proNameRemark;
}
public void setProNameRemark(String proNameRemark) {
this.proNameRemark = proNameRemark;
}
public long getWeight() {
return weight;
}
public void setWeight(long weight) {
this.weight = weight;
}
public String getTrackNo() {
return trackNo;
}
public void setTrackNo(String trackNo) {
this.trackNo = trackNo;
}
public String getBackRemark() {
return backRemark;
}
public void setBackRemark(String backRemark) {
this.backRemark = backRemark;
}
}
CommonUtils
package com.zb.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
public class CommonUtils {
public static boolean isEmpty(String s) {
return null == s || StringUtils.isEmpty(s.trim());
}
public static boolean isEmpty(Collection<?> s) {
return null == s || s.isEmpty();
}
public static boolean isNotEmpty(Collection<?> s) {
return !isEmpty(s);
}
public static boolean isNotEmpty(String redirect) {
return !isEmpty(redirect);
}
public static Date stringToDate(String dateString) {
if (CommonUtils.isEmpty(dateString)) {
return null;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return simpleDateFormat.parse(dateString);
} catch (ParseException e) {
return null;
}
}
public static String nowDateToString(String format) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
try {
return simpleDateFormat.format(new Date());
} catch (Exception e) {
return null;
}
}
public static String DateToString(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return simpleDateFormat.format(date);
} catch (Exception e) {
return null;
}
}
public static String joinKeyValue(Map<String, Object> map, String prefix, String suffix, String separator,
boolean ignoreEmptyValue, String... ignoreKeys) {
List<String> list = new ArrayList<String>();
if (map != null) {
for (Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
String value = ConvertUtils.convert(entry.getValue());
if (StringUtils.isNotEmpty(key) && !ArrayUtils.contains(ignoreKeys, key)
&& (!ignoreEmptyValue || StringUtils.isNotEmpty(value))) {
list.add(key + "=" + (value != null ? value : "") + "");
}
}
}
String s = (prefix != null ? prefix : "") + StringUtils.join(list, separator) + (suffix != null ? suffix : "");
return s;
}
public static String joinKeyValue(Map<String, Object> map, String prefix, String suffix, String valuePrefix,
String valueSuffix, String separator, boolean ignoreEmptyValue, String... ignoreKeys) {
List<String> list = new ArrayList<String>();
if (map != null) {
for (Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
String value = ConvertUtils.convert(entry.getValue());
if (StringUtils.isNotEmpty(key) && !ArrayUtils.contains(ignoreKeys, key)
&& (!ignoreEmptyValue || StringUtils.isNotEmpty(value))) {
list.add(key + "=" + valuePrefix + (value != null ? value : "") + valueSuffix);
}
}
}
String s = (prefix != null ? prefix : "") + StringUtils.join(list, separator) + (suffix != null ? suffix : "");
return s;
}
public static String joinValue(Map<String, Object> map, String prefix, String suffix, String separator,
boolean ignoreEmptyValue, String... ignoreKeys) {
List<String> list = new ArrayList<String>();
if (map != null) {
for (Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
String value = ConvertUtils.convert(entry.getValue());
if (StringUtils.isNotEmpty(key) && !ArrayUtils.contains(ignoreKeys, key)
&& (!ignoreEmptyValue || StringUtils.isNotEmpty(value))) {
list.add(value != null ? value : "");
}
}
}
return (prefix != null ? prefix : "") + StringUtils.join(list, separator) + (suffix != null ? suffix : "");
}
/**
* 分转元
*
* @param money
* @return
*/
public static String money(Long money) {
if (money == null) {
return "0.00";
}
return new BigDecimal(money).divide(new BigDecimal(100)).setScale(2, RoundingMode.DOWN).toString();
}
/**
* g转kg
*
* @param money
* @return
*/
public static String weight(Long weight) {
if (weight == null) {
return "0.000";
}
return new BigDecimal(weight).divide(new BigDecimal(1000)).setScale(3, RoundingMode.DOWN).toString();
}
/**
* kg转g
*
* @param money
* @return
*/
public static Long weight(String weight) {
if (CommonUtils.isEmpty(weight)) {
return null;
}
if (!weight.matches("^[0-9]+(\\.[0-9]{1,3})?$")) {
return null;
}
return new BigDecimal(weight).multiply(new BigDecimal(1000)).longValue();
}
/**
* 分转元
*
* @param money
* @return
*/
public static String fen2yuan(String money) {
if (money == null) {
return "0.00";
}
return new BigDecimal(money).divide(new BigDecimal(100)).setScale(2, RoundingMode.DOWN).toString();
}
/**
* 元转分
*
* @param money
* @return
*/
public static Long money(String money) {
if (CommonUtils.isEmpty(money)) {
return null;
}
if (!money.matches("^[0-9]+(\\.[0-9]{1,2})?$")) {
return null;
}
return new BigDecimal(money).multiply(new BigDecimal(100)).longValue();
}
}
EnumConverter
package com.zb.util;
import org.apache.commons.beanutils.converters.AbstractConverter;
public class EnumConverter extends AbstractConverter {
private final Class<?> enumClass;
public EnumConverter(Class<?> enumClass) {
this(enumClass, null);
}
public EnumConverter(Class<?> enumClass, Object defaultValue) {
super(defaultValue);
this.enumClass = enumClass;
}
@Override
protected Class<?> getDefaultType() {
return this.enumClass;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
protected Object convertToType(Class type, Object value) {
String stringValue = value.toString().trim();
return Enum.valueOf(type, stringValue);
}
protected String convertToString(Object value) {
return value.toString();
}
}
FreemarkerUtils
package com.zb.util;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletContext;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.converters.ArrayConverter;
import org.apache.commons.beanutils.converters.DateConverter;
import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import freemarker.core.Environment;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.utility.DeepUnwrap;
public final class FreemarkerUtils {
public static final String[] DATE_PATTERNS = new String[] { "yyyy", "yyyy-MM", "yyyyMM", "yyyy/MM", "yyyy-MM-dd", "yyyyMMdd", "yyyy/MM/dd", "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss", "yyyy/MM/dd HH:mm:ss" };
private static Configuration config = new Configuration();
private FreemarkerUtils() {
}
public static String buildHtml(ServletContext context, String templatePath, Map<String, Object> data)
throws Exception {
Configuration freemarkerCfg = new Configuration();
// 加载模版
freemarkerCfg.setServletContextForTemplateLoading(context, "/");
freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
// 指定模版路径
Template template = freemarkerCfg.getTemplate(templatePath, "UTF-8");
template.setEncoding("UTF-8");
// 静态页面路径
// 处理模版
StringWriter stringWriter = new StringWriter();
template.process(data, stringWriter);
String st = stringWriter.toString();
stringWriter.close();
return st;
}
private static final ConvertUtilsBean convertUtils;
static {
convertUtils = new ConvertUtilsBean() {
@Override
public String convert(Object value) {
if (value != null) {
Class<?> type = value.getClass();
if (type.isEnum() && super.lookup(type) == null) {
super.register(new EnumConverter(type), type);
} else if (type.isArray() && type.getComponentType().isEnum()) {
if (super.lookup(type) == null) {
ArrayConverter arrayConverter = new ArrayConverter(type,
new EnumConverter(type.getComponentType()), 0);
arrayConverter.setOnlyFirstToString(false);
super.register(arrayConverter, type);
}
Converter converter = super.lookup(type);
return ((String) converter.convert(String.class, value));
}
}
return super.convert(value);
}
@SuppressWarnings("rawtypes")
@Override
public Object convert(String value, Class clazz) {
if (clazz.isEnum() && super.lookup(clazz) == null) {
super.register(new EnumConverter(clazz), clazz);
}
return super.convert(value, clazz);
}
@SuppressWarnings("rawtypes")
@Override
public Object convert(String[] values, Class clazz) {
if (clazz.isArray() && clazz.getComponentType().isEnum()
&& super.lookup(clazz.getComponentType()) == null) {
super.register(new EnumConverter(clazz.getComponentType()), clazz.getComponentType());
}
return super.convert(values, clazz);
}
@SuppressWarnings("rawtypes")
@Override
public Object convert(Object value, Class targetType) {
if (super.lookup(targetType) == null) {
if (targetType.isEnum()) {
super.register(new EnumConverter(targetType), targetType);
} else if (targetType.isArray() && targetType.getComponentType().isEnum()) {
ArrayConverter arrayConverter = new ArrayConverter(targetType,
new EnumConverter(targetType.getComponentType()), 0);
arrayConverter.setOnlyFirstToString(false);
super.register(arrayConverter, targetType);
}
}
return super.convert(value, targetType);
}
};
DateConverter dateConverter = new DateConverter();
dateConverter.setPatterns(DATE_PATTERNS);
convertUtils.register(dateConverter, Date.class);
}
public static String process(String template, Map<String, ?> model) throws IOException, TemplateException {
Configuration configuration = null;
ApplicationContext applicationContext = SpringUtils.getApplicationContext();
if (applicationContext != null) {
FreeMarkerConfigurer freeMarkerConfigurer = SpringUtils.getBean("freeMarkerConfigurer", FreeMarkerConfigurer.class);
if (freeMarkerConfigurer != null) {
configuration = freeMarkerConfigurer.getConfiguration();
}
}
return process(template, model, configuration);
}
public static String process(String template, Map<String, ?> model, Configuration configuration)
throws IOException, TemplateException {
if (template == null) {
return null;
}
if (configuration == null) {
configuration = new Configuration();
configuration.setTagSyntax(0);
}
StringWriter out = new StringWriter();
new Template("template", new StringReader(template), configuration).process(model, out);
return out.toString();
}
@SuppressWarnings("unchecked")
public static <T> T getParameter(String name, Class<T> type, Map<String, TemplateModel> params)
throws TemplateModelException {
Assert.hasText(name);
Assert.notNull(type);
Assert.notNull(params);
TemplateModel templateModel = params.get(name);
if (templateModel == null) {
return null;
}
Object value = DeepUnwrap.unwrap(templateModel);
return (T) convertUtils.convert(value, type);
}
public static TemplateModel getVariable(String name, Environment env) throws TemplateModelException {
Assert.hasText(name);
Assert.notNull(env);
return env.getVariable(name);
}
public static void setVariable(String name, Object value, Environment env) throws TemplateException {
Assert.hasText(name);
Assert.notNull(env);
if (value instanceof TemplateModel) {
env.setVariable(name, (TemplateModel) value);
} else {
env.setVariable(name, ObjectWrapper.BEANS_WRAPPER.wrap(value));
}
}
public static void setVariables(Map<String, Object> variables, Environment env) throws TemplateException {
Assert.notNull(variables);
Assert.notNull(env);
for (Entry<String, Object> entry : variables.entrySet()) {
String name = entry.getKey();
Object value = entry.getValue();
if (value instanceof TemplateModel) {
env.setVariable(name, (TemplateModel) value);
} else {
env.setVariable(name, ObjectWrapper.BEANS_WRAPPER.wrap(value));
}
}
}
}
SpringUtils
package com.zb.util;
import java.util.Locale;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.servlet.LocaleResolver;
@Component("springUtils")
@Lazy(false)
public final class SpringUtils implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext;
private SpringUtils() {
}
public void setApplicationContext(ApplicationContext applicationContext) {
SpringUtils.applicationContext = applicationContext;
}
public void destroy() throws Exception {
applicationContext = null;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
Assert.hasText(name);
return applicationContext.getBean(name);
}
public static <T> T getBean(String name, Class<T> type) {
Assert.hasText(name);
Assert.notNull(type);
return applicationContext.getBean(name, type);
}
public static String getMessage(String code, Object... args) {
LocaleResolver localeResolver = getBean("localeResolver", LocaleResolver.class);
Locale locale = localeResolver.resolveLocale(null);
return applicationContext.getMessage(code, args, locale);
}
}
DateMethod
package com.zb.template.method;
import java.util.List;
import org.springframework.stereotype.Component;
import com.zb.util.CommonUtils;
import freemarker.ext.beans.DateModel;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
@Component("dateUtilMethod")
public class DateMethod implements TemplateMethodModelEx {
@SuppressWarnings("rawtypes")
public Object exec(List arguments) throws TemplateModelException {
if (arguments != null && !arguments.isEmpty() && arguments.get(0) != null) {
DateModel code = (DateModel) arguments.get(0);
return new SimpleScalar(CommonUtils.DateToString(code.getAsDate()));
}
return null;
}
}
MoneyMethod
package com.zb.template.method;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import com.zb.util.CommonUtils;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
@SuppressWarnings("deprecation")
@Component("moneyMethod")
public class MoneyMethod implements TemplateMethodModel {
@SuppressWarnings("rawtypes")
public Object exec(List arguments) throws TemplateModelException {
if (arguments != null && !arguments.isEmpty() && arguments.get(0) != null && StringUtils.isNotEmpty(arguments.get(0).toString())) {
String code = arguments.get(0).toString();
return new SimpleScalar(CommonUtils.money(Long.parseLong(code)));
}
return null;
}
}
WeightMethod
package com.zb.template.method;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import com.zb.util.CommonUtils;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
@SuppressWarnings("deprecation")
@Component("weightMethod")
public class WeightMethod implements TemplateMethodModel {
@SuppressWarnings("rawtypes")
public Object exec(List arguments) throws TemplateModelException {
if (arguments != null && !arguments.isEmpty() && arguments.get(0) != null && StringUtils.isNotEmpty(arguments.get(0).toString())) {
String code = arguments.get(0).toString();
return new SimpleScalar(CommonUtils.weight(Long.parseLong(code)));
}
return null;
}
}
BarCodeController
package com.zb.controller;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.jbarcode.JBarcode;
import org.jbarcode.encode.Code39Encoder;
import org.jbarcode.encode.EAN13Encoder;
import org.jbarcode.paint.BaseLineTextPainter;
import org.jbarcode.paint.EAN13TextPainter;
import org.jbarcode.paint.WideRatioCodedPainter;
import org.jbarcode.paint.WidthCodedPainter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.zb.util.CommonUtils;
/**
* 获取条形码
*
*
* 创建日期:2016年7月22日 下午1:13:11
* 操作用户:zhoubang
*
*/
@Controller
@RequestMapping("/barCode")
public class BarCodeController {
@RequestMapping(value = "/getBarCodeByCode")
public String getBarCodeByCode(String code, HttpServletResponse response, boolean noText) throws Exception {
try {
if (!CommonUtils.isEmpty(code)) {
JBarcode jBarcode = getJbarcode();
jBarcode.setShowText(!noText);
ImageIO.write(jBarcode.createBarcode(StringUtils.upperCase(code)), "jpeg", response.getOutputStream());
response.getOutputStream().flush();
response.getOutputStream().close();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static JBarcode getJbarcode() {
JBarcode localJBarcode = new JBarcode(EAN13Encoder.getInstance(), WidthCodedPainter.getInstance(), EAN13TextPainter.getInstance());
localJBarcode.setEncoder(Code39Encoder.getInstance());
localJBarcode.setPainter(WideRatioCodedPainter.getInstance());
localJBarcode.setTextPainter(BaseLineTextPainter.getInstance());
localJBarcode.setShowCheckDigit(false);
localJBarcode.setCheckDigit(false);
return localJBarcode;
}
}
PrintPdfController
package com.zb.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.lowagie.text.pdf.BaseFont;
import com.zb.util.CommonUtils;
import com.zb.util.FreemarkerUtils;
import com.zb.vo.LocationVo;
import com.zb.vo.OrderInfo;
/**
* pdf文件打印
*
*/
@Controller
@RequestMapping("/printpdf")
public class PrintPdfController {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 全局的测试数据集合
*/
private static List<OrderInfo> orderInfos = new ArrayList<OrderInfo>();
private static List<LocationVo> sendLocationVos = new ArrayList<LocationVo>();
private static List<LocationVo> receiverLocationVos = new ArrayList<LocationVo>();
private static List<String> customerNames = new ArrayList<>();
/**
* 初始化测试数据
*/
static{
initData();
}
/**
* 打印PDF
*
* 创建日期:2016年7月22日 下午1:04:26
* 操作用户:zhoubang
*
* @param request
* @param response
* @throws Exception
*/
@RequestMapping(value = "/freemarker")
public void send(HttpServletRequest request, HttpServletResponse response) throws Exception {
logger.debug("pdf文件打印");
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
Map<String, Object> root = new HashMap<>();
root.put("base", basePath);
root.put("orderInfos", orderInfos);
root.put("sendlvs", sendLocationVos);
root.put("receiverlvs", receiverLocationVos);
root.put("customerNames", customerNames);
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment;filename=print.pdf");//print.pdf 是生成的文件名称
try {
String frontPath = new ClassPathResource("../printTemplete/msyh.ttf").getFile().getAbsolutePath();
String templateString = FileUtils.readFileToString(new ClassPathResource("../printTemplete/ems.ftl").getFile());//加载读取模板内容
//调用具体打印pdf方法
printPdf(root, templateString, frontPath, response.getOutputStream());
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 打印PDF具体代码
*
* 创建日期:2016年7月22日 下午1:07:38
* 操作用户:zhoubang
*
* @param root
* @param templateString
* @param frontPath
* @param outputStream
*/
private void printPdf(Map<String, Object> root, String templateString, String frontPath, ServletOutputStream outputStream) {
String ttt = null;
try {
ttt = FreemarkerUtils.process(templateString, root);
ITextRenderer iTextRenderer = new ITextRenderer();
iTextRenderer.setDocumentFromString(ttt);
if (CommonUtils.isNotEmpty(frontPath)) {
ITextFontResolver fontResolver = iTextRenderer.getFontResolver();
fontResolver.addFont(frontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
}
iTextRenderer.layout();
iTextRenderer.createPDF(outputStream);
} catch (Exception e) {
logger.info("打印ems模板单出错" + e.getMessage());
}
if (ttt == null) {
logger.info("打印ems模板单出错,生成模板为空");
return;
}
}
/**
* 初始化一些测试数据。
* 注意:如果想在一个PDF文件中,生成多个单子,则,可以手动为每一个List集合中加入相应的对象。
* 你也可以将下面的注释去掉,就会生成2个单子的PDF。更多的单子,以此类推。实际开发的时候,肯定是读取数据库,进行遍历。
*
* 创建日期:2016年7月22日 下午1:02:27
* 操作用户:zhoubang
*
*/
public static void initData(){
//模拟数据
OrderInfo orderInfo = new OrderInfo();
orderInfo.setTrackNo("8648722123456");
orderInfo.setSendName("张三");
orderInfo.setSendAddress("上海市普陀区武宁路");
orderInfo.setReceiverName("李四");
orderInfo.setReceiverTel("15988888888");
orderInfo.setReceiverAddress("江苏省徐州市睢宁县");
orderInfo.setWeight(2000);
orderInfo.setOrderNo("20160722123456");
orderInfo.setProductName("衣物");
orderInfo.setProNameRemark("备注什么好呢");
orderInfos.add(orderInfo);
/*OrderInfo orderInfo2 = new OrderInfo();
orderInfo2.setTrackNo("99999999999999");
orderInfo2.setSendName("王武");
orderInfo2.setSendAddress("上海市徐汇区田林路");
orderInfo2.setReceiverName("孙倩");
orderInfo2.setReceiverTel("15978978978");
orderInfo2.setReceiverAddress("江苏省南京市");
orderInfo2.setWeight(5000);
orderInfo2.setOrderNo("20160722987889");
orderInfo2.setProductName("动物");
orderInfo2.setProNameRemark("备注什么好呢");
orderInfos.add(orderInfo2);*/
LocationVo vo = new LocationVo();
vo.setProvinceName("上海市");
vo.setCityName("上海市");
vo.setAreaName("徐汇区");
sendLocationVos.add(vo);
/*LocationVo voo = new LocationVo();
voo.setProvinceName("北京市");
voo.setCityName("北京市");
voo.setAreaName("朝阳区");
sendLocationVos.add(voo);*/
LocationVo vo2 = new LocationVo();
vo2.setProvinceName("江苏省");
vo2.setCityName("徐州市");
vo2.setCityName("睢宁县");
receiverLocationVos.add(vo2);
/*LocationVo vo22 = new LocationVo();
vo22.setProvinceName("江苏省");
vo22.setCityName("泰州市");
vo22.setCityName("未知县");
receiverLocationVos.add(vo22);*/
customerNames.add("上海麦当劳有限公司");
//customerNames.add("上海肯德基有限公司");
}
}