ftl生成pdf支持分页和复杂表格

您所在的位置:网站首页 Freemark导出word里图片不显示 ftl生成pdf支持分页和复杂表格

ftl生成pdf支持分页和复杂表格

2023-03-09 07:14| 来源: 网络整理| 查看: 265

SpringBoot通过FreeMarker生成pdf中遇到的难点记录

一、Configuration加载ftl模板

1.如果模板是放在本地盘符中

String templateName = "abc.ftl"; Configuration cfg = new Configuration(Configuration.VERSION_2_3_23); cfg.setDefaultEncoding("UTF-8"); cfg.setDirectoryForTemplateLoading(new File("E:/")); Template template = cfg.getTemplate(templateName);

2如果模板是放在Springboot项目的resource路径下

String templateName = "abc.ftl"; Configuration cfg = new Configuration(Configuration.VERSION_2_3_23); cfg.setDefaultEncoding("UTF-8"); cfg.setClassForTemplateLoading(this.getClass(), "/"); Template template = cfg.getTemplate(templateName);

3如果生成了模板可以使用字符流接收然后转换成文件流,不需要生成到本地

private StringWriter htmHandler(String templateName, Map paramMap) throws Exception { Configuration cfg = new Configuration(Configuration.VERSION_2_3_23); // Configuration cfg = new Configuration(); cfg.setDefaultEncoding("UTF-8"); // 获取模板的路径 System.out.println("==================获取模板路径======================="); // cfg.setClassForTemplateLoading(this.getClass(), "/"); cfg.setDirectoryForTemplateLoading(new File("E:/")); System.out.println(cfg.getTemplateLoader().toString()); System.out.println("===================获取模板路径成功======================="); //设置模板 Template template = cfg.getTemplate(templateName); StringWriter out = new StringWriter(); template.process(paramMap, out); return out; }

二、ftl文件生成pdf,导入项目中的图片

如果直接在src中写死一个本地路径也是可以读取显示的,不过无法做到动态赋值的效果

如果使用动态赋值的方式,java中的代码只能通过uri的方式,这里使用com.itextpdf.text.Image类来接收一个url并转成uri路径

URL url = Thread.currentThread().getContextClassLoader().getResource("baidu.jpg"); Image image = Image.getInstance(url); params.put("image", image.getUrl().toURI());

三、遇到一个需求是打印pdf时表格分页截断后需要在第二页有表头,这个纯css就可以实现。

关键样式

// 固定页面大小 @page { margin-left: 7mm; margin-right: 7mm; margin-bottom: 20mm; margin-top: 13mm; }

表格中需要有结构

表格样式

.srv-table{ page-break-inside:auto; -fs-table-paginate:paginate; border-spacing:0; word-break:break-strict; } .srv-table-tr{ page-break-inside:avoid; page-break-after:auto; }

效果

完整代码提供

/*解决html转pdf文件中文不显示的问题*/ body { font-family: SimSun; font-weight: bold; font-size: 11px; } /*设定纸张大小*/ /* A4纸 */ /* @page{size:210mm*297mm} */ /*@page{size: 210mm 297mm}*/ /*@page{size: 210mm 297mm}*/ table { width: 100%; margin-top: 4mm; } img { background: #fff; box-shadow: none; } @page :first { margin-top: 0mm; } @page { margin-left: 7mm; margin-right: 7mm; margin-bottom: 20mm; margin-top: 13mm; } .srv-table{ page-break-inside:auto; -fs-table-paginate:paginate; border-spacing:0; word-break:break-strict; } .srv-table-tr{ page-break-inside:avoid; page-break-after:auto; } 图片 明细 NO 编码 名称 类型 作业组 价格 ${arr_index + 1} ${arr.srvCode!} ${arr.srvName!?html} ${arr.srvTypeName!} ${arr.workByCode!} ¥${(arr.settlType! == 2) ? string(0, arr.sellPrice!?string(",##0.00"))} ${(arr.msuiteCode! == '')?string(arr.selfDealerSetMealCode!, arr.msuiteCode!)} package com.pdf.gtmcafterpdf.pdf; import com.itextpdf.text.Image; import com.itextpdf.text.pdf.BaseFont; import com.pdf.gtmcafterpdf.Templates.SrvList; import freemarker.template.Configuration; import freemarker.template.Template; import org.xhtmlrenderer.pdf.ITextRenderer; import javax.xml.bind.DatatypeConverter; import java.io.*; import java.net.URL; import java.util.*; public class BlogPdf { public static void main(String[] args) throws Exception { String templateName ="blog.ftl"; Map params = new HashMap(16); URL url = Thread.currentThread().getContextClassLoader().getResource("baidu.jpg"); Image image = Image.getInstance(url); params.put("image", image.getUrl().toURI()); Scanner scanner = new Scanner(System.in); System.out.println("请输入项目数量:"); if (scanner.hasNextLine()){ Integer srvNum = Integer.parseInt(scanner.nextLine()); System.out.println("目前项目数量:" + srvNum); params.put("srvList", getSrvList(srvNum)); }else{ params.put("srvList", getSrvList(0)); } StringWriter stringWriter = new BlogPdf().htmHandler(templateName, params); new BlogPdf().blogPdfHandler(stringWriter); } public static List getSrvList(int num){ List list = new ArrayList(); for (int i = 0; i < num; i++) { SrvList srvList = new SrvList(); srvList.setSrvCode("100000"+i); srvList.setSrvName("作业项目"); srvList.setSrvTypeName("A"); srvList.setSettlType(2); srvList.setSellPrice(100.00); srvList.setSelfDealerSetMealCode("2001"); list.add(srvList); } return list; } private StringWriter htmHandler(String templateName, Map paramMap) throws Exception { Configuration cfg = new Configuration(Configuration.VERSION_2_3_23); // Configuration cfg = new Configuration(); cfg.setDefaultEncoding("UTF-8"); // 获取模板的路径 System.out.println("==================获取模板路径======================="); // cfg.setClassForTemplateLoading(this.getClass(), "/"); cfg.setDirectoryForTemplateLoading(new File("E:/")); System.out.println(cfg.getTemplateLoader().toString()); System.out.println("===================获取模板路径成功======================="); //设置模板 Template template = cfg.getTemplate(templateName); StringWriter out = new StringWriter(); template.process(paramMap, out); return out; } private void blogPdfHandler(StringWriter writer)throws Exception { StringBuffer buffer = writer.getBuffer(); ByteArrayOutputStream os = new ByteArrayOutputStream(); ITextRenderer renderer = new ITextRenderer(); System.out.println(buffer.toString()); renderer.setDocumentFromString(buffer.toString()); org.xhtmlrenderer.pdf.ITextFontResolver fontResolver = renderer .getFontResolver(); try { System.out.println("====================================获取字体路径================================"); String path = Thread.currentThread().getContextClassLoader().getResource("simsun.ttf").toString(); System.out.println("=====================================获取字体路径成功"+path+"==========================================="); fontResolver.addFont(path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); } catch (Exception e) { e.printStackTrace(); } renderer.layout(); try { renderer.createPDF(os); } catch (Exception e) { e.printStackTrace(); } os.close(); // 将文件流转成base64返回前端 String binary = printBase64Binary(os); System.out.println(binary); // String savePath = "E:\\"; String savePath = "E:/"; String fileName = "blog.pdf"; System.out.println("文件保存路径=>{}"+savePath+fileName); base64ToFile(binary, fileName, savePath); } // 文件转成base64 public String printBase64Binary(ByteArrayOutputStream os){ byte[] bytes = os.toByteArray(); String strPDF = DatatypeConverter.printBase64Binary(bytes); return strPDF; } // base64转成pdf public void base64ToFile(String base64, String fileName, String savePath) { File file = null; //创建文件目录 String filePath = savePath; File dir = new File(filePath); if (!dir.exists() && !dir.isDirectory()) { dir.mkdirs(); } BufferedOutputStream bos = null; java.io.FileOutputStream fos = null; try { byte[] bytes = Base64.getDecoder().decode(base64); file=new File(filePath + fileName); fos = new java.io.FileOutputStream(file); bos = new BufferedOutputStream(fos); bos.write(bytes); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3