开发流程说明

1.按照客户要求来编辑“绘制”所需word文档

使用word绘制出客户需要的那种结果,让客户确认结果,然后再制作。

2.绘制完成后,另存为《Word 2003 XML 文档(*.xml)》

确认无误后,另存

3.将保存后的文件的后缀名改为《.ftl》

4.使用小红本打开ftl文件,复制全部内容,然后去百度在线格式化xml文件

打开这个ftl文件,然后复制里面的所有内容,去百度格式化一下

格式化网址: http://www.bejson.com/otherformat/xmlsort/

5.将格式化后的内容覆盖到.ftl 文件里面,然后把这个文件放到开发目录中

将内容覆盖到zkz.ftl文件里面

6.引入freemark的jar包,web项目自己去百度下载个,maven项目直接引入

传统的web项目引入2个jar包:

freemarker-2.3.28.jar
sun.misc.BASE64Decoder.jar

maven项目这样写即可:

<!--freemarker使用start-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--freemarker使用end-->

7.引入freemark工具,来生成对应的word文件

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import sun.misc.BASE64Encoder;import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;/********************************************word文档导出*******************************************/public class FreeMarkerUtil {private static Logger log = Logger.getLogger(FreeMarkerUtil.class.toString());private static final String ENCODING = "UTF-8";private static Configuration cfg = new Configuration();//初始化cfgstatic {//我们要将刚刚创建成的ftl格式的文件放到这个路径下cfg.setClassForTemplateLoading(FreeMarkerUtil.class, "/templates/XXXXX/freemaker");// setEncoding这个方法一定要设置国家及其编码,不然在ftl中的中文在生成html后会变成乱码cfg.setEncoding(Locale.getDefault(), ENCODING);// 设置对象的包装器cfg.setObjectWrapper(new DefaultObjectWrapper());// 设置异常处理器,这样的话就可以${a.b.c.d}即使没有属性也不会出错cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);}//获取模板对象public static Template getTemplate(String templateFileName) throws IOException {return cfg.getTemplate(templateFileName, ENCODING);}/*** 据数据及模板生成文件* @param data             Map的数据结果集* @param templateFileName ftl模版文件名* @param outFilePath      生成文件名称(可带路径)*/public static File createFile(Map<String, Object> data, String templateFileName, String outFilePath) {Writer out = null;File outFile = new File(outFilePath);try {// 获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致Template template = getTemplate(templateFileName);if (!outFile.getParentFile().exists()) {outFile.getParentFile().mkdirs();}out = new OutputStreamWriter(new FileOutputStream(outFile), ENCODING);// 处理模版template.process(data, out);out.flush();log.info("由模板文件" + templateFileName + "生成" + outFilePath + "成功.");} catch (Exception e) {log.error("由模板文件" + templateFileName + "生成" + outFilePath + "出错");e.printStackTrace();} finally {try {if (out != null) {out.close();}} catch (IOException e) {log.error("关闭Write对象出错", e);e.printStackTrace();}}return outFile;}//获得图片的base64码public static String getImageBase(String src) throws Exception {if (src == null || src == "") {return "";}File file = new File(src);if (!file.exists()) {return "";}InputStream in = null;byte[] data = null;try {in = new FileInputStream(file);data = new byte[in.available()];in.read(data);in.close();} catch (IOException e) {e.printStackTrace();}BASE64Encoder encoder = new BASE64Encoder();return encoder.encode(data);}public static void main(String[] args) {try {Map<String, Object> data = new HashMap<String, Object>();SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");Date date=new Date();String current=sdf.format(date);data.put("dqn", current.substring(0,4));createFile(data, "zhuohao.ftl", "C:/Users/Administrator/Desktop/test.doc");} catch (Exception e) {e.printStackTrace();}}}

8.通过工具方法将数据写入.ftl文件,然后导出到word中

js前端携带查询表单的查询参数(与列表的数据要一致)到后台获取数据
js代码:

goToWord_zkz: function(){var self = this;window.location.href = baseUrl + "xxxCont/xxxxxForWord?dclx=zkzdy&pcid=" + self.queryForm.pcid+ "&xmtab="+self.queryForm.xmtab+"&zytab="+self.queryForm.zytab+ "&sftcs=" + self.queryForm.sftcs+ "&bklb=" + self.queryForm.bklb+ "&sfxstp="+self.queryForm.sfxstp;self.$Message.success({background: true,duration: 10,content: "如果数据较多,请耐心等待,不要重复点击"});
},

java代码:

/*** 打印导出* @param dclx 导出类型:zhdy桌号打印、dzddy对照单打印、zkzdy准考证打印*/
@RequestMapping(value = "xxxxxForWord")
public void xxxxxForWord(HttpServletRequest request, HttpServletResponse response, HttpSession session,Model model, ZkzwhEntity zzkzwhEnt, String dclx) throws IOException {Map<String, Object> data = new HashMap<String, Object>();data.put("currNd", DateUtil.CurrentTime("yyyy"));List<ZkzwhEntity> xslist = zkzwhService.queryXsList_word(zzkzwhEnt);//new PageInfo<BkshPage>(zkzwhService.queryXsList(bkshPage));data.put("xslist", xslist);// 先下载到服务器String outPath = File.separator + "upload" + File.separator + "freeMaker" + File.separator + "temp";File fl1 = new File(context.getRealPath(outPath));fl1.mkdirs();File fl2 = new File(context.getRealPath(outPath), user.getUsername()+dclx+".doc");// 下载到服务器的文件名称if(!fl2.exists()) {fl2.createNewFile();}String ftlName = "";//模板文件的全称String docName = "";//导出文件的名字FreeMarkerUtil fmu = new FreeMarkerUtil();if("zhdy".equals(dclx)){//桌号打印ftlName = "zhuohao.ftl";docName = "年单招桌贴";}else if("dzddy".equals(dclx)){//对照单打印ftlName = "duizhaodan.ftl";docName = "年单招对照单";}else if("zkzdy".equals(dclx)){//准考证打印ftlName = "zhunkaozheng.ftl";docName = "年单招准考证";}fmu.createFile(data, ftlName, context.getRealPath(outPath) + File.separator + user.getUsername()+dclx + ".doc");// 读取文件if(fl2.exists()) {InputStream ins = new FileInputStream(fl2);BufferedInputStream bins = new BufferedInputStream(ins);// 放到缓冲流里面OutputStream outs = response.getOutputStream();// 获取文件输出IO流BufferedOutputStream bouts = new BufferedOutputStream(outs);response.setContentType("application/x-download");// 设置response内容的类型response.setHeader("Content-disposition" , "attachment;filename=" + new String((DateUtil.CurrentTime("yyyy")+ docName + ".doc").getBytes("GB2312"), "ISO-8859-1"));// 设置头部信息int bytesRead = 0;byte[] buffer = new byte[8192];// 开始向网络传输文件流while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {bouts.write(buffer, 0, bytesRead);}bouts.flush();// 这里一定要调用flush()方法ins.close();bins.close();outs.close();bouts.close();} else {response.sendRedirect("下载失败");}
}

9.遇到的问题,图片不展示

开发过程中,一直都很顺利很快乐,但是最后的最后,还是遇到了问题,就是模板循环出来后,图片没有打印出来。

图片上的保存信息,意思就是图片资源没有找到。
百度了下,百度到如下信息,即id重复的问题,于是根据百度到的内容,我做出了修改:

<w:binData w:name="wordml://src_${xsObj.sfzh}.png" xml:space="preserve">${xsObj.zp_str!}</w:binData>
<v:shape id="图片_${xsObj_index-1}" o:spid="_x0000_s1026${xsObj_sfzh}" type="#_x0000_t75${xsObj.sfzh}"><v:imagedata src="wordml://src_${xsObj.sfzh}.png" o:title=""/>
</v:shape>

注意:
1,${xsObj.zp_str!} 传递的是我从后台取出来的base格式的图片内容。
2,<w:binData><\binData> 标签之间不能有其他任何字符,类似于textarea标签的性质一样。
3,word中存在多张 不同 的图片,那么在遍历图片时,id和name必须不同才可以,使用循环的下标来标记或者数据库中的id来标记,像我的文章中,我使用了身份证号作为id,就可以不重复。

我以为这就大功告成了,但是实际上,还是不行,我以为是我哪里写错了,我仔细检查了好几遍,确定代码没有写错,于是开始找数据的问题。
结果却是发现是数据来源的问题。
word转成的xml再转成ftl格式的数据后,它不支持前缀为 “data:image/jpg;base64,”,就是因为我的bas格式的图片中,我在存储时,故意拼接了这个字符,为了方便页面中 <img src="">直接显示图片。但是在这里就必须没有这个 “data:image/jpg;base64,” 开头才可以。
因为别的地方还用到这个base格式的图像,所以不方便修改保存方法,于是在数据库中查询的时候截取了一下字符串即可:


完美!真香。

freemark导出word全过程 + 图片不显示问题相关推荐

  1. 记录前端导出word 本地图片不显示问题

    导出 方法一: jquery.wordexport 可以做导出word(也可以导出html,把源码里面的doc换成html) 导出 方法二: 借助HTML5 Blob 可以做导出word 出现问题 外 ...

  2. java freemarker导出word 带图片,文件导出后图片无法使用office正常打开

    问题记录:java freemark导出word 带图片,文件导出后图片无法使用office正常打开,解决之! 现象:wps打开正常,office如下 修改点: 图片${image1}标签前后保证无空 ...

  3. java freemark导出word (模板、单张图片、多张图片源码)

    java freemark导出word (模板.单张图片.多张图片源码) 首先模板设置 代码编辑 设置word只读.全部 环境设置.jar包 模板设置 ** 设置模板然后另存为 这里一定要选择对xml ...

  4. 纯前端JS导出Word包含图片

    纯前端JS导出Word包含图片 纯前端JS导出Word文档包含图片 Word导出方式 依赖 实现代码 纯前端JS导出Word文档包含图片 在做项目中,遇到一个需求,是将后台返回的属性以及URL图片导出 ...

  5. vue 导出word带图片

    下载依赖 包 npm install docxtemplater npm install pizzip npm install jszip npm install jszip-utils npm in ...

  6. NPOI导出Word插入图片问题解决方案

    NPOI用版本2.2.0或者2.2.1时导出Word插入图片时,word文档打开报错 解决方案之一:用NPOI 2.1.3版本可以解决 XWPFDocument doc = new XWPFDocum ...

  7. word中图片不显示的解决办法

    今天群里(Word学习交流群 180627193)一位朋友问到,最近在使用Word编辑文档,发现Word里插入的图片不能显示在页面上.而且插入的图形只显示一个有8个黑点的图片框轮廓,但在打印预览时能显 ...

  8. freemarker模板导出word循环图片表格详细教程

    前言:表哥之前已经过一篇freemarker模板导出带表格word详细教程  freemarker模板导出带表格word详细教程_Java大表哥的博客-CSDN博客,为什么现在又要写一篇呢. 因为我这 ...

  9. poi-tl导出word实现图片环绕方式为浮于在文字上方办法

    poi-tl导出word实现图片环绕方式为浮于在文字上方办法 poi-tl简介 因为poi-tl暂时不支持设置图片环绕方式,但是可以自定义图片渲染插件 poi-tl简介 poi-tl(poi temp ...

  10. word插入图片,显示不全

    问题描述:word插入图片,显示不全.(具体如下图所示) 原因:未知 解决办法:选中图片,然后按Ctrl+1键.解决之后如下图所示.

最新文章

  1. html事件隐藏,Html事件列表
  2. java web mvc 拆分_JAVA WEB初接触——简单的MVC架构
  3. html5弹窗全屏,jQuery炫酷全屏模态窗口插件
  4. Swagger如何访问Ocelot中带权限验证的API
  5. java在什么环境变量_Java-环境变量
  6. 未来教育计算机二级书怎么样,未来教育计算机二级
  7. Activiti 工作流会签开发设计思路
  8. vim删除多行_vim文本编辑器
  9. mysql 中ak_数据库ak
  10. python---图表的使用
  11. 企业与市场_自动驾驶相关公司-技术发展
  12. 安装VMware出现无法访问你试图使用的功能所在的网络位置
  13. 离合器膜片弹簧的优化设计matlab,基于matlab目标函数的建立优化离合器膜片弹簧的设计研究.doc...
  14. 阿里云OSS图床搭建教程
  15. 计算机英语中级职称题库,职称计算机考试题库(中级职称需要考计算机吗)
  16. html5图片任何改不透明度,如何巧改插入图片的透明度
  17. 计算机网络网线制作与测试结果,《计算机网络》网线制作实验报告(1).doc
  18. 一文搞定基因型数据清洗
  19. 阅读“变形计”:一场偶然与非偶然的相遇
  20. ES选举:Elasticsearch中Master选举完全解读

热门文章

  1. 【致远OA】快速修复安装A6的方法
  2. 服务器vmware新建虚拟机教程,如何创建虚拟机教程全解
  3. 计算机英语单词练习五
  4. java 根据手机号获取归属地
  5. HP台式机安装WIN10
  6. 008-2018-09-12 文件操作
  7. WordPress有没有好的主题推荐?27个Ultra WordPress企业主题分享:不再有选择 困难症了
  8. 让游戏沉浸感炸裂的实时3D音效技术原理与实践(上)
  9. 笔记本安装双系统教程
  10. android mcc 模拟,Android 读取MCC, MNC