java使用freemarker生成word

一、前端生成base64编码

npm install echarts --save

到vue的main.js中加入:

import echarts from 'echarts'

Vue.prototype.$echarts=echarts; //使用$在前是为了防止于组件中的data命名冲突

配置echarts组件(我这里绘制的是饼图):

<template>

  <div id="chart" style="width: 600px; height: 400px;"></div>

</template>

<script>
  export default {

    data() {

      return {
        base64: "",
        data: [

          {
            "name": "apple",
            "value": 26
          },
          {
            "name": "orange",
            "value": 10
          },
          {
            "name": "grape",
            "value": 15
          },

          {
            "name": "banana",
            "value": 16
          }

        ],
      }
    },
    mounted() {
      this.base64 = this.drawcharts(this.data);
      console.log(this.base64);

    },
    methods: {
      drawcharts(chartdata) {
        // 可以设置主题: "dark"、 "light"
        console.log(chartdata);
        let mychart = this.$echarts.init(document.getElementById("chart"), "light");
        var option = {
          animation: false, // 该属性必须加,不然转换后的base64达不到图表的效果
          series: [{
            type: 'pie',
            center: ("50%", "50%"),
            radius: "90%",
            data: chartdata,
          }]
        };

        mychart.setOption(option);
        let chartBase64 = mychart.getDataURL();
        return chartBase64;
      }

    }
  }
</script>

<style>

</style>

二、请求后台并得到生成word

前端请求

安装 js-file-download

npm install js-file-download --save

import axios from 'axios';
import fileDownload from 'js-file-download'
exports () {
			let manyCharts = []
			let params = {
				image: this.base64
			}
			axios.post('bus/decision/exportData', params, {responseType: 'arraybuffer'}).then(res => {
				fileDownload(res.data, + "test.doc")
				this.$message.success("导出成功", 3);

			}).catch(error => {
				console.log(error)
				this.$message.warning('导出出错!');
			})

		},

后台代码

添加依赖
pom.xml文件中添加

 <dependency>
                <groupId>org.freemarker</groupId>
                <artifactId>freemarker</artifactId>
                <version>2.3.30</version>
  </dependency>

注:版本选择30,选择比30低的启动时会报错

@PostMapping(value = "/exportData")
    @ApiOperation(value = "导出xxx")
    @ResponseBody
    public void exportData(@RequestBody Map<String, Object> map, HttpServletResponse response) {

        judgedTaskService.exportData(map, response);
    }
 @Override
    public void exportData(Map<String, Object> map, HttpServletResponse response) {

        Map<String, Object> data = new HashMap<>();
      
        data.put("image", getChart(map.get("image")));
        data.put("test", "测试");

        try {
            // 导出 "test.ftl"  模板名称
            WordUtils.exportMillCertificateWord(response, data, "test.ftl");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
  private String getChart(Object chart) {
        // 截取","之后的数据
        String charts = "";
        if (chart != null) {
            charts = chart.toString();
            charts = charts.substring(charts.substring(0, charts.indexOf(",")).length() + 1, charts.length());
        }
        return charts;
    }
import freemarker.template.Configuration;
import freemarker.template.Template;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;

public class WordUtils {
    //配置信息
    private static Configuration configuration = null;
    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        // 在resource下新建一个template文件夹
        configuration.setClassForTemplateLoading(WordUtils.class, "/template/");
    }

    private WordUtils() {
        throw new AssertionError();
    }


    public static void exportMillCertificateWord(HttpServletResponse response, Map map, String ftlFile) throws IOException {

        Template freemarkerTemplate = configuration.getTemplate(ftlFile);
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        OutputStream toClient = null;
        try {
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map,freemarkerTemplate);
            fin = new FileInputStream(file);
            String filename = file.getName();
            InputStream fis = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Length", "" + file.length());
            response.setContentType("application/msword");

            toClient = new BufferedOutputStream(response.getOutputStream());
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } finally {
            if(fin != null) fin.close();
            if(toClient != null) toClient.close();
            if(file != null) file.delete(); // 删除临时文件
        }
    }

    private static File createDoc(Map<?, ?> dataMap, Template template) {
        // 临时生成文件路径
        String filePath = System.getProperty("user.dir") + "/air-diagnosis-bus/src/main/resources/file/judgedTask.doc";
        File f = new File(filePath);
        // 文件不存在则新建
        if (!f.exists()) {
            try {
                f.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();

            }
        }
        Template t = template;
        try {
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
            Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }
}

模板制作

1、新建一个test.doc文档
${test}对应上面代码Map集合中key为test,最终生成word时显示对应的value值
在这里插入图片描述
2、模板另存为xml文件
在这里插入图片描述

3、编辑xml文件并生成ftl文件

建议使用Firstobject free XML editor 打开xml文件,这样能格式化文件,比较好编辑

下载路径:http://www.firstobject.com/dn_editor.htm

打开文件点击Tools-Indent 或者按F8格式化文件,如下图:

在这里插入图片描述
找到已经变成了base64编码的图片
注:这里的base64编码跟页面上生成的base64编码略有不同,少了“data:image/png;base64,”,所以在代码中我们要去掉“data:image/png;base64,”这一段,这里我上面的代码中使用公共方法getChart()已经去掉
在这里插入图片描述
将这里的base64编码删除,换成上面代码中的image, ${image}
在这里插入图片描述
到此模板制作完成,将文件重命名为.ftl格式的文件,本人是将.ftl文件放置resource文件夹下template(新建)文件夹下

附加
循环遍历图片:
添加

  <#list list as item>
        </#list>

注:list 为图片base64编码集合
找到<w:pict>标签,往上再找 <w:p>标签,在 <w:p>标签前添加循环<#list list as item>,结束 </w:p>标签后添加</#list>,如下图,
在这里插入图片描述
注:不是遍历图片则不需要改上面两处,修改代码如下:"${“wordml://0”+item_index+3+“00000”+".jpg"}"

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值