(持续更新中)使用FreeMarker生成word文档(表格、图片、复选框讲解),word转pdf,预览pdf,pdf下载工具类


一、下载或配置:

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-words</artifactId>
    <version>15.12.0</version>
</dependency>

二、创建模板文件:(Demo讲解)

1.先新建一个word文档,将 word 中需要填充的数据用占位符${变量名}替换。

  • 效果如下:
  • 注:图片随便放一张上去,主要是得到图片标签,后面会改。表格里的序号默认这种写法,后面会改成变量自增。
  • 复选框符号设置:
    在这里插入图片描述

在这里插入图片描述

2.将word文档另存为xml格式的文件。

  • 效果如下:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/73f0c0d0f9404345a991c9ea77522883.png

3.用Notepad++打开xml模板文件,把 pkg:binaryData 标签里的图片base64编码删除,用占位符${变量名}替换。

  • 注:建议先用Notepad++的xml格式化插件格式化下标签
    在这里插入图片描述
  • 替换效果
    在这里插入图片描述

4.处理复选框(00A3:是未选中状态 ,0052:是选中状态 ,00A8:是未选中状态,00FE:是选中状态),用if,else标签写一个逻辑判断gender =="1"就勾(男)复选框,gender =="2"就勾(女)复选框。

  • 先设置复选框标签,复选框标签显示的是 <w:t>☐</w:t>,将下面标签替换到你复选框显示的位置
  • <w:sym w:font=“Wingdings 2” w:char=“00A3”/>
  • 以下标签是复选框默认未选中
<w:sym w:font="Wingdings" w:char="00A8"/>

在这里插入图片描述

  • 处理复选框标签,加上if,else标签处理逻辑,gender是性别变量
<#if gender=="1">
	<w:sym w:font="Wingdings" w:char="00FE"/>
<#else>
	<w:sym w:font="Wingdings" w:char="00A8"/>
</#if>

在这里插入图片描述

<#if gender=="2">
	<w:sym w:font="Wingdings" w:char="00FE"/>
<#else>
	<w:sym w:font="Wingdings" w:char="00A8"/>
</#if>

在这里插入图片描述

5.集合数据填充进表格

  • 表格标签讲解

在这里插入图片描述

  • 用list标签包裹第二个tr标签
  • 注:第一个tr标签是是固定的标题,数据从第二个tr标签开始循环填充

在这里插入图片描述
tr标签里的变量改完${list对象.变量}

${bg.变量}

注:序号变量的写法不同,要改为{list对象_index+1}自增

${bg_index+1}

在这里插入图片描述

  • 日期格式变量需要转换
${(bg.date)?string('yyyy年MM月dd日')}

在这里插入图片描述

6.最后将xml文件后缀改为ftl文件格式保存即可。

在这里插入图片描述

三、开始测试:

  • 生成word文档,word转pdf,pdf预览、下载工具类
package com.text.util;

import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.hebtx.exception.PDFServerSignException;
import com.hebtx.seal.sign.RemoteSign;
import org.apache.commons.lang3.StringUtils;
import com.supervise.common.config.HxzkConfig;
import freemarker.core.ParseException;
import freemarker.log.Logger;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * Word转PDF工具类
 * @author luvJie-7c

 *  */
public class WordToPdfUtils {
	
	
	private static Logger log = Logger.getLogger(WordToPdfUtil.class.toString());
	
   /**
     * 用freemaker模板生成word文档
     * @author luvJie-7c
     * @date 
     * @param dataMap 要填充的数据
     * @param templateName 模板名称
     * @param fileName 要输出的文件名称
     * @param CoType 文件类型
     * @return java.lang.String
     */
    public static String createWord(Map<String, String> dataMap, String templateName, String fileName, String CoType){

        long start = System.currentTimeMillis();
        //定义word路径
        String wordPath = "";
        //定义pdf路径
        String pdfPath = "";
        try {
        //设置FreeMarker的版本和编码格式 版本和jar包版本要一致
        Configuration config = new Configuration(Configuration.VERSION_2_3_22);
        //设置FreeMarker生成Word文档所需要的模板路径 此次进行类加载 找到资源目录resources目录下template包   
        config.setClassForTemplateLoading(WordToPdfUtils.class, "/template");
        //加载web项目webapp/ftl文件夹下 
		//config.setDirectoryForTemplateLoading(new File(request.getSession().getServletContext().getRealPath("/ftl")));
        //设置模板编码格式
        config.setDefaultEncoding("UTF-8");
            Template template = null;
            try {
                //设置FreeMarker生成Word文档所需要的模板
                template = config.getTemplate(templateName,"UTF-8");
            } catch (TemplateNotFoundException e) {
                log.error("模板文件未找到", e);
                e.printStackTrace();
            } catch (MalformedTemplateNameException e) {
                log.error("模板类型不正确", e);
                e.printStackTrace();
            } catch (ParseException e) {
                log.error("解析模板出错,请检查模板格式", e);
                e.printStackTrace();
            } catch (IOException e) {
                log.error("IO读取失败", e);
                e.printStackTrace();
            }
            //创建日期年月日 组文件路径
            SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
            String dfDate = df.format(new Date());
            String dateYear = dfDate.substring(0,4);
            String dateMonth = dfDate.substring(5,7);
            String dateDay = dfDate.substring(8,10);
            //存放路径
            wordPath = "存储盘路径" + CoType + "/" + dateYear + "/"+ dateMonth + "/" + dateDay +"/" + fileName + "/";
            //将word路径赋值给pdf路径
            pdfPath = wordPath;
            //创建文件夹
            File f = new File(wordPath+fileName+".doc");
            //判断文件夹是否存在,不存在,则新建一个文件夹
            if (!f.getParentFile().exists()) {
                f.getParentFile().mkdirs();
            }
            //创建一个Word文档输出流
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
            try {
                template.process(dataMap, out);
            } catch (TemplateException e) {
                log.error("填充模板时异常", e);
                e.printStackTrace();
            } catch (IOException e) {
                log.error("IO读取时异常", e);
                e.printStackTrace();
            }
            log.info("由模板文件:" + templateName + " 生成文件 :" + fileName + ".doc" + " 成功!!");
            out.flush();
            out.close();
            //word文档转PDF
            wordOrPdf(wordPath+fileName+".doc", null);
            //pdf路径
            pdfPath = pdfPath+fileName+".pdf";
            log.info("Pdf文档转换成功!! 生成地址:"+ pdfPath);
            long end = System.currentTimeMillis();
            log.info("Pdf文档生成耗时:" + ((end - start) / 1000.0) + "秒");
        } catch (Exception e) {
            e.printStackTrace();
            log.info("Word模板生成失败!!");
        }
        return pdfPath;
    }
	
	 
	/**
     * 使用aspose.word把word文档转为pdf文档
     *
     * @param sourceFile word文档绝对路径
     * @param destFile   pdf文档绝对路径
     */
    public static String wordOrPdf(String sourceFile, String destFile) throws Exception {
        destFile = StringUtils.isEmpty(destFile) ? sourceFile.replace(".doc", ".pdf") : destFile;
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!getLicense()) {
            throw new Exception("生成PDF文档,验证License失败!");
        }
        try {
            File file = new File(destFile);  //新建一个空白pdf文档
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(sourceFile);//通过sourceFile创建word文档对象
            //本地项目不设置此路径   只针对服务器上的字体文件路径
            //FontSettings.setFontsFolder("/usr/share/fonts/windowsFont/", true);        
            doc.save(os, SaveFormat.PDF);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("生成PDF文档失败!");
        }
        return destFile;
    }
	
	
    /**
     * @Description: 验证aspose.word组件是否授权:无授权的文件有水印标记
     */
    public static boolean getLicense() {
        boolean result = false;
        try {
            String s = "<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature></License>";
            ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());
            com.aspose.words.License license = new com.aspose.words.License();
            license.setLicense(inputStream);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    
    
    /**
     * pdf预览、下载
     * @author luvJie-7c
     * @date 
     * @param fileName 文件名
     * @param path 文件路径
     * @return void
     */
    public static String previewPdf(String fileName, String path){
        //默认状态'0' 文件不存在 '1'文件存在  '2'文件异常
        String exist = "0";
        //获取HttpServletResponse (静态自创建)
        HttpServletResponse response =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            // 验证该文件是否是存在
            if(new File(path).exists()){
                //添加跨域访问
                response.setHeader("Access-Control-Allow-Origin", "*");
                //以流的形式传输
                response.setContentType("application/octet-stream");
                // 设置文件流编码格式
                response.setCharacterEncoding("UTF-8");
                //Content-Disposition属性名 (attachment表示以附件的方式下载;inline表示在页面内打开)
                response.setHeader("Content-Disposition", "attachment; fileName="+fileName+".pdf");
                try { //输入输出
                    FileInputStream is = new FileInputStream(path);
                    ServletOutputStream out = response.getOutputStream();
                    byte[] buffer = new byte[1024];
                    int i = 0;
                    while ((i = is.read(buffer)) != -1) {
                        out.write(buffer,0,i);
                    }
                    //缓存区的数据进行输出
                    out.flush();
                    //关闭流
                    out.close();
                    is.close();
                    exist = "1";
                    log.info("已输出Pdf文档:"+fileName+".pdf");
                } catch (IOException e) {
                    exist = "2";
                    log.error("IO读取时异常", e);
                    e.printStackTrace();
                }
            }
        return exist;
    }
  • 新建测试数据
public class test {
    private String calendar;
    private Date date;

    public String getCalendar() {
        return calendar;
    }

    public void setCalendar(String calendar) {
        this.calendar = calendar;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}
  • 调用工具类:
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        //模拟5条测试数据
        List list = new ArrayList();
        for (int i = 0; i < 5;i++) {
            test test = new test();
            test.setCalendar("周日");
            test.setDate(new Date());
            list.add(test);
        }
        //姓名
        hashMap.put("name", "测试");
        //存入一个图片的base64编码
        hashMap.put("img", "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");
        //性别
        hashMap.put("gender", "1");
        //集合数据
        hashMap.put("bgList",list);
        try {
            //返回pdf路径
            String pdfPath = WordToPdfUtils.createWord(hashMap, "测试文档.ftl", "测试文档", "hz");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • 文档生成地址:

在这里插入图片描述

  • 最终生成效果:
    在这里插入图片描述

四、将实体对象数据插入进word模板方式:

将实体对象数据转换为map对象数据,插入进word模板数据(FreeMarker实现方式)


  • 9
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
要在Spring Boot使用FreeMarker插入Word文档图片,可以按照以下步骤进行操作: 1. 将图片上传到服务器,并获取其在服务器上的路径。 2. 在FreeMarker模板使用img标签将图片插入到模板。例如: ``` <img src="${imagePath}" /> ``` 其`${imagePath}`是图片在服务器上的路径。 3. 在Java代码使用Apache POI库读取模板文件,并将模板的占位符替换为实际值。同时,将图片插入到Word文档。例如: ```java // 读取模板文件 InputStream inputStream = new FileInputStream("template.docx"); XWPFDocument document = new XWPFDocument(inputStream); // 替换模板的占位符 Map<String, Object> data = new HashMap<>(); data.put("imagePath", "/path/to/image.png"); FreemarkerUtils.processTemplate("template.ftl", data, document); // 插入图片 String imageFilePath = "/path/to/image.png"; byte[] imageData = FileUtils.readFileToByteArray(new File(imageFilePath)); int imageType = Document.PICTURE_TYPE_PNG; int imageWidth = Units.toEMU(200); int imageHeight = Units.toEMU(200); XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); int imageIndex = document.addPicture(imageData, imageType); run.addPicture(imageIndex, imageType, "image.png", imageWidth, imageHeight); // 保存Word文档 OutputStream outputStream = new FileOutputStream("output.docx"); document.write(outputStream); outputStream.close(); ``` 其`FreemarkerUtils.processTemplate`方法用于将FreeMarker模板的占位符替换为实际值。 注意:在使用Apache POI插入图片时,需要注意图片的类型和大小,以及插入位置和样式等因素。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luvJie-7c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值