利用word的freemarker模板导出word文件

博客内容讲述了前端如何通过jQuery发起POST请求,向后台发送数据。后端接收到请求后,使用Freemarker模板引擎填充数据并生成Word文件,最后将文件写入浏览器供用户下载。整个过程涉及了HTTP请求、模板引擎和文件流操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前端请求

var url = window.webApi.business.exportYearWord;
jQuery('<form action="' + url + '" method="post)">' // action请求路径及推送方法
// + '<input type="text" name="opType" value="' + opType + '"/>'
+ '</form>').appendTo('body').submit().remove();

====================================================

后端java类1

  处理查询数据:ProductWordMainDeal.java

package com.synda.back.controller.wordExportFreemark;

import com.synda.back.tools.Ret;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/back/exportFreemarkWord")
public class ProductWordMainDeal {

    @RequestMapping("/exportYearWord")
    public String exportYearExaminedWord(HttpServletRequest request,HttpServletResponse response){
        try {
           String templateFileName="123.ftl";
           String targetFileName="导出的文件名称.doc";

           Map<String, Object> dataMap = new HashMap<String, Object>();
           dataMap.put("register", "注册人");
           dataMap.put("editor","编辑人");

           //填充查询数据到模板文件,生成文件输入流
           FileInputStream ins=ProductWordFile.fillDataToTemplate(dataMap,templateFileName);

           //将文件输入流写到浏览器下载
           if(ins!=null){
               Boolean browserFlag=ProductWordFile.downToBrowser(ins,targetFileName,request,response);
               if(!browserFlag){
                   return Ret.fail("导出Word到浏览器失败!").toJson();
               }
           }else{
               return Ret.fail("导出Word失败!").toJson();
           }
        } catch (Exception e) {
            e.printStackTrace();
            return Ret.fail("导出Word失败!").toJson();
        }
        return null;
    }
}

后端java类2

        将查询数据填充到模板生成临时文件流,将文件流写到浏览器:ProductWordFile.java

package com.synda.back.controller.wordExportFreemark;

import freemarker.template.*;
import org.springframework.stereotype.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;


@Controller
public class ProductWordFile {

    /**
     * 1、将查询数据填充到模板文件生成新的文件流
     * @param dataMap 查询数据
     * @param templateFileName 模板文件名
     * @return
     * @throws FileNotFoundException
     */
    public static FileInputStream fillDataToTemplate(Map<String, Object> dataMap, String templateFileName) throws FileNotFoundException {
        File file = null;
        InputStream fin = null;
        file =WordTemplateFillData.createDoc(dataMap, templateFileName);//填充查询数据到ftl模板
        return new FileInputStream(file);
    }




    /**
     * 2、将填充数据的doc文件写出到浏览器
     * @param targetFileName 导出目标文件名
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public static Boolean  downToBrowser(FileInputStream ins,String targetFileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
        //==============================================解决导出中文名乱码问题
        if(targetFileName!=null&&!"".equals(targetFileName)) {
            String userAgent = request.getHeader("User-Agent");
            //针对IE或者以IE为内核的浏览器
            if (userAgent.contains("MSIE") || userAgent.contains("Trident") || userAgent.contains("Edge")) {
                targetFileName = java.net.URLEncoder.encode(targetFileName, "UTF-8");
            } else {//非IE浏览器的处理
                targetFileName = new String(targetFileName.getBytes("UTF-8"), "ISO-8859-1");
            }
        }

        response.setCharacterEncoding("utf-8");
        response.setContentType("application/force-download");
        response.setHeader("Content-Disposition","attachment;fileName="+targetFileName);
        return writeToBrowser(response.getOutputStream(),ins);
    }


    /**
     * 将文件流写到浏览器
     * @param outputStream
     * @param in
     */
    public static Boolean writeToBrowser(OutputStream outputStream,InputStream in) {
        try {
            byte[] buffer = new byte[4];
            int r = -1;
            while (-1!=(r=in.read(buffer))){
                outputStream.write(buffer,0,r);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if(outputStream!=null) {
                    outputStream.close();
                }
                if(in!=null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



}

后端java类3

        查询数据填充到模板生成文件流:WordTemplateFillData.java

package com.synda.back.controller.wordExportFreemark;

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

import java.io.*;
import java.util.Map;

public class WordTemplateFillData {
    private static Configuration configuration = null;

    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        configuration.setClassForTemplateLoading(WordTemplateFillData.class, "/");
    }

    public static File createDoc(Map<?, ?> dataMap, String type) {
        String name = "temp" + (int) (Math.random() * 100000) + ".doc";
        File f = new File(name);
        Template t;
        try {
            t = configuration.getTemplate(type);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        try {
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
            // Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            Writer w=new BufferedWriter(new OutputStreamWriter( new FileOutputStream(f),"UTF-8"));
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }

}

====================制作模板

 另存为123.xml

修改填充map对应key用${}

重命名123.xml为123.ftl,拷贝到项目代码加载模板的路径位置,该代码模板放置在项目根路径下面。然后运行代码main方法即可查看导出的文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值