• Java之word导出下载


    访问我的博客

    前言

    最近遇到项目需求需要将数据库中的部分数据导出到 word 中,具体是在一个新闻列表中将选中的新闻导出到一个 word 中。参考了网上一些教程,实现了该功能,在此记录下来。

    导出结果如下:

    mark

    图中为导出的其中两条新闻。

    搜索网上导出 word 的方式有很多种,但是很多都是一笔带过,有示例代码的只找到了 POI 导出,和通过 FreeMarker 方式导出,但是只是具有参考意义。本文采取使用 FreeMark 方式。

    实现步骤

    1. Maven 工程引入FreeMarker 的依赖,非 Maven 工程添加 jar 包
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.26-incubating</version>
    </dependency>
    
    1. 创建 word 模板

      1. 新建 word 替换内容为占位符
        mark

      2. 另存模板为 XML 文件
        mark

      3. 使用 NotePad++ 打开 xml 文件

      4. 选中全部内容,到这里进行格式化

      5. 将原内容替换为格式化后的内容

      6. 因为我的 word 的内容是一个列表,所以需要添加一个 freemarer 标签标识

      7. 找到 <w:document> 元素下面的 <w:body> 元素,添加 <#list newsList news> , 并在</w:body>结束标签之前闭合 </#list>, 此处的 newsList 为后台读取模板时需要需要渲染数据map集合的key, 其所对应的是一个list集合。
        mark

      8. 保存为 FreeMarker 的模板文件,后缀为 ftl 格式,拷贝到项目中
        mark

    2. 编写代码

      1. 从数据中查询数据集合放入Map中, 调用工具方法,返回流
      Map<String, Object> root = new HashMap<String, Object>();
      	root.put("newsList", newsList);//newsList为新闻对象集合
      	String template = "/temp.ftl";  //模板文件的地址
      	ByteArrayOutputStream outputStream = WordUtil.process(root, template);
      	return outputStream;
      
      1. 调用下载工具类进行下载即可。
      DownloadUtil.download(byteArrayOutputStream, response, returnname);
      

      注:在实现功能的时候,由于采取的是 ajax 请求方式,导致只是将流写入 Response 时, Response 为 xml 格式的数据。但是想要实现的效果是弹出下载框,下载 word 文档。最后查询资料,修改ajax请求为form表单提交方式(ajax form),才弹出下载框实现了功能。

    文章涉及工具类

    //WordUtil.java
    import java.io.BufferedWriter;
    import java.io.ByteArrayOutputStream;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.util.Map;
    
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    
    public final class WordUtil {
    	  private static Configuration configuration = null;
    
    	  private WordUtil() {
    	    throw new AssertionError();
    	  }
    
    	  /**
    	   * 根据模板生成相应的文件
    	   * @param root 保存数据的map
    	   * @param template 模板文件的地址
    	   * @param path 生成的word文档输出地址
    	   * @return
    	   */
    	  public static synchronized ByteArrayOutputStream process(Map<?, ?> root, String template) {
    
    	    if (null == root ) {
    	      throw new RuntimeException("数据不能为空");
    	    }
    
    	    if (null == template) {
    	      throw new RuntimeException("模板文件不能为空");
    	    }
    
    	    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    	    String templatePath = template.substring(0, template.lastIndexOf("/"));
    	    String templateName = template.substring(template.lastIndexOf("/") + 1, template.length());
    
    	    if (null == configuration) {
    	      configuration = new Configuration(Configuration.VERSION_2_3_23);  // 这里Configurantion对象不能有两个,否则多线程访问会报错
    	      configuration.setDefaultEncoding("utf-8");
    	      configuration.setClassicCompatible(true);
    	    }
    	    configuration.setClassForTemplateLoading(WordUtil.class, templatePath);
    
    	    Template t = null;
    	    try {
    	      t = configuration.getTemplate(templateName);
    	      Writer w = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
    	      t.process(root, w);  // 这里w是一个输出地址,可以输出到任何位置,如控制台,网页等
    	      w.close();
    	    } catch (Exception e) {
    	      throw new RuntimeException(e);
    	    }
    	    return outputStream;
          }
    
    }
    
    //DownloadUtil.java
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.io.FileUtils;
    
    public class DownloadUtil {
    
    	/**
    	 * @param byteArrayOutputStream 将文件内容写入ByteArrayOutputStream
    	 * @param response HttpServletResponse	写入response
    	 * @param returnName 返回的文件名
    	 */
    	public static void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException{
    		response.setContentType("application/msword");
    		response.setHeader("Content-Disposition", "attachment; filename=" + returnName);
    		response.setContentLength(byteArrayOutputStream.size());
    		OutputStream outputstream = response.getOutputStream();			//取得输出流
    		byteArrayOutputStream.writeTo(outputstream);					//写到输出流
    		byteArrayOutputStream.close();									//关闭
    		outputstream.flush();											//刷数据
    	}
    }
    

    源码下载

    点我下载

    参考链接

  • 相关阅读:
    MySQL存储引擎InnoDB与Myisam的六大区别
    PHP+mysql防止SQL注入
    HTTPS 的实现原理
    如何保障 API 接口的安全性?
    使用Merge存储引擎实现MySQL分表
    彻底搞懂Reactor模型和Proactor模型
    REDIS集群脑裂以及解决方案
    linux shell文件合并 去重 分割
    python fnmatch & glob
    sed初理多行合并+sed之G、H、g、h使用+sed n/N使用说明
  • 原文地址:https://www.cnblogs.com/vcmq/p/9484362.html
Copyright © 2020-2023  润新知