java 下载word freemaker
网上有很多优质的博文了,这里这篇博客就是记录一下字自己,写demo的历程,坑和收获
在java程序中下载word 有6中方式,此处省略(嘻嘻),不过大家公认的是 freemaker 和 PageOffice
本篇文章是用的freemaker。
下载word 的大体思路是,制作模板,封装数据,导出
一 制作模板
很简单的模板
1 首先新建word
2 文件另存为 word .xml格式。
3 用 notepad++ 或者ideal打开xml文件(我这里推荐用ideal,看着舒服些)关于格式化xml,可以在点击开的链接上格式化xml
格式化xml之后,把文件保存为ftl格式,重新再在编辑器打开。
找到其中${user.username}和${user.password},仔细分析该ftl文件可以发现,在word文档中表格的每一行在xml文件中即为一个<w:tr></w:tr>标签,而在该标签中,每一个<w:tc></w:tc>则对应一个单元格。了解这个之后,我们就要使用ftl语法对该模板文件进行改造。这里我们需要导出的是一个用户列表的文件,每个用户包含一个用户名和密码,那么这里用户所在的这一行(<w:tr></w:tr>)就需要使用ftl中的<#list></#list>标签包含起来:
<w:tr>
<w:tc>
...
用户名:
...
</w:tc>
<w:tc>
...
${user.username}
...
</w:tc>
<w:tc>
...
密码:
...
</w:tc>
<w:tc>
...
${user.password}
...
</w:tc>
</w:tr>
</#list>
到此为止,我们的ftl模板就制作完毕了。
二 接下来我们创建后台服务端的代码
代码分为3部分
1 WordUtil 为freemaker模板设置相关的内容。
2 DownloadUtil 为下载的 工具类。
3自己封装自己的数据,一般是就是从数据库中查询出的数据。。
下面贴出的代码时service层和util工具类 ,controller 没内容就不贴了。
@Service public class DownLoadServiceImpl implements DownLoadService { @Override public void downLoad(HttpServletResponse response, String wordName) { Map<?, ?> root = initData(); //数据源对象 String template = "/template/UserList.ftl"; //模板文件的地址 String path = "E:\\UserList.doc"; //生成的word文档的输出地址 ByteArrayOutputStream byteArrayOutputStream = WordUtil.process(root, template); try { DownLoadUtil.download(byteArrayOutputStream,response,wordName); } catch (IOException e) { e.printStackTrace(); } } private Map<?, ?> initData() { Map<String, Object> root = new HashMap<String, Object>(); List<User> users = new ArrayList<User>(); User zhangsan = new User("小姐姐", "倾国倾城"); User lisi = new User("沉鱼落雁", "闭月羞花"); //User wangwu = new User("王五", "789"); users.add(zhangsan); users.add(lisi); //users.add(wangwu); root.put("users", users); root.put("title", "用户列表"); return root; } }
public class DownLoadUtil { /** * @param byteArrayOutputStream 将文件内容写入ByteArrayOutputStream * @param response HttpServletResponse 写入response * @param returnName 返回的文件名 */ public static void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException { response.setContentType("application/msword"); response.setHeader("Content-Disposition", "attachment; filename=" + returnName); response.setContentLength(byteArrayOutputStream.size()); OutputStream outputstream = response.getOutputStream(); //取得输出流 byteArrayOutputStream.writeTo(outputstream); //写到输出流 byteArrayOutputStream.close(); //关闭 outputstream.flush(); //刷数据 } }
public class WordUtil { private static Configuration configuration = null; private WordUtil() { throw new AssertionError(); } /** * 根据模板生成相应的文件 * @param root 保存数据的map * @param template 模板文件的地址 * @param * @return */ public static synchronized ByteArrayOutputStream process(Map<?, ?> root, String template) { if (null == root ) { throw new RuntimeException("数据不能为空"); } if (null == template) { throw new RuntimeException("模板文件不能为空"); } ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); String templatePath = template.substring(0, template.lastIndexOf("/")); String templateName = template.substring(template.lastIndexOf("/") + 1, template.length()); if (null == configuration) { configuration = new Configuration(Configuration.VERSION_2_3_23); // 这里Configurantion对象不能有两个,否则多线程访问会报错 configuration.setDefaultEncoding("utf-8"); configuration.setClassicCompatible(true); } configuration.setClassForTemplateLoading(WordUtil.class, templatePath); Template t = null; try { t = configuration.getTemplate(templateName); Writer w = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8")); t.process(root, w); // 这里w是一个输出地址,可以输出到任何位置,如控制台,网页等 w.close(); } catch (Exception e) { throw new RuntimeException(e); } return outputStream; } }
下面是实体类
public class User { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public User(String name, String password) { this.name = name; this.password = password; } public User() { } }
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency>
做个各个demo 参考了好几位博友的文章,在此表示感谢。
参考链接:https://www.cnblogs.com/vcmq/p/9484362.html
http://itindex.net/detail/55080-springboot-freemarker-%E6%A0%BC%E5%BC%8F
下面demo源码:链接: https://pan.baidu.com/s/1-eVO-YgBTw-xTxA4Q4EIdg 提取码: 5g8h