Spring Boot 菜鸟教程 10 freemarker导出word下载

freemarker

  • FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
  • FreeMarker是免费的,基于Apache许可证2.0版本发布。其模板编写为FreeMarker Template Language(FTL),属于简单、专用的语言。需要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,主要用于如何展现数据, 而在模板之外注意于要展示什么数据。

最终下载效果

这里写图片描述

项目图片

这里写图片描述

操作流程

  • 准备doc模版
    这里写图片描述
  • 另存为xml文件
    这里写图片描述
  • 修改名为userList.ftl后拷贝文件到src/main/resources
    这里写图片描述

怎样修改userList.ftl

Eclipse下如何打开ftl文件

  • 下载一个专门的ftl编辑器插件,然后在里面格式化;
  • 或者设置ftl的编辑器为jsp的编辑器,用它做format,eclipse->windows->preferences
    这里写图片描述

修改userList.ftl第一步

原来,注意rId4的位置

<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
                    Target="word/document.xml" />

现在

<#list list as user> 
            <Relationship Id="rId${user_index}Png"
                Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
                Target="word/document.xml" /> 
</#list>

修改userList.ftl第二步

原来,注意rId4的位置,image1.png

<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
                    Target="media/image1.png" />

现在

<#list list as user> 
                <Relationship Id="rId${user_index}Png"
                Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image${user_index}.png" />
</#list>

修改userList.ftl第三步

原来

<w:tr>
                            <w:tblPrEx>
                                <w:tblBorders>
                                    <w:top w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:left w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:bottom w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:right w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:insideH w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:insideV w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                </w:tblBorders>
                                <w:tblLayout w:type="fixed" />
                                <w:tblCellMar>
                                    <w:left w:w="108" w:type="dxa" />
                                    <w:right w:w="108" w:type="dxa" />
                                </w:tblCellMar>
                            </w:tblPrEx>
                            <w:tc>
                                <w:tcPr>
                                    <w:tcW w:w="2130" w:type="dxa" />
                                    <w:vAlign w:val="top" />
                                </w:tcPr>
                                <w:p>
                                    <w:pPr>
                                        <w:pStyle w:val="4" />
                                        <w:jc w:val="center" />
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                    </w:pPr>
                                    <w:r>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                        <w:t>111</w:t>
                                    </w:r>
                                </w:p>
                            </w:tc>
                            <w:tc>
                                <w:tcPr>
                                    <w:tcW w:w="2130" w:type="dxa" />
                                    <w:vAlign w:val="top" />
                                </w:tcPr>
                                <w:p>
                                    <w:pPr>
                                        <w:pStyle w:val="4" />
                                        <w:jc w:val="center" />
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                    </w:pPr>
                                    <w:r>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                        <w:t>222</w:t>
                                    </w:r>
                                </w:p>
                            </w:tc>
                            <w:tc>
                                <w:tcPr>
                                    <w:tcW w:w="2131" w:type="dxa" />
                                    <w:vAlign w:val="top" />
                                </w:tcPr>
                                <w:p>
                                    <w:pPr>
                                        <w:pStyle w:val="4" />
                                        <w:jc w:val="center" />
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                    </w:pPr>
                                    <w:r>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                        <w:t>333</w:t>
                                    </w:r>
                                </w:p>
                            </w:tc>
                            <w:tc>
                                <w:tcPr>
                                    <w:tcW w:w="2131" w:type="dxa" />
                                    <w:vAlign w:val="top" />
                                </w:tcPr>
                                <w:p>
                                    <w:pPr>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                    </w:pPr>
                                    <w:r>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                        <w:pict>
                                            <v:shape id="_x0000_i1026" o:spt="75" alt="wx" type="#_x0000_t75" style="height:93.25pt;width:95.6pt;"
                                                filled="f" o:preferrelative="t" stroked="f" coordsize="21600,21600">
                                                <v:path />
                                                <v:fill on="f" focussize="0,0" />
                                                <v:stroke on="f" />
                                                <v:imagedata r:id="rId4" o:title="wx" />
                                                <o:lock v:ext="edit" aspectratio="t" />
                                                <w10:wrap type="none" />
                                                <w10:anchorlock />
                                            </v:shape>
                                        </w:pict>
                                    </w:r>
                                </w:p>
                            </w:tc>
                        </w:tr>

现在

<#list list as user>
                        <w:tr>
                            <w:tblPrEx>
                                <w:tblBorders>
                                    <w:top w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:left w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:bottom w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:right w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:insideH w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                    <w:insideV w:val="single" w:color="auto" w:sz="4" w:space="0" />
                                </w:tblBorders>
                                <w:tblLayout w:type="fixed" />
                                <w:tblCellMar>
                                    <w:left w:w="108" w:type="dxa" />
                                    <w:right w:w="108" w:type="dxa" />
                                </w:tblCellMar>
                            </w:tblPrEx>
                            <w:tc>
                                <w:tcPr>
                                    <w:tcW w:w="2130" w:type="dxa" />
                                    <w:vAlign w:val="top" />
                                </w:tcPr>
                                <w:p>
                                    <w:pPr>
                                        <w:pStyle w:val="4" />
                                        <w:jc w:val="center" />
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                    </w:pPr>
                                    <w:r>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                        <w:t>${user.id}</w:t>
                                    </w:r>
                                </w:p>
                            </w:tc>
                            <w:tc>
                                <w:tcPr>
                                    <w:tcW w:w="2130" w:type="dxa" />
                                    <w:vAlign w:val="top" />
                                </w:tcPr>
                                <w:p>
                                    <w:pPr>
                                        <w:pStyle w:val="4" />
                                        <w:jc w:val="center" />
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                    </w:pPr>
                                    <w:r>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                        <w:t>${user.name}</w:t>
                                    </w:r>
                                </w:p>
                            </w:tc>
                            <w:tc>
                                <w:tcPr>
                                    <w:tcW w:w="2131" w:type="dxa" />
                                    <w:vAlign w:val="top" />
                                </w:tcPr>
                                <w:p>
                                    <w:pPr>
                                        <w:pStyle w:val="4" />
                                        <w:jc w:val="center" />
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                    </w:pPr>
                                    <w:r>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                        <w:t>${user.age}</w:t>
                                    </w:r>
                                </w:p>
                            </w:tc>
                            <w:tc>
                                <w:tcPr>
                                    <w:tcW w:w="2131" w:type="dxa" />
                                    <w:vAlign w:val="top" />
                                </w:tcPr>
                                <w:p>
                                    <w:pPr>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                    </w:pPr>
                                    <w:r>
                                        <w:rPr>
                                            <w:rFonts w:hint="eastAsia" />
                                            <w:lang w:val="en-US" w:eastAsia="zh-CN" />
                                        </w:rPr>
                                        <w:pict>
                                            <v:shape id="_x0000_i1026" o:spt="75" alt="${user.name}" type="#_x0000_t75"
                                                style="height:93.25pt;width:95.6pt;" filled="f" o:preferrelative="t" stroked="f"
                                                coordsize="21600,21600">
                                                <v:path />
                                                <v:fill on="f" focussize="0,0" />
                                                <v:stroke on="f" />
                                                <v:imagedata r:id="rId${user_index}Png" o:title="${user.name}" />
                                                <o:lock v:ext="edit" aspectratio="t" />
                                                <w10:wrap type="none" />
                                                <w10:anchorlock />
                                            </v:shape>
                                        </w:pict>
                                    </w:r>
                                </w:p>
                            </w:tc>
                        </w:tr>
                        </#list>

修改userList.ftl第四步,关键是图片

原来

<pkg:part pkg:name="/word/media/image1.png" pkg:contentType="image/png">
        <pkg:binaryData>iVBORw0KGgoAAAANSUhEUgAAAPEAAADrCAYAAAC4hnD0AAAgAElEQVR4nOx9B5wkZZn.....
gxxYtZVEXKLEIEZJxCVKDHJAxP8PvwV4N/MWQn4AAAAASUVORK5CYII=
        </pkg:binaryData>
    </pkg:part>

现在

<#list list as user>
    <pkg:part pkg:name="/word/media/image${user_index}.png" pkg:contentType="image/png">
        <pkg:binaryData>${user.headPortrait}</pkg:binaryData>
    </pkg:part>
    </#list>

最后祝你好运,细心,注意标签闭合,image名称对应

UserController.download方法##

@Autowired
  private FreeMarkerConfigurer freeMarkerConfigurer;
  private Base64 b64Encoder = new Base64();

  // 处理下载word文档
  @RequestMapping("/download")
  public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 告诉浏览器用什么软件可以打开此文件
    response.setHeader("content-Type", "application/msword");
    // 下载文件的默认名称
    response.setHeader("Content-Disposition", "attachment;filename=xx.doc");
    freeMarkerConfigurer.getConfiguration().setClassForTemplateLoading(getClass(), "/");
    Template template = freeMarkerConfigurer.getConfiguration().getTemplate("userList.ftl");

    String webapp = request.getServletContext().getRealPath("/");

    List<User> list = userRepository.findAll();
    for (int i = 0; i < list.size(); i++) {
      User user = list.get(i);
      File file = new File(webapp, user.getHeadPortrait());
      FileInputStream fis = new FileInputStream(file);
      byte[] imgData = new byte[fis.available()];
      fis.read(imgData);
      fis.close();
      String headPortrait = b64Encoder.encodeAsString(imgData);
      user.setHeadPortrait(headPortrait);
    }
    Map<String, Object> root = new HashMap<String, Object>();
    root.put("list", list);
    template.process(root, new OutputStreamWriter(response.getOutputStream()));
  }

user.jsp,添加的核心代码##

function headPortraitFormatter(value,row,index){
    if (value){
        return "![]("+value+")";
    } else {
        return "";
    }
}
    
<th data-options="field:'headPortrait',width:10,formatter:headPortraitFormatter">头像</th>

<a data-url="downloadUser" href="javascript:void(0)" class="easyui-linkbutton c5" iconCls="icon-reload">word下载</a>

其他关联代码

注意事项##

  • 最后还是要祝你好运,还是细心,注意标签闭合,image名称对应

源码地址

https://github.com/je-ge/spring-boot

如果觉得我的文章或者代码对您有帮助,可以请我喝杯咖啡。
**您的支持将鼓励我继续创作!谢谢! **

微信打赏
微信打赏

支付宝打赏
支付宝打赏

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容