java使用freemaker自定义路径导出Word关键点讲解版

如何制作Word模板并用Java导出自定义的内容 在做项目时会按照指定模板导出word文档,本文讲解分析需求后,制作word模板、修改模板内容,最终通过Java代码实现按照模板自定义内容的导出。 阅读详情

最近工作遇到需要开发java导出Word操作,这里我选用的模板是freemaker。

导出的前期操作在网络上一找一大把,我这里复述下我的操作:

1.将要导出的模板打到Word中,然后另存为xml格式的文件。

文档中要作为动态替换的内容信息,需要使用${}包住,值得注意的是,在Word文档中,如果Word识别认为需要替换的部分存在语病,被波浪线标注出来了,那么在转换为xml格式的时候,会被拆开,无法被当做一个字段来处理,所以需要在转换xml之前的Word中,将语病去除修改好。 

2.将修改好的xml文件,以ftl的格式保存,当做在代码中使用的模板,放在静态文件目录中

3.下面就是导出部分,我们首先实现代码中拼装字段,输出到本地中

public void createDoc(Map<String, Object> dataMap, String fileName) throws UnsupportedEncodingException {
        //dataMap 要填入模本的数据文件
        //设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
        //这里我们的模板是放在template包下面
        configuration.setClassForTemplateLoading(this.getClass(), "/template");
        Template t = null;
        try {
            //occupationalHealth.ftl为要装载的模板
            t = configuration.getTemplate("occupationalHealth.ftl");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //输出文档路径及名称
        File outFile = new File(fileName);
        //如果不存在临时路径则创建
        if (!outFile.getParentFile().exists()) {
            outFile.getParentFile().mkdirs();
        }
        Writer out = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(outFile);
            OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8");
            //这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。
            //out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
            out = new BufferedWriter(oWriter);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        try {
            t.process(dataMap, out);
            out.close();
            fos.close();
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
   }

 我个人认为这里的写法有很多,网上能搜索出很多大同小异的操作,核心方法就是 ,先加载本地ftl模板,成为输出流的形式,再通过process方法将传入的要替换的参数与模板处理成Word文件输出到指定的目录,这里我的参数也贴一下:

Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("depart", exportDomain.getEnterpriseName());
        dataMap.put("factory", exportDomain.getWorkShop());
        dataMap.put("employee", exportDomain.getName());
        dataMap.put("year", "2021");
        dataMap.put("month", "08");
        dataMap.put("day", "31");
        dataMap.put("medical", "motoGP");

        exportAndPrintService.createDoc(response,dataMap, "D:/outFile.doc");

 其实上面便是输出到本地的几个关键点的罗列,下面,如果想以io流的形式输出到前端,供我们下载,则需要做一些调整:

首先,createDoc方法不能是void类型了,需要设置为file类型:

public File createDoc(Map<String, Object> dataMap, String fileName) throws UnsupportedEncodingException {
        //dataMap 要填入模本的数据文件
        //设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
        //这里我们的模板是放在template包下面
        configuration.setClassForTemplateLoading(this.getClass(), "/template");
        Template t = null;
        try {
            //occupationalHealth.ftl为要装载的模板
            t = configuration.getTemplate("occupationalHealth.ftl");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //输出文档路径及名称
        File outFile = new File(fileName);
        //如果不存在临时路径则创建
        if (!outFile.getParentFile().exists()) {
            outFile.getParentFile().mkdirs();
        }
        Writer out = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(outFile);
            OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8");
            //这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。
            //out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
            out = new BufferedWriter(oWriter);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        try {
            t.process(dataMap, out);
            out.close();
            fos.close();
            return outFile;
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

再最后我们返回了文档路径与名称,这是为后面能够刷出到页面返回了重要的内容

接下来就是关键的一点,也是困扰我很久,怎么将本地生成的文件以流的形式刷 到前端,方法如下:

public void exportMillCertificateWord(HttpServletResponse response, Map map, String fileName) throws IOException {
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            file = createDoc(map, fileName);
            fin = new FileInputStream(file);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            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(); // 删除临时文件
            }
        }

    }

 这个方法首先接收到map,与filename参数,为了能够返回页面,也要定义response。然后在方法中调用刚才写的加载模板与参数,生成本地文档的方法,拿到生成的文档后,我们再将其读到返回值中返回给前端,也就是说,freemaker生成Word读到前端,需要一个临时地址来存放文档,读完后,再由程序删除即可,本地调试可以是本地磁盘,服务器上可以是部署路径,这一点是我研究了一天才弄明白的,我认为这是整个导出操作的关键点所在,导出网上有大把的案例,前端处理网上也有大把案例,但是这个关键点,我没有看到讲述过,记录下来,分享一下。

也顺便贴一下前端处理这个来之不易的输出流的方法:

function exportMethod(data) {
  axios({
    method: 'get',
    url: baseUrl + data.url,//接口地址
    responseType: 'blob',
    headers: {
      'Content-Type': 'application/json'
    }
  }).then((res) => {
    let type = "", type2 = []
    if (data.type == "doc") {
      type = 'application/msword'
      type2 = ['.doc', '.docx']
    }
    const link = document.createElement('a')
    let blob = new Blob([res.data], { type })
    link.style.display = 'none'
    link.href = URL.createObjectURL(blob)
    link.download = data.fileName 
    link.type = type2
    document.body.appendChild(link)
    link.click()
  }).catch(error => {
    console.log(error)
  })
}

前端是vue写的,相信不同的工具的编写方式也是一搜一大把,至于自定义下载路径,则是浏览器的配置问题了。

工作之余匆匆总结下,有问题欢迎指出。

POI XWPFDocument 导出word目录详解 通过XWPFDocument生成目录 正常情况下,通过XWPFDocument自带的createTOC(),可以生成目录,但是有一些缺点: 目录标题无法更改,只能显示英文 样式不够美观,无法布局 按照顺序,只能在word中写入所有内容后在掉createTOC()生成目录,导致目录在最下方 下面我们重写createTOC()来完成对目录样式,布局,标题,位置的修改 /** * 生成目... 阅读详情

相关推荐

java Apache poi 操作word生成word目录(根据word模板生成word文件)

在项目需求中,需要对于一个word模板文档生成相对应的word文件,而此word模板是多页的并且需要在最终文件中生成相应的目录,由于项目环境是Linux,所以舍弃了jacob(windows环境)。然后主要是研究了Apache poi 进行word操作以及如何生成目录。 ...

ONE PIECE——伟大航道 3万+

常用的java模板引擎之 Freemarker 学习入门

常用的java模板引擎之 Freemarker 学习入门:包括环境搭建及快速入门,其基础语法及静态化测试

qq_44999561的博客 787

java快速导出word文档

在 Java 应用程序中,有时候我们需要将数据导出为 Word 文档,以便进行文档的编辑、打印或共享。本文将介绍如何使用 Java 实现导出 Word 文档的方法,帮助你灵活处理文档导出需求。

最初的节奏 3338

Java中静态模板文件freemaker使用

面对大文本数据展示时,每次查询数据库费时费力,基于这种读多写少的需求,考虑使用freemarker生成静态文件,存入文件系统中,查询时直接展示文件,不必在查询数据库。FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。在resources目录下创建templates,在其中创建post.ftl模板文件。json数据源(这里为了方便手动建立JSON数据源,实际开发中可从数据库中查询)

RX1125的博客 592

CANopen PDO 配置實戰:3步完成0x1800-0x1A00物件字典映射與事件觸發

本文详细解析CANopen PDO配置实战,通过3个关键步骤完成0x1800-0x1A00对象字典映射与事件触发设置。重点介绍COB-ID位域解析、映射参数配置及事件触发优化,帮助工程师实现工业自动化设备间毫秒级实时数据交换,提升系统通信效率。

weixin_33709609的博客 379

用CentOS 7安装cadence搭建适合IC Design的科研环境(四)——IC617、MMSIM151、calibre2015安装过程step by step

以下操作都在root权限下执行。建立安装目录建议把这种大型软件装在/opt目录下。mkdir -p /opt/cadence/installscape mkdir -p /opt/mentor/Calibre2015其中-p参数是直接建立父目录。因为IC617和MMISM151会自己建立安装目录,所以在这里没有建相关目录。而calibre则是默认安装在安装包所在的目录下,所以需要提前建立。解压安

maxwell2ic的博客 7万+

java根据模板导出数据到word文档中(表格,自定义标签等)

将鼠标的光标移到要输入数据的地方,点击“插入”,点击“文档部件”,点击“域”;选择“邮件合并”,在域代码的函数后加入自定义的字段名“${字段名}”。如果不用循环的话,直接字段名字节定义名称就可以了,如果需要循环,字段名设置为【${对象.属性}】若需要循环表格内的内容时,处理如下,“域”中“邮件合并”的域代码使用“${对象.属性}”格式,自此,一个简单的模板制作完成。

八月林城的博客 5983

3D Gaussian Splatting:用于实时的辐射场渲染

3D Gaussian Splatting:用于实时的辐射场渲染 3d gaussian splatting for real-time radiance field rendering

m0_51976564的博客 1万+

java导出word

2. Word模板中的表格的长度最好充满Word文档的左右两边,否则如果表格下面还有其他文本内容,下面的文本内容会自动填充到表格的缝隙处,而且会对下面的文本内容进行覆盖。表格数据的处理其实和上面对文本内容的处理是类似的,只不过要在Word模板中加上集合的变量,Java代码中也要有对集合进行特对的处理(这个在后面的代码展示部分会说)。给表格数据添加序号是通过后台代码生成的,比如上面的"goods1.setNum(1)"这段代码,其实也可以在Word模板中设置对应的域变量来实现序号的填充。

weixin_48080634的博客 3900

uniapp map地图实现marker聚合点,并点击marker触发事件

【代码】uniapp map地图实现marker聚合点,并点击marker触发事件。

weixin_44705979的博客 5437

《PLECS仿真与实战:从建模到高端应用》-专栏文件目录

《PLECS仿真与实战:从建模到高端应用》是一本系统介绍PLECS电力电子仿真软件的实用指南。全书共10章,首先介绍软件安装与基础操作,包括RC电路仿真等入门内容;随后深入讲解各类电力电子电路的建模与仿真,涵盖整流、交交变换、直流变换、逆变等电路;最后探讨PWM控制建模和直流调速系统等高端应用。书中配有丰富的示例程序和波形分析方法,附录还包含电力电子器件、代码生成等实用资料。该书适合电力电子领域工程师和学生系统学习电路仿真技术。

540

java 使用freemaker模版生成docx word文档的解决方案

   公司前一段时间做的一个项目中应用到了这个技术,需要后台获取数据后在前台直接下载word文档,利用freemarker模版生成的doc文档在电脑上可以正常打开,但是发送到手机上打开则全部变成“乱码”。但实际上并不是乱码,而是xml格式的代码,在手机等移动端显示不出正常的文档信息。之后辗转查询使用了很多方案,比如利用poi操作,利用jacob进行格式转换,但是效果都不尽如人意,而且处理过程非常复...

Eric_ley的博客 2380

光学传播仿真软件:ASAP_(1).ASAP软件介绍与安装

ASAP(Advanced System for Analysis and Propagation)是一款强大的光学传播仿真软件,广泛应用于光学系统的设计、分析和优化。它提供了丰富的建模工具和仿真功能,可以帮助用户从简单的光学元件到复杂的光学系统进行仿真。:支持光学、机械、热学等多物理场的联合仿真。:采用高精度的算法,确保仿真结果的准确性。:内置了大量的光学元件,如透镜、反射镜、棱镜、光栅等。:提供直观的用户界面,支持多种建模和仿真方式。:支持使用脚本语言进行二次开发,增强软件的定制能力。

kkchenjj的博客 1590

freeMarker创建word文件生成ftl文件模板,根据文件模板标签替换相应数据生成word文件示例

1.什么是freeMarker? FreeMarker是一款用java语言编写的模版引擎,它是基于模板文件生成其他文本的通用工具。它虽然不是web应用框架,但它很合适作为web应用框架的一个组件。 2.它的特点? ① 一轻量级模版引擎,不需要Servlet环境就可以很轻松的嵌入到应用程序中 ② 能生成各种文本,如html,xml,java,等 ③ 入门简单,它是用java编写的,很多语法和java相似 3.使用步骤: ① 创建一个spring boot项目引入maven依赖导入FreeMarker jar

huxiaochao_6053的博客 1443

计算机毕设:线性回归 Xgboost LSTM 预测黄金价格实战 完整代码数据视频讲解 可直接运行

线性回归 Xgboost LSTM 预测黄金价格实战 完整代码数据视频讲解 可直接运行

1760

④ Django创建用户中心应用users,扩展用户信息

本章配套视频教程 Django创建用户中心应用users,扩展用户数据 在settings.py文件中配置项目 1、语言配置:LANGUAGE_CODE = 'zh-hans’ 2、时区配置:TIME_ZONE = 'Asia\Shanghai’ 3、模板路径配置:‘DIRS’: [os.path.join(BASE_DIR, ‘templates’)], 并创建templates文件

轻编程的博客 670

java打印/导出自定义word文档

java导出自定义word文档

m0_64081550的博客 1241

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

导出word文档(office,wps都可以打开)带封面目录

public ResponseEntity<org.springframework.core.io.Resource> exportWord(HttpServletRequest request, HttpServletResponse response) { // 标题 String title = "封面标题"; try { XWPFDocument document= new XWPFDocument(); .

qq_35563165的博客 734

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

java word文档生成目录_JAVA合并word文档生成目录

/*** 先临时生成一个合并完成后的docx格式文档,doc会出现乱码。*@parampathList 所有需要合并的文档的绝对路径*@paramsavePath 一个路径,但是没有文件的后缀,之后进行拼接。*@return状态,是否保存成功*/public static boolean mergeWordToPdf(ListpathList, String savePath){//判断是否...

weixin_42348363的博客 973

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

java根据模板导出word

在Java中,根据模板导出Word文档通常涉及到使用某种库或框架来处理Word文件的格式和内容。Apache POI是一个流行的选择,它提供了一套完整的API来读写Microsoft Office文档,包括Word(.doc和.docx格式)。

liuhm的博客 4336

[含完整代码]Java实现导出word文档【超详细】

[含完整代码]Java实现导出word文档【超详细】java实现导出word文档是项目中很常见的操作,但又是很棘手的操作,这篇文章,带大家从0到1超详细的完整的操作一遍java实现导出word文档。一定要认真看这篇文章,超详细。话不多说直接上代码。

wang20000102的博客 1万+

java导出多个Word到指定路径,再生成压缩包从浏览器下载下来

思路:先逐个导出Word文件到服务器,再压缩,再返回给用户下载。 (导出Word用的是freemarker模板导出形式,这里不再赘述) 直接贴代码: Controller文件: @ApiOperation("同时导出多个Word文件") @GetMapping("/exportZip") public void exportZip(String instrumentIds, HttpServletRequest request, HttpServletResponse respon

lllll520520520520520的博客 1864

java poi导出下载excel报表或下载到指定路径

Java poi导出excel报表hu

qq_39628803的博客 3858

java FreeMarker模板路径问题

【代码】java FreeMarker模板路径问题。

The____wind的博客 784

java 导出word_Java使用word模板导出word

1.创建一个空的springboot工程,引入jar包org.apache.poipoi-ooxml3.17org.apache.poipoi3.172.工具类一package com.example.demo.util;import org.apache.poi.openxml4j.opc.OPCPackage;import org.apache.poi.xwpf.usermodel.XWPFD...

weixin_28876369的博客 530

java通过freemarker生成word文档

1、使用freemarker的原因是:由于POI和ITEXT在处理复杂word文档格式时欠缺,尤其在生成WORD文档时,(其他处理word的工具需要动态加载windows动态链接库,有些还要收费),并且需求要在WORD指定位置插入图片,所以在参考了POI和ITEXT官网处理WORD和网络上其他处理WORD的工具后,发现freemarker可以通过设定WORD模板,经过处理生成...

weixin_34363171的博客 584
上一篇: java中this,super,extends,implements相关继承概念讲解
下一篇: Address already in use: bind JVM端口被占用解决方法
mmm.c
博客等级 码龄9年 117粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值