Java生成pdfについて
SpringBoot freemarker iTextレンダリングhtmlテンプレートからPDF maven依存をエクスポート
PDF書き出しfreemarkerが必要なレンダリングテンプレートftlファイル
ftlテンプレートに関するいくつかの情報:ftlテンプレートはhtmlと一致するラベルを使用し、htmlとは異なりftlテンプレートファイルはif-else、forなどの独自の論理要素演算ラベルを追加することができ、論理演算ラベルはfreemarkerの公式ドキュメントを参照することができます.
https://freemarker.apache.org/docs/ref_directives.html
上のすべてが正常な時.macOS 15.4バージョンのシステムでは、macOSシステムが持参したフォントを使用してpdfを生成する際にエラーが発生します.具体的な原因は不明です.解決策はWindowsシステムに中国語のフォントをコピーすればいいです.
org.freemarker
freemarker
${freemarker.version}
org.xhtmlrenderer
flying-saucer-pdf
${flying-saucer-pdf.version}
com.itextpdf
itextpdf
${itextpdf.version}
2.3.28
9.1.16
5.5.13
PDF書き出しfreemarkerが必要なレンダリングテンプレートftlファイル
ftlテンプレートに関するいくつかの情報:ftlテンプレートはhtmlと一致するラベルを使用し、htmlとは異なりftlテンプレートファイルはif-else、forなどの独自の論理要素演算ラベルを追加することができ、論理演算ラベルはfreemarkerの公式ドキュメントを参照することができます.
https://freemarker.apache.org/docs/ref_directives.html
package com.shopping.rbac.util;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
import com.shopping.rbac.entity.ShoppingOrderDetailEntity;
import com.shopping.rbac.rest.app.order.response.GetShoppingOrderRes;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
* @author hanqy
* @version 1.0
* @CreateDate 2020/6/18 8:26
*/
public class PDFUtil {
private static final String fontFile = "/Users/hanqy/Desktop/ /SIMSUN.TTC";
private static final String pdfFile = "/Users/hanqy/Desktop/ /pdfdemo.pdf";
private static final String htmlTmpFile = "/Users/hanqy/Desktop/ /orderPrepare.ftl";
public static void main(String[] args) {
Map dataMap = new HashMap<>();
GetShoppingOrderRes getShoppingOrderRes = new GetShoppingOrderRes();
getShoppingOrderRes.setId(123);
getShoppingOrderRes.setPrice(new BigDecimal(50));
getShoppingOrderRes.setWxName("test ");
getShoppingOrderRes.setNum(10);
getShoppingOrderRes.setOrderTime(DateHelper.formatDate(new Date(), DateHelper.DATE_FORMAT_YYYYMMDDHHMMSS));
List shoppingOrderDetailEntities = new ArrayList<>();
BigDecimal countSum = new BigDecimal(0);
for (int i = 1; i <= 5; i++) {
ShoppingOrderDetailEntity shoppingOrderDetailEntity = new ShoppingOrderDetailEntity();
shoppingOrderDetailEntity.setNum(5);
shoppingOrderDetailEntity.setPrice(new BigDecimal(1));
shoppingOrderDetailEntity.setName(" " + i);
shoppingOrderDetailEntity.setSum(shoppingOrderDetailEntity.getPrice().multiply(new BigDecimal(shoppingOrderDetailEntity.getNum())));
countSum = countSum.add(countSum.add(shoppingOrderDetailEntity.getSum()));
shoppingOrderDetailEntities.add(shoppingOrderDetailEntity);
}
dataMap.put("order", getShoppingOrderRes);
dataMap.put("details", shoppingOrderDetailEntities);
dataMap.put("countsum", countSum);
dataMap.put("discount", "0");
dataMap.put("actuallypaid", countSum);
String pdfData = freemarkerRender(dataMap, htmlTmpFile);
createPDF(pdfData, fontFile, pdfFile);
}
/**
* Freemarker html
*
* @param dataMap thml Map
* @param htmlTmpFile thml ( + )
*/
public static String freemarkerRender(Map dataMap, String htmlTmpFile) {
Configuration cfg = new Configuration();
cfg.setDefaultEncoding("UTF-8");
Writer out = new StringWriter();
try {
//
int num = htmlTmpFile.lastIndexOf('/');
if (num == -1) {
num = htmlTmpFile.lastIndexOf('\\');
}
//
cfg.setDirectoryForTemplateLoading(new File(htmlTmpFile.substring(0, num)));
Template template = cfg.getTemplate(htmlTmpFile.substring(num));
//
template.process(dataMap, out);
out.flush();
return out.toString();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* Itext PDF
*
* @param htmlTmpStr html
* @param fontFile ( + )
* @param pdfFile PDF ( + )
*/
public static void createPDF(String htmlTmpStr, String fontFile, String pdfFile) {
File pdf = new File(pdfFile);
try {
OutputStream out = new FileOutputStream(pdf);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(htmlTmpStr);
ITextFontResolver fontResolver = renderer.getFontResolver();
// , (ttc)
fontResolver.addFont(fontFile, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(out);
if (out != null) {
out.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
上のすべてが正常な時.macOS 15.4バージョンのシステムでは、macOSシステムが持参したフォントを使用してpdfを生成する際にエラーが発生します.具体的な原因は不明です.解決策はWindowsシステムに中国語のフォントをコピーすればいいです.