freemarker生成pdf工具類

依賴:

		<dependency>
			<groupId>org.xhtmlrenderer</groupId>
			<artifactId>flying-saucer-pdf</artifactId>
			<version>9.1.18</version>
		</dependency>

中文轉換工具和模板目錄:

 

轉換工具下載鏈接:https://pan.baidu.com/s/1Y83-8TmETRhOUSJ_QyKgfg  密碼:gqw0

工具類: 

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
import freemarker.core.ParseException;
import freemarker.template.*;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

@SuppressWarnings("deprecation")
public class PdfUtils {

    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 {
        Version version = new Version("2.3.25");
        Configuration config = new Configuration(version);
        config.setDirectoryForTemplateLoading(new File(templatePath));
        config.setEncoding(Locale.CHINA, "utf-8");
        return config;
    }

    /**
     * 獲取類路徑
     * @return
     */
    public static String getPath(){
       // return "/"+ PdfUtils.class.getResource("/").getPath().substring(1);
        return PdfUtils.class.getResource("/").getPath();
    }

    /**
     * 生成PDF到文件
     * @param ftlPath 模板文件路徑(不含文件名)
     * @param ftlName 模板文件名(不含路徑)
     * @param data 數據
     * @param outputFile 目標文件(全路徑名稱)
     * @throws Exception
     */
    public static void generateToFile(String ftlPath,String ftlName,Object data,String outputFile) throws Exception {
        String html= getPdfContent(ftlPath, ftlName, data);
        OutputStream out = null;
        ITextRenderer render = null;
        out = new FileOutputStream(outputFile);
        render = getRender();
        render.setDocumentFromString(html);
        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,String title, HttpServletResponse response) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException, DocumentException{
        String html=getPdfContent(ftlPath, ftlName, data);
        String outName = title+".pdf";
        OutputStream out = null;
        ITextRenderer render = null;
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename="+new String(outName.getBytes("UTF-8"), "ISO8859-1"));
        out = response.getOutputStream();
        render = 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;
    }
}

測試:

public static void main(String[] args) {
        try {

            Map<Object, Object> o=new HashMap<Object, Object>();
            //存入一個集合
            List<String> list = new ArrayList<String>();
            list.add("xiaoming");
            list.add("張三");
            list.add("李四");
            o.put("name", "my name is rose");
            o.put("nameList", list);

            list.forEach(System.out::println);

            String path = getPath();

            generateToFile(path, "tpl2.ftl", o, "/Users/json/個人文稿/開發/191120-cpr/模版/xdemo.pdf");

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(getPath());

    }

模板文件:

<!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>
    <meta charset="utf-8" />
    <title>
    </title>
    <style>
        /*解決html轉pdf文件中文不顯示的問題*/
        body {
            font-family: SimSun;
        }
    </style>
</head>
<body>
    <#list cprMap as list>
        <#if list['cpr1'].studentName??>
             ${list['cpr1'].studentName!""}
             ${list['cpr1'].courseDate!""}
        </#if>
    </#list>
</body>
</html>

 

發佈了260 篇原創文章 · 獲贊 57 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章