freemarker根据Word模板导出PDF

题外话:帖子百度搜了半天多,没找到合适的,如果你需求差不多,可以省很多时间

需求

每个主体的信息自然是不同的,需要基于word模板,填充主体的数据,浏览器导出PDF(PDF有2页)。

需求模板如下

实现思路

freemarker+spire.doc.free

数据库读取相关数据->freemarker语法渲染->spire.doc.free转为PDF流->写入response流导出

说明:

spire.doc:第三方收费包,有个免费包:spire.doc.free

不采用其他jar包的原因,要么收费,要么格式错乱

实现步骤

1、编辑word,需要填充的字段用 ${xxx}

2、word另存为xml格式(不重名为.ftl也是可以的)

3、resources目录下创建templates文件夹,存放xml文件

4、   ①处理xml文件 每个$变量后添加 "?if_exists"

                作用:如果不加,该值为空会报错。

        ②检查下${} 大括号内是否有xml的代码!有的会带

5、pom引用

 <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.32</version>
  </dependency>
  <dependency>
      <groupId>com.bestpay.spiredoc</groupId>
      <artifactId>spire.doc.free</artifactId>
      <version>5.2.0</version>
  </dependency>

6、后端主要代码

//引用的包
import com.spire.doc.Document;
import com.spire.doc.FileFormat;




//查询数据省略



//保存要导出的数据
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("custId", "客户号");
dataMap.put("custName", "客户名称");

//导出pdf
//模板存放路径
String templatesPath = "/templates";
FreemarkerFtlUtil freemarkerFtlUtil = new FreemarkerFtlUtil();
ByteArrayOutputStream outputStream = freemarkerFtlUtil.writeToByteArrayOutputStream(dataMap, templatesPath, tempName);

response.setContentType("application/pdf;charset=utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(dueDiLiGenceVO.getFileName() + ".pdf", "UTF8"));
//写出到响应流
Document document = new Document(new ByteArrayInputStream(outputStream.toByteArray()));
document.saveToStream(response.getOutputStream(), FileFormat.PDF);
document.close();








import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;

/**
 * @Author 
 * @Description freemarker操作 ftl文件工具类
 * @Param
 * @return
 **/
public class FreemarkerFtlUtil {

    //将数据写入到ftl模板中,并转为字节输出流
    public ByteArrayOutputStream writeToByteArrayOutputStream(Map<String, Object> dataMap, String templatePath,
                                                              String templateName) throws Exception {
        Configuration configuration = new Configuration(Configuration.getVersion());
        configuration.setClassForTemplateLoading(getClass(), templatePath);
        //下面方式Linux环境报错
//        configuration.setDirectoryForTemplateLoading(new File(templatePath));
        configuration.setDefaultEncoding("utf-8");

        //写出doc到流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Writer out = new OutputStreamWriter(baos, "UTF-8");
        Template template = configuration.getTemplate(templateName);
        template.process(dataMap, out);
        out.flush();
        return baos;

    }
}

1、关于spire.doc.free,一定需要用5.2.0,一定需要用5.2.0,一定需要用5.2.0!

5.1.0版本会报错!

2、freemarker加载模板的路径问题,按照上述操作,不会出现读不到的问题。

要根据Word模板导出Java代码,可以使用Apache POI和FreeMarker这两个开源库来实现。具体步骤如下: 1. 使用Apache POI读取Word模板文件,获取模板中的内容。 2. 将读取到的内容传递给FreeMarker进行解析,生成需要填充的数据。 3. 将生成的数据填充到Word模板中,生成最终的Word文档。 以下是实现的简单示例代码: ``` // 读取Word模板文件 FileInputStream fis = new FileInputStream("template.docx"); XWPFDocument doc = new XWPFDocument(fis); // 获取模板中的内容 List<XWPFParagraph> paragraphs = doc.getParagraphs(); List<XWPFTable> tables = doc.getTables(); // 使用FreeMarker生成数据 Configuration cfg = new Configuration(Configuration.VERSION_2_3_0); cfg.setDefaultEncoding("UTF-8"); cfg.setClassForTemplateLoading(this.getClass(), "/templates"); Map<String, Object> data = new HashMap<>(); data.put("name", "张三"); data.put("age", 20); Template template = cfg.getTemplate("template.ftl"); StringWriter writer = new StringWriter(); template.process(data, writer); // 将生成的数据填充到Word模板中 String content = writer.toString(); for (XWPFParagraph paragraph : paragraphs) { String text = paragraph.getText(); if (text.contains("${")) { text = text.replaceAll("\\$\\{.*?\\}", content); paragraph.setText(text); } } for (XWPFTable table : tables) { List<XWPFTableRow> rows = table.getRows(); for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { String text = cell.getText(); if (text.contains("${")) { text = text.replaceAll("\\$\\{.*?\\}", content); cell.setText(text); } } } } // 保存最终的Word文档 FileOutputStream fos = new FileOutputStream("output.docx"); doc.write(fos); fos.close(); ``` 以上代码仅供参考,具体实现还需要根据实际需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值