java使用freemark生成pdf

1.首先通过maven的pom.xml文件引入jar包

<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.freemarker</groupId>
			<artifactId>freemarker</artifactId>
			<version>2.3.22</version>
		</dependency>
		<dependency>
			<groupId>org.xhtmlrenderer</groupId>
			<artifactId>flying-saucer-pdf</artifactId>
			<version>9.0.3</version>
		</dependency>

2.编写一个PDF生成辅助类

package yang.zheng.util.pdf;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Locale;

import org.xhtmlrenderer.pdf.ITextRenderer;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
 
/**
 * PDF生成辅助类
 * @author Goofy <a href="http://www.xdemo.org">http://www.xdemo.org</a>
 *
 */
@SuppressWarnings("deprecation")
public class PdfHelper {
 
    public static ITextRenderer getRender() throws DocumentException, IOException {
 
        ITextRenderer render = new ITextRenderer();
 
        String path = getPath();
        //添加字体,以支持中文
        render.getFontResolver().addFont(path + "pdf/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        render.getFontResolver().addFont(path + "pdf/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
 
        return render;
    }
 
    //获取要写入PDF的内容
    public static String getPdfContent(String ftlPath, String ftlName, Object o) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
        return useTemplate(ftlPath, ftlName, o);
    }
 
    //使用freemarker得到html内容
    public static String useTemplate(String ftlPath, String ftlName, Object o) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
 
        String html = null;
 
        Template tpl = getFreemarkerConfig(ftlPath).getTemplate(ftlName);
        tpl.setEncoding("UTF-8");
 
        StringWriter writer = new StringWriter();
        tpl.process(o, writer);
        writer.flush();
        html = writer.toString();
        return html;
    }
 
    /**
     * 获取Freemarker配置
     * @param templatePath
     * @return
     * @throws IOException
     */
    private static Configuration getFreemarkerConfig(String templatePath) throws IOException {
    	freemarker.template.Version version = new freemarker.template.Version("2.3.22");
        Configuration config = new Configuration(version);
        config.setDirectoryForTemplateLoading(new File(templatePath));
        config.setEncoding(Locale.CHINA, "utf-8");
        return config;
    }
     
    /**
     * 获取类路径
     * @return
     */
    public static String getPath(){
        return PdfHelper.class.getResource("/").getPath().substring(1);
    }
 
}
3.编写一个pdf工具类

package yang.zheng.util.pdf;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.xhtmlrenderer.pdf.ITextRenderer;

import com.lowagie.text.DocumentException;

import freemarker.core.ParseException;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
 
/**
 * PDF生成工具类
 * @author Goofy <a href="http://www.xdemo.org">http://www.xdemo.org</a>
 *
 */
public class PdfUtils {
 
    public static void main(String[] args) {
        try {
 
            Map<Object, Object> o=new HashMap<Object, Object>();
            //存入一个集合
            List<String> list = new ArrayList<String>();
            list.add("小明");
            list.add("张三");
            list.add("李四");
            o.put("name", "http://www.xdemo.org/");
            o.put("nameList", list);
             
            String path=PdfHelper.getPath();
             
            generateToFile(path, "pdf/tpl.ftl",path+"pdf/", o, "D:\\xdemo.pdf");
             
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
     
    /**
     * 生成PDF到文件
     * @param ftlPath 模板文件路径(不含文件名)
     * @param ftlName 模板文件吗(不含路径)
     * @param imageDiskPath 图片的磁盘路径
     * @param data 数据
     * @param outputFile 目标文件(全路径名称)
     * @throws Exception
     */
    public static void generateToFile(String ftlPath,String ftlName,String imageDiskPath,Object data,String outputFile) throws Exception {
        String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
        OutputStream out = null;
        ITextRenderer render = null;
        out = new FileOutputStream(outputFile);
        render = PdfHelper.getRender();
        render.setDocumentFromString(html);
        if(imageDiskPath!=null&&!imageDiskPath.equals("")){
            //html中如果有图片,图片的路径则使用这里设置的路径的相对路径,这个是作为根路径
            render.getSharedContext().setBaseURL("file:/"+imageDiskPath);
        }
        render.layout();
        render.createPDF(out);
        render.finishPDF();
        render = null;
        out.close();
    }
     
    /**
     * 生成PDF到输出流中(ServletOutputStream用于下载PDF)
     * @param ftlPath ftl模板文件的路径(不含文件名)
     * @param ftlName ftl模板文件的名称(不含路径)
     * @param imageDiskPath 如果PDF中要求图片,那么需要传入图片所在位置的磁盘路径
     * @param data 输入到FTL中的数据
     * @param response HttpServletResponse
     * @return
     * @throws TemplateNotFoundException
     * @throws MalformedTemplateNameException
     * @throws ParseException
     * @throws IOException
     * @throws TemplateException
     * @throws DocumentException
     */
    public static OutputStream generateToServletOutputStream(String ftlPath,String ftlName,String imageDiskPath,Object data,HttpServletResponse response) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException, DocumentException{
        String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
        OutputStream out = null;
        ITextRenderer render = null;
        out = response.getOutputStream();
        render = PdfHelper.getRender();
        render.setDocumentFromString(html);
        if(imageDiskPath!=null&&!imageDiskPath.equals("")){
            //html中如果有图片,图片的路径则使用这里设置的路径的相对路径,这个是作为根路径
            render.getSharedContext().setBaseURL("file:/"+imageDiskPath);
        }
        render.layout();
        render.createPDF(out);
        render.finishPDF();
        render = null;
        return out;
    }
}
4.pdf生成模板(tpl.ftl)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style type="text/css">
body {
    margin-left: 45px;
    margin-right: 45px;
    font-family: Arial Unicode MS;
    font-size: 10px;
}
 
table {
    margin: auto;
    width: 100%;
    border-collapse: collapse;
    border: 1px solid #444444;
}
 
th,td {
    border: 1px solid #444444;
    font-size: 10px;
    margin-left: 5px;
}
 
.mcContent {
    line-height: 180%;
    padding: 20px;
}
 
.logo {
    text-align: center;
}
 
.title {
    text-align: center;
    font-weight: bold;
    font-size: 20px;
}
 
.notes {
    font-weight: normal;
    margin-left: 5px;
    margin-right: 5px;
    line-height: 18px;
}
 
.text_content {
    margin-left: 5px;
    margin-right: 5px;
    line-height: 18px;
}
 
.sum_insured_first_row {
    width: 20%;
}
 
.sum_insured_span {
    font-size: 10px;
}
 
.special_agreements_div {
    page-break-before: always;
    font-size: 14px;
    margin-top: 20px;
}
 
.special_agreements_div .special_agreements {
    font-size: 18px;
    font-weight: bold;
}
 
.title_right {
    width: 100%;
    margin: 0 auto;
}
 
.title_right p {
    text-align: left;
    margin: 0;
    margin-left: 50%;
    padding: 0;
}
 
@page {
    size: 8.5in 11in;
    @
    bottom-center
    {
    content
    :
    "page "
    counter(
    page
    )
    " of  "
    counter(
    pages
    );
}
 
.signature {
    margin: 0 auto;
    clear: both;
    font-size: 16px;
    font-weight: bold;
}
 
.signature_table {
/*     font-size: 16px; */
    font-weight: bold;
}
 
</style>
</head>
<body>
    作者:<a href="http://www.xdemo.org/">http://www.xdemo.org/</a>
    <div>
        <p>你好:${name}</p>
        <div class="logo"><!--这里的图片使用相对与ITextRenderer.getSharedContext().setBaseURL("file:/"+imageDiskPath);的路径-->
            图片支持<img src="logo1.png" />
        </div>
        <div>
            <p>Hello PDF: 中文支持</p>
            <div style="border:1px solid red;color:red;">
                样式支持,红边框,红字
            </div>
            <div style="border:10px solid blue;color:blue;">
                样式支持,蓝色10像素的边框,蓝字
            </div>
            <hr/>
            <table>
                <tr style="background:gray;">
                    <th>A</th>
                    <th>B</th>
                    <th>C</th>
                    <th>D</th>
                </tr>
                <tr>
                    <td>100</td>
                    <td>29</td>
                    <td>32</td>
                    <td>43</td>
                </tr>
                <tr>
                    <td>100</td>
                    <td>29</td>
                    <td>32</td>
                    <td>43</td>
                </tr>
                <tr>
                    <td>100</td>
                    <td>29</td>
                    <td>32</td>
                    <td>43</td>
                </tr>
                <tr>
                    <td>100</td>
                    <td>29</td>
                    <td>32</td>
                    <td>43</td>
                </tr>
                <tr>
                    <td>100</td>
                    <td>29</td>
                    <td>32</td>
                    <td>43</td>
                </tr>
                <tr>
                <#list nameList as list>
                  <td>${list}</td>
                 </#list>
                </tr>
            </table>
        </div>
    </div>
</body>
</html>
5.字体

 生成pdf工具类中使用了两种字体分别为arialuni.ttf和simsun.ttc,请大家自行到百度中搜索下载。



评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值