freemaker导出word时出现值被分割的问题处理

没错,你们最爱的小工具又要出现了。博客好久没有更新了。主要吧,最近好像也没有学习什么东西。之前导出word使用的是freemaker,将编写好的word模板保存为xml格式在改成ftl。然后导出

抽取出一个工具类

import freemarker.template.Configuration;
import freemarker.template.Template;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;

/**
 * Word工具类 <br>
 *
 * @author gzm
 */
public class WordUtils {

	/**
	 * 下载动态生成的Word文件。只支持ftl文件模板。
	 * @param response response
	 * @param map 值
	 * @param templatePath 模板路径,即模板放在哪个位置
	 * @param templateName 模板名称。
	 * @param downloadName 导出文件名。
	 * @throws IOException IO异常
	 */
    public static void downloadWordByTemplate(HttpServletResponse response,
											  Map map, String templatePath, String templateName, String downloadName) throws IOException {

    	MapNullToSpace(map);
    	Configuration configuration = new Configuration();
    	configuration.setDefaultEncoding("utf-8");
    	configuration.setDirectoryForTemplateLoading(new File(templatePath));

    	Template freemarkerTemplate = configuration.getTemplate(templateName);
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map,freemarkerTemplate);
            fin = new FileInputStream(file);

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 设置浏览器以下载的方式处理该文件名
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(downloadName, "UTF-8"))));

            out = response.getOutputStream();
            byte[] buffer = new byte[512];  // 缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } finally {
            if(fin != null) {
            	fin.close();
			}
            if(out != null) {
            	out.close();
			}
            if(file != null) {
            	file.delete(); // 删除临时文件
			}
        }
    }

	private static File createDoc(Map<?, ?> dataMap, Template template) {
        String name =  "test.doc";
        File f = new File(name);
        Template t = template;
        try {
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
            Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }

	/**
	 * Map中null值改为空字符串
	 * @param map Map
	 */
	private static void MapNullToSpace(Map<String, Object> map) {
		for (String key : map.keySet()) {
			if (null == map.get(key)) {
				map.put(key, "");
			}
    	}
	}

}

导出是没有问题了,但是在使用模板的时候却发生了问题

我的word中使用这样的变量,转成ftl时候值却被分割开了

之前我的做法是找到这些值手动去调。眼睛都要瞅瞎了效率还低。所以抽时间写了段脚本,变量中的标签情况掉

    public static void main(String[] args) {

        FileReader fileReader = new FileReader("E:\\个人基本信息表.ftl");

        List<String> strings = fileReader.readLines();
        FileAppender appender = new FileAppender(FileUtil.newFile("D:\\reslut3.ftl"), 16, true);

        for (String string : strings) {
            if (!string.contains("$")) {
                appender.append(string);
                continue;
            }
            string = string.replaceAll("\\$", "#\\$");
            String[] ss = string.split("#");
            // 同一行的内容写到同一行,文件追加自动换行了
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < ss.length; i++) {
                String s1 = ss[i];
                if (!s1.startsWith("$")) {
                    sb.append(s1);
                    continue;
                }
                int i1 = s1.lastIndexOf("}");
                String substr = s1.substring(0, i1 + 1);
                sb.append(substr.replaceAll("<[^>]+>", ""));
                sb.append(s1.substring(i1 + 1));
            }
            appender.append(sb.toString());
        }
        appender.flush();
        appender.toString();

    }

脚本中的文件操作使用的是hutool,这个工具包还是非常强大值得使用,如果没有添加hutool依赖的话,可以自己修改一下文件操作的部分

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.3.10</version>
</dependency>

好了,这样导出的工作就变得简单了很多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值