先用wps写个word 模板 ,${} 不解释,再保存成xml文件(点击另存为保存,格式为xml)。再放到idea ctrl alt L 调整格式,然后ctrl f (${)检查有的是不是乱了。图片的16进制的字符串也替换成${},最后改成ftl格式。

import freemarker.template.Configuration; import freemarker.template.Template; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import sun.misc.BASE64Encoder; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.*; @RestController @RequestMapping("zzz") @Slf4j public class WordController { @Resource(name = "wordConfiguration") private Configuration wordConfiguration; /** * 导出word * @param response */ //@GetMapping("/getBookWord") @RequestMapping("ttt") public void getBookWord(HttpServletResponse response) { try { //图片的base64集合 String image1 = encodeBase64File("wordtemp/test.jpg"); Map dataModel = new HashMap<>(); dataModel.put("username", "666"); dataModel.put("images", image1); response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=test.doc"); //加载模板 Template template = wordConfiguration.getTemplate("test.ftl", "utf-8"); template.process(dataModel, response.getWriter());//response的Writer不需要我们手动关,tomcat会帮我们关的 } catch (Exception e) { log.error("导出word异常:", e); } } /** * 将文件转为base64字符串 * @param path 文件地址 * @return * @throws IOException */ public String encodeBase64File(String path) throws IOException { //读取resource目录下的文件 try (InputStream inputStream = WordController.class.getClassLoader().getResourceAsStream(path)){ byte[] buffer = new byte[inputStream.available()]; inputStream.read(buffer); return new BASE64Encoder().encode(buffer); } } }

import freemarker.template.Configuration; import org.springframework.context.annotation.Bean; import java.io.File; import static freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS; @org.springframework.context.annotation.Configuration public class WordConf { /** * 将freemarker的Configuration对象作为一个单例对象,可以避免重复创建的性能开销 * 这里我是将Configuration对象作为bean交给spring容器来管理,如果不是spring项目的话可以自己写一个单例模式 * 从Configuration类上的注释可以找到说明:Configuration是有状态的,线程不安全的,但是它的各种get方法是线程安全的 * 所以一旦这个单例对象被配置好以后就不该再调用它的set方法 * @return */ @Bean public Configuration wordConfiguration(){ Configuration result = new Configuration(DEFAULT_INCOMPATIBLE_IMPROVEMENTS); result.setDefaultEncoding("utf-8"); //设置模板加载器 result.setClassForTemplateLoading(this.getClass(), "/wordtemp"); return result; } }

base64也可以这样

public String encodeBase64File(String path) throws IOException { byte[] data = null; // 读取图片字节数组 try { InputStream in = new FileInputStream(path); data = new byte[in.available()]; in.read(data); in.close(); } catch (IOException e) { e.printStackTrace(); } return new BASE64Encoder().encode(data); }