网上找过很多方法,但一直没有特别合适的直接导入方式,所以借鉴一篇博客的方法:先将echarts图表保存到本地临时文件,然后将文件添加到word摸板的对应位置,虽然比较繁琐,但摸板可调,操作更灵活。
参考博客连接:https://blinkfox.github.io/2018/10/01/hou-duan/java/shi-yong-java-diao-yong-phantomjs-dong-tai-dao-chu-echarts-tu-pian-dao-word-wen-jian-zhong/
新建word文档 test.docx,写好模板样式,可根据自己的需要自行添加,{{}}为你要填充的内容,固定不变文字可以提前写道模板里面
开始写后台java代码部分,首先导入需要的依赖,因为后边会用到网页,和其他依赖这里一并导入
org.springframework.boot
spring-boot-starter-thymeleaf
org.projectlombok
lombok
true
com.deepoove
poi-tl
1.0.0
需要的java导出工具类 PoitlTest 这里是将本地存在的图片和自己构造的数据填充到模板中
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.PictureRenderData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* poi-tl库的使用示例.
*/
public class PoitlTest {
private static final Logger log = LoggerFactory.getLogger(PoitlTest.class);
/** word模板路径,这里为了方便直接采用真实路径 */
private static final String DOC_PATH = "D:\\test\\test.docx";
/** 要插入word的图片路径. 同上*/
private static final String PIC_PATH = "D:\\test\\demo1.jpg";
private static final String PIC_PATH1 = "D:\\test\\demo2.jpg";
/** 输出文件及路径. */
private static final String OUTPUT_PATH = "D:\\test\\poitl_out_word.docx";
/**
* 构造要填充的数据
* Map或者是对象都可以(map的key为模板里面的填充标签,对象的属性名为模板里面的填充标签
* @return map
*/
private static Map buildBeanData() {
Map map= new HashMap<>();
map.put("title","导出word文档");
map.put("smallTitle","数据图表信息");
map.put("content1","图1");
map.put("pic1",new PictureRenderData(600, 400, PIC_PATH));
map.put("content2","图2");
map.put("pic2",new PictureRenderData(600, 400, PIC_PATH1));
return map;
}
/**
*
* 导出方法
*/
public static void export() throws IOException {
XWPFTemplate template = XWPFTemplate.compile(DOC_PATH).render(buildBeanData());
FileOutputStream out = new FileOutputStream(OUTPUT_PATH);
template.write(out);
out.flush();
out.close();
template.close();
log.info("通过'poi-tl'导出word成功!");
}
}
直接运行 export 方法测试输出word文档成功,效果展示如下
我们思路是echarts图片再页面显示,点击导出后先将图片存到本地,然后放入模板,因为我用到是thymeleaf引擎,需要在配置文件添加thymeleaf配置内容
spring.thymeleaf.prefix= classpath:/templates/ #页面所在位置
spring.thymeleaf.suffix= .html #后缀
index.html页面内容为
测试的ECharts数据统计图
后台请求的controller方法内容为,在方法中导出word文档时应该动态传入你设置保存图片的路径,此处只为演示所以没改,各位看客可以根据自己的需要更改一下,未修改记得将导出类的图片路径修改为你导出图片的路径
import com.example.practice.word.PoitlTest;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@CrossOrigin
@RestController
public class AdminController {
private static final Logger log = LoggerFactory.getLogger(AdminController.class);
@PostMapping("saveImage")
public void getAdmin(HttpServletRequest request) {
// 获取图片信息.其实是图片解析为base64的编码
String picInfo1 = request.getParameter("picInfo1");
String picInfo2 = request.getParameter("picInfo2");
if (StringUtils.isBlank(picInfo1) || StringUtils.isBlank(picInfo2)) {
log.error("picInfo为空,未从前台获取到base64图片信息!");
return;
}
//存放图片的位置
getAndsaveImage(picInfo1, "D:\\test\\image1.png");
getAndsaveImage(picInfo2, "D:\\test\\image2.png");
//生成word文档
try {
//此处应该改为将图片地址动态的传入,博主未改,各位看客见谅
PoitlTest.export();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("导出成功");
}
/**
* 获取并保存图片到本地.
*
* @param picInfo 图片信息
* @param imagePath 图片保存的路径
*/
private void getAndsaveImage(String picInfo, String imagePath) {
// 传递过程中 "+" 变为了 " ".
String newPicInfo = picInfo.replaceAll(" ", "+");
String picPath = decodeBase64(newPicInfo, imagePath);
log.warn("从echarts中生成图片的的路径为:{}", picPath);
}
/**
* 解析Base64位信息并输出到某个目录下面.
*
* @param base64Info base64串
* @param picPath 生成的文件路径
* @return 文件地址
*/
private String decodeBase64(String base64Info, String picPath) {
if (StringUtils.isEmpty(base64Info)) {
return null;
}
// 数据中:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABI4AAAEsCAYAAAClh/jbAAA ... 在"base64,"之后的才是图片信息
String[] arr = base64Info.split("base64,");
// 将图片输出到系统某目录.
OutputStream out = null;
try {
// 使用了Apache commons codec的包来解析Base64
byte[] buffer = Base64.decodeBase64(arr[1]);
out = new FileOutputStream(picPath);
out.write(buffer);
} catch (IOException e) {
log.error("解析Base64图片信息并保存到某目录下出错!", e);
} finally {
IOUtils.closeQuietly(out);
}
return picPath;
}
}
验证效果:在浏览器输入localhost:8080
点击button,导出到word,查看word内容