之前使用[XWPFDocument][]动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所以使用freemarker动态生成,生成的支持所有格式。

一、使用officeword建一个需要的表格,需要动态替换的可以先写上字母

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70][]

二、另存为word2003xml格式

![20190507101739653.png][]

三、把后缀修改为ftl

![20190507101833803.png][]

四、把word xml格式化,可以使用notepad++的xml tool插件,或者使用在线格式化

格式化前

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 1][]

格式化后

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 2][]

五、把之前所有要替换的字母加$\{\}

![20190507102240262.png][]改为![20190507102258388.png][]

六、需要动态添加的找到

,在上加

![20190507102336915.png][]

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 3][]

循环里面的字母加上$\{postdutyNormObj.\}

![20190507103541717.png][]

七、合并单元格

例合并5行的第一列,第一行的第一列有值,增加;第二、三、四、五行的第一列没值把去掉,增加

第一行:

![20190507104953341.png][]

第二、三、四、五行:

![20190507104936551.png][]

动态判断如下:其中index是行号

![20190507105305977.png][]

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 4][]

八、内容相同的上下行合并,其中preContent是上一行的值,可以在java里添加需要判断列的值

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 5][]

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 6][]

九、单元格内换行

![20190507105707524.png][]

在java里循环,trs就是替换的count

for (int i = 0; i < count; i++) {

VPersonalWorkDailyChild tr = list_p.get(i);

VPersonalWorkDaily parent = baseInfoService.getObjectById(VPersonalWorkDaily.class, tr.getId_personal_work_daily());

String data = i+1+". "+gfnull(tr.getTime())+" "+gfnull(parent.getName_place())+gfnull(tr.getPlace())+" "+gfnull(tr.getContent());

trs += "

"+

""+

""+

""+

""+

""+

""+

""+

""+

""+

""+

""+

""+data+""+

""+

"";

}

十、Controller代码,map是所有要替换的内容

/**

*

* @Date 2019年2月25日 下午17:30:23

* @Description 考核成绩汇总导出考核表具体条目

* @Fcunction exportWordForSpecific

* @param response

* @return ReturnDatas

*

*/

@ResponseBody

@SystemControllerLog(description="考核成绩汇总导出考核表具体条目")

@RequestMapping(value="exportWordForSpecific")

public ReturnDatas exportWordForSpecific(HttpServletResponse response, String id){

ReturnDatas returnDatas = ReturnDatas.getSuccessReturnDatas();

try {

Map map = assessGradeSumService.exportWordForSpecific(id);

String org_name = (String) map.get("org_name");

String user_name = (String) map.get("user_name");

String month_ = (String) map.get("month_");

response.setCharacterEncoding("UTF-8");

response.setContentType("application/msexcle");

response.setHeader("content-disposition", "attachment;filename="+new String((org_name+"-"+user_name+month_+"履职考核表").getBytes("utf-8"),"ISO8859-1")+".doc");

OutputStream outputStream = response.getOutputStream();

WordGenerator.createDoc(map, "AssessMonthTable2.ftl", outputStream);

outputStream.flush();

outputStream.close();

returnDatas.setStatus(ReturnDatas.SUCCESS);

return returnDatas;

} catch (Exception e) {

e.printStackTrace();

LogUtil.error("考核成绩汇总导出考核表具体条目异常:"+e.getMessage(),e);

returnDatas.setStatus(ReturnDatas.ERROR);

returnDatas.setMessage("考核成绩汇总导出考核表具体条目异常。");

}

return returnDatas;

}

十一、WordGenerator 工具类

package com.enter.net.util;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.Writer;

import java.util.Map;

import freemarker.template.Configuration;

import freemarker.template.Template;

import freemarker.template.TemplateException;

public class WordGenerator {

/**

* 生成doc文件

* @param dataMap word中需要展示的动态数据

* @param templateName word模板名称

* @param output 输出流

* @return

* @throws IOException

* @throws TemplateException

*/

public static void createDoc(Map, ?> dataMap,String templateName,OutputStream output) throws TemplateException, IOException {

//创建配置实例

Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);

//设置编码

configuration.setDefaultEncoding("UTF-8");

//空值

configuration.setClassicCompatible(true);

//ftl模板文件统一放至 com.fh.template 包下面

configuration.setClassForTemplateLoading(WordGenerator.class,"/templates/");

//获取模板

Template template = configuration.getTemplate(templateName);

//将模板和数据模型合并生成文件

Writer out = new BufferedWriter(new OutputStreamWriter(output,"UTF-8"));

// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开

// Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");

//生成文件

template.process(dataMap, out);

//关闭流

out.flush();

out.close();

}

}

十二、参考

注:若动态替换的内容里有特殊符号,如"<>",可以是用?html转义。在freemarker模板里把$\{content\}改成$\{content?html\}

标签相关

:每一行;

:是每一列;

:里面添加合并;

:里面是内容样式及内容;

:里面是内容;

$\{assessAllObj.content?html\}:如果替换的内容里有<>会报错,可以加上?html进行转义

常用到的语句

#if>

#if>

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70]: /images/1599997842466.png

[20190507101739653.png]: /images/1599997819417.png

[20190507101833803.png]: /images/1599997797266.png

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 1]: /images/1599997763522.png

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 2]: /images/1599997740474.png

[20190507102240262.png]: /images/1599997715295.png

[20190507102258388.png]: /images/1599997685929.png

[20190507102336915.png]: /images/1599997657247.png

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 3]: /images/1599997627679.png

[20190507103541717.png]: /images/1599997602324.png

[20190507104953341.png]: /images/1599997578442.png

[20190507104936551.png]: /images/1599997549191.png

[20190507105305977.png]: /images/1599997523687.png

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 4]: /images/1599997495250.png

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 5]: /images/1599997463967.png

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 6]: /images/1599997424074.png

[20190507105707524.png]: /images/1599997370369.png

freemarker html 换行,java使用freemarker模板导出word,合并单元格,单元格内换行相关推荐

  1. 【Apache POI】Java Web根据模板导出word文件

    最近工作中遇到一个需求:根据word模板文档导出word文件. 查阅了一些资料,发现Apache POI可以实现文档读写的功能,于是就研究了一下,总结如下: Apache-POI在线Javadoc:h ...

  2. java通过ftl模板导出word最详细教程

    百度云链接 链接: https://pan.baidu.com/s/1OEzvsFSqAelstDtu2mo5xw 提取码: fdhq https://pan.baidu.com/s/1OEzvsFS ...

  3. java利用poi模板导出word文件

    注意:  doc文件的读取,需要导入poi-scratchpad包: docx文件读取,需要导入poi-ooxml包: 一.引入pom <dependency><groupId> ...

  4. springboot中使用freemarker根据flt模板导出word、pdf文档

    1.导包: <!--FreeMarker --> <dependency><groupId>org.springframework.boot</groupId ...

  5. freemarker模板导出word循环图片表格详细教程

    前言:表哥之前已经过一篇freemarker模板导出带表格word详细教程  freemarker模板导出带表格word详细教程_Java大表哥的博客-CSDN博客,为什么现在又要写一篇呢. 因为我这 ...

  6. java关于对于word或者pdf文件的批量下载实现,其中包括(Java实现创建word文档模板,根据模板导出word文档)

    本次需求是,pdf是表格类型的文件,我这里使用了word模板进行处理.但由于是多个文件一起导出,因此全部放到一个目录底下进行打包下载. ## 整体思路 /*** 下载思路:* 1.查询出数据后:* 2 ...

  7. java调用word模板文件_Java使用模板导出word文档

    Java使用模板导出word文档 需要导入freemark的jar包 使用word模板,在需要填值的地方使用字符串代替,是因为word转换为xml文件时查找不到要填入内容的位置.尽量不要在写字符串的时 ...

  8. java通过Excel 模板导出复杂统计类excel文档,在ruoyi前后端分离框架中的应用

    Hello, 大家好! 我是不作死就不会死,智商不在线,但颜值超有品的拆家队大队长 --咖啡汪 一只不是在戏精,就是在戏精路上的极品二哈 前几天刚做了java通过Excel 模板导出复杂统计类exce ...

  9. java 根据excel模板导出excel

    java 根据excel模板导出excel 由于项目需求,最近做了一个需要根据查询接口导出excel表格数据的需求 pom依赖: <dependency><groupId>or ...

  10. java 分析excel模板,java 根据excel模板导出excel

    java 根据excel模板导出excel 由于项目需求,最近做了一个需要根据查询接口导出excel表格数据的需求 pom依赖: org.apache.poi poi 3.16 org.apache. ...

最新文章

  1. mysql5.6热升级_mysql 5.6 后热数据的加载
  2. git 下载项目和更新项目(1)
  3. 如何绘制caffe网络训练曲线
  4. Linux之VMware Tools显示灰色正确解决办法
  5. 从程序员小仙飞升上神,java技术开发要如何实现?
  6. Linux命令之iconv命令
  7. Labview之RS485通信
  8. hbase 2.0.5的下载及安装
  9. linux安装eclipse教程,Linux下的Eclipse安装
  10. win10系统与时间服务器同步超时,如何解决Win10系统时间无法同步的问题?
  11. 笔记本电脑WIFI图标消失解决方案大全,无WIFI图标也能自由连WIFI上网。
  12. MOOC中国大学自动评分js脚本
  13. 什么是企业邮箱客户端授权码,如何使用?
  14. 杭州的旅游景点与民间传说故事
  15. 申论公文题-总结类-1
  16. 桌面录屏软件,分享3个十分便捷的录屏软件
  17. [Cqoi2016] 密钥破解 Java 题解
  18. LinuxZIP压缩和解压缩
  19. idea左边项目栏目录结构不见了/文件夹在上面显示
  20. 从狭义相对论到经典场论(一):起源和洛伦兹变换的导出

热门文章

  1. 深大数据库系统实验3——DATABASE SOFTWARE练习实验
  2. freetype安装
  3. localhost和127.0.0.1都无法打开的解决方法
  4. 猫眼app产品分析和原型绘制
  5. 设计模式 - 状态模式
  6. hexo categories和tags页面不显示解决办法
  7. PPAPI插件的全屏切换处理
  8. Visual studio 2013安装失败总结
  9. Google Earth Engine(GEE) 批量运行和取消task
  10. 1.3 nest.js使用supertest单元测试及e2e测试