一:进行模板创建

我们要进行模板导出的话 需要首先将前台的数据传到后台再解析成流文件存储到相应位置,但是要将word以模板格式进行导出的话,我借助了freemark模板殷勤来进行实现,

我们需要在项目开始前,导入maven依赖

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

然后找出我们需要的模板 

首先需要一份想要导出的模板,通过office软件转换成xml格式 (一定要根据office 不是wps toon过“另存为”的方式转换格式不能手动更改拓展名来进行格式转换;

freemarker 导出的 docx 打不开 freemarker word导出_数据

之后将xml文件放入到项目里面,我放到了 word导出对应的包下,并将其扩展名改为.ftl,使得该模板文件可以被模板殷勤识别并应用。

jpg是模板导出需要用到的图片,只有红色箭头标注的是本项目必须的文件 其余几个可以忽略,当然图片和导出样例.ftl  可以自己放到别的  写对他们的路径就可以(我放在了别处这只是演示)。

 

freemarker 导出的 docx 打不开 freemarker word导出_文件名_02

二:进行文件导出的工具类的创建

工具类的作用包含 编码文件名、获取下载/导出路径、进行模板导出的处理

编码文件名:

UUID.randomUUID 这个方法是给文件加上一个唯一字符串 防止文件名称重复 导致的比如数据覆盖等错误。 filename是自定义的文件名称

/**
     * 编码文件名
     */
    public static String encodingFilename(String filename) {
        filename = UUID.randomUUID().toString() + "_" + filename + ".doc";
        return filename;
    }

获取下载路径 定义好要将该文档导出到哪一个文件里面 设置文件导出路径

代码解释:

  NiuaConfig。getDownloadPath()是我采用的框架的自定义方法不通用,作用是获取到导出文件存储的根路径:“D://code/download//” 这都是可以自己定义的甚至不用方法直接写上去也可以。

if判断是根据我的方法来的 防止服务器没有该文件夹 进行自动创建。

/**
     * 获取下载路径
     *
     * @param filename 文件名称
     */
    public static String getAbsoluteFile(String filename) {
        String downloadPath = NiuaConfig.getDownloadPath() + filename;
        File desc = new File(downloadPath);
        if (!desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        return downloadPath;
    }

模板导出核心方法:

代码解释

在准备数据这一块 采用的是map 根据freemark里面加了$符号的变量进行的赋值

采用map的赋值格式:

前面的是实体类的字段名,后面是想要对其进行的赋值。

dataMap.put("classPath", "com.freemark.hello");
dataMap.put("className", "AutoCodeDemo");

如:ftl里面${topScore.goodScoreMin} 在map里面为其赋值 就会在相应的模板里面进行显示 

freemarker 导出的 docx 打不开 freemarker word导出_数据_03

 核心类代码:

public static ResultJson exportWordDoc(Map<String, Object> data, String wordName) throws IOException, TemplateException {
        /** 初始化配置文件 **/
        Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        /** 设置编码 **/
        configuration.setDefaultEncoding("utf-8");
        /** 我的ftl文件是放在D盘的**/
        String fileDirectory = NiuaConfig.getFtlPath();
        //String fileDirectory = "D:\\niua-dev\\niua-admin\\src\\main\\resources\\word";
        /** 加载文件 **/
        configuration.setDirectoryForTemplateLoading(new File(fileDirectory));
        /** 加载模板 **/
        Template template = configuration.getTemplate("导出样例.ftl");
        /** 准备数据 **/
        Map<String, Object> dataMap;
        dataMap = data;

        String fileName = encodingFilename(wordName);
        /** 指定输出word文件的路径 **/
        String outFilePath = getAbsoluteFile(fileName);
        File docFile = new File(outFilePath);
        FileOutputStream fos = new FileOutputStream(docFile);
        Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"), 10240);
        template.process(dataMap, out);

        if (out != null) {
            out.close();
        }
        return ResultJson.ok(fileName);
    }

 对于word模板中图片处理 在对mapdata进行赋值的时候 根据图片的url将其转换为输入流数据,放入mapdata中

public static String getImageStr(String imgUrl) {
        imgUrl = NiuaConfig.getProfile() + "\\" + "upload" + "\\" +imgUrl;
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(imgUrl);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }

三:对于 datamap中的数据 、导出word中的数据 、以及导出样例ftl 相互对应关系

datamap:

这里的data采用了map存储,

data:

data.put("number", number);

key value格式我就不介绍了 记住这个number 再ftl文件里面通过${number} 来对其进行值的读取,保存在word文件上

freemarker 导出的 docx 打不开 freemarker word导出_word导出_04

 

ftl:

freemarker 导出的 docx 打不开 freemarker word导出_word导出_05

 word:

freemarker 导出的 docx 打不开 freemarker word导出_freemark_06

 

对应的考生编号就会根据number进行显示出来。

如果对应的表格需要用到多行一样的格式,这时候需要采用 freemark的遍历list方法。

eg:

freemarker 导出的 docx 打不开 freemarker word导出_文件名_07