一、前端生成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"}"