java 将ftl文件作为模板导出word文档

     因为poi等输出word很麻烦,所以本文使用word编辑好模板,转成xml再转成ftl,在java中导入ftl模板,填充数据再生成为word下载或保存。

一、模板文档

1、在Word中编辑好word模板,变量部分用el表达式替代

java 将ftl文件作为模板导出word文档_第1张图片

2、另存为xml文件(2003),打开xml文件,讲 sellerName等改为el表达式:${sellerName!}等,然后将.xml文件后缀改为.ftl,把.ftl模板文件到项目制定目录。加载jar包freemarker.jar然后开始后端代码


二、后台主要代码

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ClassUtils;

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

/**
 * word模板工具类
* 

Title: WordGenerator

*

Description:

* @author terry.peng */ public class WordGenerator { private static Configuration configuration=null; //private static final String templateFolder = WordGenerator.class.getClass().getResource("").getPath()+"/ftl/"; //private static final String templateFolder = WordGenerator.class.getClass().getResource("/" + ClassUtils.convertClassNameToResourcePath(WordGenerator.class.getPackage().getName())).getFile() + "/ftl"; private static final String templateFolder = "D:/ftl"; static{ configuration=new Configuration(); configuration.setDefaultEncoding("utf-8"); try { configuration.setDirectoryForTemplateLoading(new File(templateFolder)); } catch (IOException e) { e.printStackTrace();//throw new RuntimeException(e); } } private WordGenerator() { throw new AssertionError(); } /** * 下载合同 * @param map 要填充的数据模型 * @param docName 下载保存的名称(例如:销售合同.doc) * @param ftlFile ftl模板名称(例如:sellerContract.ftl) * @throws Exception */ public static void downContract(HttpServletRequest request, HttpServletResponse response, Map map,String docName,String ftlFile) throws Exception { File file = null; FileInputStream fin = null; ServletOutputStream out = null; try { setDownloadHeader(request, response, docName);//设置下载头 // 调用工具类的createDoc方法生成Word文档 file = createDoc(request,response,map,docName,ftlFile); fin = new FileInputStream(file.getAbsolutePath()); out = response.getOutputStream(); int len = 0; byte[] buf = new byte[1024]; while ((len = fin.read(buf)) != -1) { out.write(buf, 0, len); } out.flush(); } catch (Exception e) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); throw new Exception(e.getMessage(), e); } finally { if(fin != null) { try { fin.close(); } catch (Exception e) { e.printStackTrace(); } } if(out != null) { try { out.close(); } catch (Exception e) { e.printStackTrace(); } } if(file != null) { try { file.delete();// 删除临时文件 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * 导入ftl并创建doc * @param request * @param response * @param dataMap * @param docName * @param ftlFile * @return * @throws IOException */ public static File createDoc(HttpServletRequest request, HttpServletResponse response,Map dataMap, String docName,String ftlFile) throws IOException { Template template = configuration.getTemplate(ftlFile); String name = templateFolder + File.separator + (int) (Math.random() * 100000) + docName; File file = new File(name); try { // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开 Writer writer = new OutputStreamWriter(new FileOutputStream(file), "utf-8"); template.process(dataMap, writer); // 关闭流 writer.flush(); writer.close(); } catch (Exception ex) { ex.printStackTrace(); } return file; } /** object转map *

Title: objectToMap

*

Description:

* @param obj * @return */ public static Map objectToMap(Object obj) { if (obj == null) { return null; } return new org.apache.commons.beanutils.BeanMap(obj); } /** * map转Object *

Title: mapToObject

*

Description:

* @param map * @param beanClass * @return * @throws Exception */ public static Object mapToObject(Map map, Class beanClass) throws Exception { if (map == null) return null; Object obj = beanClass.newInstance(); org.apache.commons.beanutils.BeanUtils.populate(obj, map); return obj; } /** * * @param request * @param response * @param fileName */ public static void setDownloadHeader(HttpServletRequest request, HttpServletResponse response, String fileName) { String userAgent = request.getHeader("User-Agent"); boolean isIE = (userAgent != null) && (userAgent.toLowerCase().indexOf("msie") != -1); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "must-revalidate, no-transform"); response.setDateHeader("Expires", 0L); response.setContentType("application/x-download"); try { if (isIE) { fileName = new String(fileName.getBytes("gb2312"), "iso-8859-1"); response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\""); } else { fileName = new String(fileName.getBytes("gb2312"), "iso-8859-1"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); } } catch (Exception e) { e.printStackTrace(); } } }

三、其他

ftl模板中取值可以用el表达式取值${username}

如果要迭代list,String[]、或者在模板中做其他逻辑处理等,可以直接写freemarker的语言,例如:

 0)> <#list goodsAttr as g>${g!}<#if g_has_next>]]> ]]>
 <#list tradeRemark?split("\n") as g>${g!}<#if g_has_next>]]> ]]>

在xml中写freemarker语言要用原样输出

word转成的xml回车符号为

效果为

java 将ftl文件作为模板导出word文档_第2张图片

本文出处:https://blog.csdn.net/pdy8023/article/details/80339414



你可能感兴趣的:(JAVAEE)