Java生成pdfについて

6487 ワード

SpringBoot freemarker iTextレンダリングhtmlテンプレートからPDF maven依存をエクスポート
 
            
                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システムに中国語のフォントをコピーすればいいです.