<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.31</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.2</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.13.2</version> </dependency>
1.freemark动态解析html工具
import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import lombok.AccessLevel; import lombok.NoArgsConstructor; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.nio.charset.Charset; /** * @author huangrusheng * @version 1.0 * @date 2021/5/24 10:25 */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class FreeMarkUtil { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private static final Configuration configuration; static { configuration = new Configuration(Configuration.VERSION_2_3_30); configuration.setDefaultEncoding(DEFAULT_CHARSET.name()); configuration.setClassLoaderForTemplateLoading(getDefaultClassLoader(), "ftl"); } public static void parse(Object params, String templateName, Writer writer) throws IOException, TemplateException { Template template = configuration.getTemplate(templateName); template.process(params,writer); } public static byte[] parse(Object params,String templateName) throws IOException, TemplateException { StringWriter stringWriter = new StringWriter(); parse(params,templateName,stringWriter); System.out.println(stringWriter.toString()); return stringWriter.toString().getBytes(DEFAULT_CHARSET); } public static ClassLoader getDefaultClassLoader(){ ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader != null){ return classLoader; } classLoader = FreeMarkUtil.class.getClassLoader(); if(classLoader != null){ return classLoader; } return ClassLoader.getSystemClassLoader(); } }
2.html转换为pdf工具
import cn.hrs.tools.export.FreeMarkUtil; import cn.hutool.core.util.StrUtil; import com.itextpdf.text.Document; import com.itextpdf.text.Font; import com.itextpdf.text.PageSize; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.tool.xml.XMLWorkerFontProvider; import com.itextpdf.tool.xml.XMLWorkerHelper; import lombok.AccessLevel; import lombok.NoArgsConstructor; import java.io.ByteArrayInputStream; import java.io.OutputStream; /** * @author huangrusheng * @version 1.0 * @date 2021/5/24 15:03 */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class PDFUtil { public static void exportByHtml(Object params, String templateName, OutputStream outputStream)throws Exception{ exportByHtml(params,templateName,outputStream,null); } public static void exportByHtml(Object params, String templateName, OutputStream outputStream, Rectangle rectangle) throws Exception{ Document document = null; try{ document = new Document(rectangle == null ? PageSize.A4 : rectangle); PdfWriter pdfWriter = PdfWriter.getInstance(document,outputStream); document.open(); XMLWorkerHelper xmlWorkerHelper = XMLWorkerHelper.getInstance(); xmlWorkerHelper.parseXHtml(pdfWriter,document, new ByteArrayInputStream(FreeMarkUtil.parse(params,templateName)),FreeMarkUtil.DEFAULT_CHARSET ,new SongTiFontProvider()); }finally { if (document != null){ document.close(); } } } public static class SongTiFontProvider extends XMLWorkerFontProvider{ @Override public Font getFont(final String fontName, String encoding, float size, final int style){ String fntName = fontName; if(StrUtil.isBlank(fntName)){ fntName = "宋体"; } float newSize = size; if(newSize == 0){ newSize = 4; } return super.getFont(fntName,encoding,newSize,style); } } }
1.ftl模板
<html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <body> <h1>${name}</h1> <p> <table border="1"> <tr> <td style="width:80%"> ${introduce}</td> <td style="width:20%"> <img style="width:100px;height:100px;float:right" src="${address}"/></td> </tr> </table> </p> </body> </html>
2.代码
import cn.hrs.tools.export.pdf.PDFUtil; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.io.FileOutputStream; import java.util.HashMap; import java.util.Map; /** * @author huangrusheng * @version 1.0 * @date 2021/5/24 15:47 */ @RunWith(JUnit4.class) public class PDFUtilTest { @Test public void exportPDF() throws Exception{ FileOutputStream outputStream = new FileOutputStream("D:\\hrs.pdf"); Map<String,Object> params = new HashMap<>(3); params.put("name","智能安防方案"); params.put("introduce","利用了智能视频分析技术提供的报警信息的安防系统就称为智能安防系统 。" + "而由于智能分析的图像识别特性,它与安防系统中的监控系统结合是最会紧密的,智能监控系统也是安防系统中智能分析应用最成熟的系统。也就是说智能分析技术在安防系统中的应用发展方向是两个,一是不断提高分析技术,提供更准确更丰富的报警结果;二是不断优化安防系统方案,充分利用智能分析技术的特点,将智能分析的报警结果智能地应用到安防体系中。"); params.put("address","https://profile.csdnimg.cn/A/5/D/1_m0_38138879"); PDFUtil.exportByHtml(params,"text.ftl",outputStream); outputStream.close(); } }
3.结果
模板位置: