去年做了一个将word表格从后端导出的功能

在这里久远的记录一下...

文档准备

excel表格用编辑器打开后,可以发现它也是一个可编辑的标记性的格式,如同html页面里面的标签首尾相连。

为表格填充假数据

首先为需要导出的word表格填充假数据来占位。

方便之后动态填充数据找到对应的位置。

将word文档另存为xml格式文件

填充好数据后,我们将word文档保存为xml标记语言。

然后将其命名为.ftl后缀文件。

在IDEA里对其进行格式化,我们就能看到其像标签一样的标记语言。

后台操作

引入freemarker的依赖

首先要为我们的项目中引入freemarker的依赖。

<!--freemarker-->
<dependency>
	<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
	<version>2.3.23</version>
</dependency>

### 使用到的工具类

在这里,我对项目word导出使用到一个工具类如下~

public class WordUtils {

  private static Configuration contractConfiguration = null;
  private static Configuration applicationConfiguration = null;

  //这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
  //private static final String templateFolder = WordUtils.class.getClassLoader().getResource("").getPath();
  private static String templateFolder = SystemUtil.getRootPath() + SystemUtil.DOCUMENT_FORM_PATH;//模板存放路径

  static {
    contractConfiguration = new Configuration(Configuration.VERSION_2_3_23);
    contractConfiguration.setDefaultEncoding("utf-8");
    try {
      contractConfiguration.setDirectoryForTemplateLoading(new File(templateFolder + SystemUtil.SEPARATOR + "contract"));
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

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

  //导出合同
  public static void exportWord(HttpServletRequest request, HttpServletResponse response, Map map, String title, String ftlFile) throws IOException {
    Template freemarkerTemplate = contractConfiguration.getTemplate(ftlFile);
    File file = null;
    InputStream fin = null;
    ServletOutputStream out = null;
    try {
      // 调用工具类的createDoc方法生成Word文档
      file = createDoc(map, freemarkerTemplate);
      fin = new FileInputStream(file);
      //String fileName = title + ".doc";
      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;
  }
}

这里map是代表存放的数据,以键值对的形式存取。

title代表导出文件的名称。

ftlFile代表模板的名称。

调用工具类

调用工具类eg~

  @RequestMapping(value = "/registerExport/{djbid}", method = RequestMethod.GET)
  @ResponseBody
  public JsonResult registerExport(@PathVariable String djbid, HttpServletRequest request, HttpServletResponse response) {
    PrintRegisterVO djbData = getCbhtData(djbid);
    String title = djbData.getCbfmc() + "-登记簿";
    Map<String, Object> dataMap = new HashMap<String, Object>();
    dataMap.put("djb", djbData);
    try {
      WordUtils.exportContractWord(request, response, dataMap, title, "农村土地承包经营权证登记簿.ftl");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }

ftl模板动态data替换

局部模板代码如下~~~

<#list djb.familyMember as f>
    <w:tblPrEx>
      <w:tblCellMar>
        <w:top w:w="0" w:type="dxa"/>
        <w:bottom w:w="0" w:type="dxa"/>
      </w:tblCellMar>
    </w:tblPrEx>
    <w:trPr>
      <w:gridAfter w:val="1"/>
      <w:wAfter w:w="10" w:type="dxa"/>
      <w:trHeight w:h-rule="exact" w:val="454"/>
      <w:jc w:val="center"/>
    </w:trPr>
    <w:tc>
      <w:tcPr>
        <w:tcW w:w="1340" w:type="dxa"/>
        <w:vAlign w:val="center"/>
      </w:tcPr>
      <w:p wsp:rsidR="00A24009" wsp:rsidRPr="00487C70" wsp:rsidRDefault="00FE0AE2" wsp:rsidP="00210D10">
        <w:pPr>
          <w:spacing w:line="400" w:line-rule="exact"/>
          <w:jc w:val="center"/>
          <w:rPr>
            <w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast"/>
            <wx:font wx:val="宋体"/>
            <w:sz w:val="24"/>
            <w:sz-cs w:val="24"/>
          </w:rPr>
        </w:pPr>
        <w:r>
          <w:rPr>
            <w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast"/>
            <wx:font wx:val="宋体"/>
            <w:sz w:val="24"/>
            <w:sz-cs w:val="24"/>
          </w:rPr>
          <w:t></w:t>
        </w:r>
        <w:r>
          <w:rPr>
            <w:rFonts w:ascii="宋体" w:h-ansi="宋体"/>
            <wx:font wx:val="宋体"/>
            <w:sz w:val="24"/>
            <w:sz-cs w:val="24"/>
          </w:rPr>
          <w:t>${f.cyxm!}</w:t>
        </w:r>
      </w:p>
    </w:tc>
    <w:tc>
      <w:tcPr>
        <w:tcW w:w="845" w:type="dxa"/>
        <w:gridSpan w:val="2"/>
        <w:vAlign w:val="center"/>
      </w:tcPr>
      <w:p wsp:rsidR="00A24009" wsp:rsidRPr="00487C70" wsp:rsidRDefault="00FE0AE2" wsp:rsidP="00210D10">
        <w:pPr>
          <w:spacing w:line="400" w:line-rule="exact"/>
          <w:jc w:val="center"/>
          <w:rPr>
            <w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast"/>
            <wx:font wx:val="宋体"/>
            <w:sz w:val="24"/>
            <w:sz-cs w:val="24"/>
          </w:rPr>
        </w:pPr>
        <w:r>
          <w:rPr>
            <w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast"/>
            <wx:font wx:val="宋体"/>
            <w:sz w:val="24"/>
            <w:sz-cs w:val="24"/>
          </w:rPr>
          <w:t></w:t>
        </w:r>
        <w:r>
          <w:rPr>
            <w:rFonts w:ascii="宋体" w:h-ansi="宋体"/>
            <wx:font wx:val="宋体"/>
            <w:sz w:val="24"/>
            <w:sz-cs w:val="24"/>
          </w:rPr>
          <w:t>${f.cyxbmc!}</w:t>
        </w:r>
      </w:p>
    </w:tc>
</#list>

End

关于freemarker导出word实现还有很多种方式~

此处有错误望指出~

关于freemarker语法我会单独开一篇blog~

文章作者: 已删除用户
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yida
Back-end Word导出 Freemarker
喜欢就支持一下吧