依賴:
<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>