java根据word模板导出word文件

发布于:2023-04-27 ⋅ 阅读:(546) ⋅ 点赞:(0)

前言:java导出word有很多方式,这里介绍最简单的一种,利用freemark模板导出word文档。


说明:这里用导出一个list列表数据到word文档来举例

首先导入freeamark依赖,版本号最好不要太低,在maven依赖官网找使用次数最多的附maven依赖地址:https://mvnrepository.com/

1、将list数据导出到word数据模板如图所示,字段的值暂时用数字1-7代替,这里说明一下为什么要用1-7的数字代替字段值,因为一会要把doc格式的文件转换成xml,这里如果直接填写变量的值的话变量值如果过长会导致word格式发生变化,从而导致解析出来的xml有问题,到最后会影响导出的word文档格式没都没了的情况(这是个坑,我试了很多次才发现是因为变量过长导致的word格式变形从而导致的解析出来的xml文件有问题)

 2.模板建好以后直接另存为xml,这里上图给你们讲一下怎么另存xml,我发现好多人不知道怎么另存为xml,我这里以wps为例子(word office 也一样),点击左上角的文件,找到另存为,选择另存的位置以及格式,这里选择xml如图所示

 

3.之后我们可以在存放文件的地方得到一个xml文件如图所示

 

4.使用 可以打开xml文件的工具打开文件,我这里用的是Notepad++

将文件中的内容复制出来,去在线格式化一下格式,我这里用的是菜鸟教程的在线格式化地址:https://c.runoob.com/front-end/710 

将格式化之后的内容复制回 Notepad++,接下来就是对xml中的内容做修改。

5.我们的word表格一共两行,第一行为标题,第二行为我们需要设置的字段值,找到文件中第二个<w:tr></w:tr>标签

 因为我们是将list数据循环设置到word中,所以需要遍历值,遍历语法是freemark的遍历语法,挺简单的,用<#list userList as user></#list>标签将第二行的<w:tr></w:tr>包裹起来如图所示,userList就是你要遍历的list,user就是list中的每个元素,相当于foreach中的item=userList var=user都是一个意思,实在看不懂建议百度一下吧。

写完外面的循环标签,在设置里面的字段值,找到之前我们填写1-7数字的地方,1为序号,我们用${user_index+1}表示,这样可以自增序号,2-7为user这个实体中的属性,直接替换成${user.属性}即可,不过这里有一点需要注意,就是要对值进行非空判断,不然如果有的值为空就会出现模板解析错误。这里只写一个例子,其他的同理,如图所示

 

 所有属性都替换成如上图的格式以后保存xml文件,然后转换成ftl格式的文件,这里转换不需要像doc转xml一样,直接重命名然后改后缀名即可,如图所示

6.这样我们的模板就做好了,个人认为模板这里是最麻烦的,因为坑比较多,所以我也是踩了好多坑,最后才成功了,还有一点要说一下,这里最好用doc格式。代码部分比较简单,直接贴代码了,直接copy就可以用

	/**
	 * 导出word
	 *
	 * @param request
	 * @param response
	 */
	@RequestMapping(params = "exportDoc")
	public void exportDoc(HttpServletRequest request, HttpServletResponse response,String proId) {
		//查询专家列表数据
		List<TSUser> expertList = sinoExaminepaperServiceI.selPaperUser(proId, 0);
        Map<String, List<TSUser>> dataMap = new HashMap<>();
        List<TSUser> list = new ArrayList<>();
        if (expertList != null && expertList.size() > 0) {
			for (TSUser tsUser : expertList) {
			    list.add(tsUser);
			}
		}
		dataMap.put("userList",list);
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_29);
        configuration.setDefaultEncoding("utf-8");

        PrintWriter out = null;
        Template t = null;
        try {
            configuration.setDirectoryForTemplateLoading(new File(request.getSession().getServletContext().getRealPath("/")+"webpage/com/sino/secretariatexamine/word/"));
            response.reset();
            response.setHeader("Content-Disposition", "attachment;filename=\"" + new String("征求意见专家名单.doc".getBytes("GBK"), "iso8859-1") + "\"");
            response.setContentType("application/x-download;charset=GBK");
            response.setCharacterEncoding("utf-8");
            out = response.getWriter();
            t = configuration.getTemplate("expertList.ftl","utf-8");
            t.process(dataMap, out);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            out.close();
        }


    }

 这里是我的业务代码部分,想要使用的要做相应的修改,我做的是一个专家列表数据导出功能,list根据情况修改成要查询的list数据,注意list的key userList,这里的key是和模板中<#list userList as user></#list> 中对应的。

根据各自情况需要修改的有以下几个部分

1.查询出来的list

2.new Configuration(Configuration.VERSION_2_3_29),这里的freemark模板版本改成你maven中导入的freemark模板的版本

3.设置模板加载地址的路径需要做相应的修改,可以参考https://www.cnblogs.com/fangjian0423/p/freemarker-templateloading-question.html 看下configuration设置加载模板的三个方法

4.configuration.getTemplate里面填写你的模板名字(我这里将ceshi.ftl改成了expertList.ftl)

 

补充:如果不是导出list列表数据,只导出一个实体数据,比如自动填写简历那种,更简单,直接将dataMap.put中的list改为实体就行了,然后制作模板的时候去掉外层的list循环,在字段的地方直接${实体的属性}这样就行了,我这里是设置了响应头下载了,如果在本地玩还可以直接将word生成写到磁盘文件中,代码我就不贴了,有需要的可以去百度下。

 

代码部分相对来说比较简单,只要搞清楚一些设置参数的含义,修改成你项目中相对应的参数就可以了。然后启动项目进行测试就OK了,结果如图,大功告成!

 

 

 

 

 

 

本文含有隐藏内容,请 开通VIP 后查看