Spring Boot 导出Word文档(二)结束篇

248 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

书接上文

该怎么生成导出字节流呢

首先是获取模板文件 然后创建一个文件对象 和一个输入字节流 和一个 输出字节流对象 然后调用上文的createDoc()方法来生成一个文件 然后通过FileInputStream()方法来生成一个输入字节流 然后再把输入字节流的内容给转到输出字节流里来让浏览器下载 具体就是这么一个流程 有不懂的看几遍代码应该就清晰了

   public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map, String title, String ftlFile) throws IOException {
        Template freemarkerTemplate = configuration.getTemplate(ftlFile);
        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");
            // 设置浏览器以下载的方式处理该文件名
            String fileName = title  + ".doc";
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "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(); // 删除临时文件
        }
    }

而整个工具类的全文如下

package com.zhong.share.work.control.JudeController;

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.Writer;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

public class WordUtils {

    private static Configuration configuration = null;
        //classLoader.getResource()只能获取相对路径的资源
//     private static  String templateFolder = WordUtils.class.getClassLoader().getResource("/teacherPlan.ftl").getPath();
    private static  String templateFolder = "F://controlleclass//src//main//resources//people";
        //class.getResource()可以获取绝对路径和相对路径
//        private static String templateFolder = WordUtils.class.getResource("/teacherPlan").getPath();


    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        try {
        	templateFolder = URLDecoder.decode(templateFolder, "UTF-8");
        	System.out.println(templateFolder);
            configuration.setDirectoryForTemplateLoading(new File(templateFolder));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private WordUtils() {
        throw new AssertionError();
    }

    public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map, String title, String ftlFile) throws IOException {
        Template freemarkerTemplate = configuration.getTemplate(ftlFile);
        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");
            // 设置浏览器以下载的方式处理该文件名
            String fileName = title  + ".doc";
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "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 = "sellPlan.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;
    }
}

而怎么在control类里调用呢 则把数据放到map里 然后输出

      //下载违规人员表
    @GetMapping("/export")
    public  void exportSellPlan(HttpServletRequest request, HttpServletResponse response){

        User user = new User();

        List<User> list = new ArrayList<>();
        list = userService.JudedPeople();

        String prestr = "";
        for (int i = 0; i < list.size(); i++) {
            User u = list.get(i);
            String value = u.getUsername();
            if (i == list.size() - 1) {// 拼接时,不包括最后一个&字符
                prestr = prestr + "   " + value;
            }
            else {
                prestr = prestr + "   " + value + "   ";
            }

        }

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("peopleid", prestr);
            try {
                WordUtils.exportMillCertificateWord(request, response, map, "违规人员表", "people.ftl");
            } catch (IOException e) {
                e.printStackTrace();}

        }