word转FreeMarker的ftl文件编辑导出编辑后的word

1.ftl文件介绍

ftl是Freemarker模板的文件后缀名
FreeMarker其实是一种比较简单的网页展示技术,说白了就是网页模板和数据模型的结合体。这种结合模式的好处就是,分离了网页界面设计人员和编程人员的工作,让他们各司其职。
FreeMarker大致的工作方式是,网页模板里面嵌入了数据模型中的数据、FreeMarker自定义流程控制语言、FreeMarker自定义的操作函数等等,在装载网页的时候,FreeMarker模板自动从数据模型中提取数据,并解释整个网页为我们熟知的HTML页面。
在B/S程式设计中,常常有美工和程序员二个角色,他们具有不同专业技能:美工专注于表现——创建页面、风格、布局、效果等等可视元素;而程序员则忙于创建程式的商业流程,生成设计页面要显示的数据等等。
模板引擎就是为了解决上面的问题而产生的。在设计HTML的时候,我们加入一些特定指令来指定要插入哪些数据,这些加了特殊指令的HTML或者其他文本,称为模板(Template)。而模板引擎会在输出页面时,用适当的数据替代这些代码,模板和嵌入JSP的HTML是不同的,模板指令只有很有限的编程能力,可以避免混入商业逻辑。

2.word编辑步骤

   2.1 word模板编辑

  •             word可以把要编辑的部分改为$对象.属性或$属性名转为xml文件,$符号与属性名称分开,去掉多余行,把$属性名称写一起
  •            word中含有图片需要模板中传入图片转为xml文件,图片转为文件流,把文件流中的图片替换为$对象.属性或$属性名。
  •            把xml文件改后缀,改为ftl文件。
  •            把ftl文件放在项目指定的路径下。

word转FreeMarker的ftl文件编辑导出编辑后的word_第1张图片

.doc转为xml文件

文字

word转FreeMarker的ftl文件编辑导出编辑后的word_第2张图片

 

图片

 

图片只要把binaryData中的字符流改为${变量名}就可以。

3.后台代码

   

package com.model.controller;



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

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import sun.misc.BASE64Encoder;
import sun.net.www.protocol.http.HttpURLConnection;

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


/**
 * word 下载
 * Created by xxx on 2018/11/6.
 */
@Controller
@RequestMapping("/project")
public class ProjectController {

    private static Logger logger=Logger.getLogger(ProjectController.class);



    /**
     *  下载
     * @param response
     */
    @RequestMapping(value="/download")
    public void download(HttpServletResponse response){
        try{
            Map map=new HashMap(6);
            //组装返回数据
            completeData(map);
            //建立下载文件名称
            String fileName = Long.toString(System.currentTimeMillis()) + RandomStringUtils.randomNumeric(10) + ".doc";
            //修改文件模板
            File file=writeFileTemplate(fileName,map);
            //导出文件
            exportFile(response,file);
        }catch(Exception e){
            logger.error(" download file error",e);
        }
    }

    /**
     * 导出文件
     * @param response
     * @param file
     */
    public  void exportFile(HttpServletResponse response,File file){
        try{
            ServletOutputStream out=response.getOutputStream();
            BufferedInputStream in=new BufferedInputStream(new FileInputStream(file));
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
            byte[] buffer=new byte[1024];
            int count=0;
            while((count=in.read(buffer))!=-1){
                out.write(buffer,0,count);
            }
            out.flush();
            out.close();
        }catch(Exception e){
            logger.error("export word error",e);
        }finally{
            file.delete();
        }
    }

    /**
     * 修改文件模板
     * @param fileName
     * @param map
     * @return
     * @throws Exception
     */
    public File writeFileTemplate(String fileName,Map map) throws Exception{
        try{
            //设置freemarker模板编码、路径、模板名称
            Configuration configuration=new Configuration();
            configuration.setDefaultEncoding("utf-8");
            String tempPath=this.getClass().getResource("").getPath().substring(0,this.getClass().getResource("").getPath().indexOf("WEB-INF"));
            String templatePath=tempPath+"WEB-INF/exportTemplates/trademark/";
            configuration.setDirectoryForTemplateLoading(new File(templatePath));
            Template template=configuration.getTemplate("model.ftl");
            //设置输出文件路径
            String outPath=tempPath+"WEB-INF/tempFile/"+fileName;
            File outFile=new File(outPath);
            Writer writer=null;
            try{
               writer=new OutputStreamWriter(new FileOutputStream(outFile), "utf-8");
               template.process(map,writer);
            }catch(Exception e){
                logger.error("template write data error",e);
                throw e;
            }finally{
                writer.close();
            }
            return outFile;
        }catch(Exception e){
            logger.error("ProjectController.writeFileTemplate  error",e);
            throw e;
        }
    }

    /**
     * 组装返回数据
     * @param map
     * @return
     * @throws Exception
     */
    public Map completeData(Map map)throws Exception{
        try{
            map.put("name","张三");
            map.put("department","技术部");
            map.put("projectName","灿烂");
            map.put("year","2018");
            map.put("month","11");
            map.put("day","8");
            File file=saveToFile("http://mm.yh31.com:88/tp/sdj/201712241958292972.jpg");
            String imageBase64 = encodeBase64File(file);
            map.put("picture",imageBase64);
        }catch(Exception e){
            logger.error("ProjectController.completeData error",e);
            throw e;
        }
        return map;
    }

    /**
     * 通过url获取文件
     * @param destUrl
     */
    public File saveToFile(String destUrl) {
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        HttpURLConnection httpUrl = null;
        URL url = null;
        int BUFFER_SIZE = 1024;
        byte[] buf = new byte[BUFFER_SIZE];
        int size = 0;
        //在填写文件路径时,一定要写上具体的文件名称(xx.txt),否则会出现拒绝访问。
        File file = new File("E:\\download\\picture.png");
        if(!file.exists()){
            //先得到文件的上级目录,并创建上级目录,在创建文件
            file.getParentFile().mkdir();
            try {
                //创建文件
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            url = new URL(destUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            bis = new BufferedInputStream(httpUrl.getInputStream());
            fos = new FileOutputStream(file);
            while ((size = bis.read(buf)) != -1) {
                fos.write(buf, 0, size);
            }
            fos.flush();
        } catch (IOException e) {
        } catch (ClassCastException e) {
            logger.error("url transfer to http url error",e);
            throw e;
        } finally {
            try {
                fos.close();
                bis.close();
                httpUrl.disconnect();
            } catch (IOException e) {
            } catch (NullPointerException e) {
            }
        }

        return file;
    }

    /**
     * 将文件转化为Base64编码
     * @param file
     * @return
     * @throws Exception
     */
    public static String encodeBase64File(File file) throws Exception {
        //File file = new File(path);;
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return new BASE64Encoder().encode(buffer);
    }

}

4.测试中遇到的问题

    4.1 方法public File saveToFile(String destUrl)中的 httpUrl = (HttpURLConnection) url.openConnection();因为HttpUrl与Url引用的java包不一致,Url是.net而HttpURL是apache,为此统一改为.net包

   4.2 获取文件路径的问题,详见博文https://blog.csdn.net/weixin_41926301/article/details/83818927

   4.3 方法public File writeFileTemplate(String fileName,Map map) throws Exception;其中

   writer=new OutputStreamWriter(new FileOutputStream(outFile), "utf-8")错误的写法
   writer=new OutputStreamWriter(new FileOutputStream(outFile))会造成文件输出的编码不是utf-8的格式,从而造成下载后的文件不可读。

5.运行结果

word转FreeMarker的ftl文件编辑导出编辑后的word_第3张图片

   

你可能感兴趣的:(JavaScript,freemaker,word,ftl)