使用FreeMarker自定义生成word文档

使用FreeMarker自定义生成word文档

最终生成word文档如下:
在这里插入图片描述

实现思路:
  1. 按照要生成的文档模板格式,创建一个新的word(doc)文档,将其调整成所需格式,然后处理其中需要动态填充的数据,如下:
    在这里插入图片描述
  2. 将该word文档另存为Word 2003 XML 文档(*.xml)格式,然后将其后缀改为.ftl
  3. 此时该.ftl文件里的内容格式可能不规范,规范其内容,例如:”${map.projectName}“中间可能被其他字符给分隔。所以要把中间的无用字符给删掉;
  4. 最后生成的文件可能长这样:
    在这里插入图片描述
功能实现:

模板已经写好,现在就是后端代码实现了。

	/**
     * 生成word
     * @param projectInformation	该课题信息对象
     * @param dir	要生成的word的存储路径
     * @return
     * @throws Exception
     */
    public static String exportWord(ProjectInformation projectInformation, String dir){

        File file = new File(dir);
        if (!file.exists()){
            file.mkdirs();
        }
        Configuration conf = new Configuration();
        conf.setDefaultEncoding("UTF-8");
        //加载模板文件(模板的路径)
        conf.setDirectoryForTemplateLoading(new File(dir));
        // 加载模板
        String separator = File.separator;
        Template template = conf.getTemplate("templatePrint.ftl");
        template.setEncoding("UTF-8");
        // 定义数据
        Map root = new HashMap();

        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isNotBlank(projectInformation.getName())){
            map.put("projectName",projectInformation.getName());
        }else {
            map.put("projectName","");
        }
        if (StringUtils.isNotBlank(projectInformation.getName())){
            map.put("projectNumber", projectInformation.getNumber());
        }else {
            map.put("projectNumber","");
        }
        if (StringUtils.isNotBlank(projectInformation.getName())){
            map.put("serialNumber",projectInformation.getSerial());
        }else {
            map.put("serialNumber","");
        }

        SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
        String currentTime = sf.format(new Date());
        map.put("currentTime",currentTime);
        root.put("map",map);

        // 定义输出
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");//设置日期格式
        String date = f.format(new Date(System.currentTimeMillis()));
        Random random = new Random();
        int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;// 获取5位随机数
        String fileName = date+rannum+"标签.doc";
        //判断文件夹是否存在,不存在则创建
        File fileDir = new File(HtmlUtil.getAppDir()+separator+"Template");
        if (!fileDir.exists()){
            fileDir.mkdirs();
        }
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(HtmlUtil.getAppDir()+separator+"Template" + separator+fileName),"UTF-8"));
        template.process(root, out);
        out.flush();
        out.close();
        return fileName;
    }    
    
##### 补充:
如果要生成的文档里面包含表格,怎么循环放置数据?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/38256.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Ubuntu】Ubuntu14 安装 open-jdk-1.7(open-jdk-7) 最新 持续更新中

【Ubuntu】Ubuntu14 安装 open-jdk-1.7&#xff08;open-jdk-7&#xff09; 最新 持续更新中 一、概述二、特别说明三、开发环境四、安装 open-jdk-1.7五、配置环境1、配置环境变量路径2、环境变量3、完成安装 一、概述 一个好的文章能够帮助开发者完成更便捷、更快速的开发。…

红帽Linux 8.0末班车

RH124&#xff64;RH134&#xff64;RH294三门课和考前辅导的套包课程。红帽系统管理是针对了解 Linux 并需要核心红帽企业 Linux 技能的 IT 业人员而设计的。学完这个课程后&#xff0c;学员将能够执行安装操作&#xff0c;建立网络连接&#xff0c;管理物理存储器&#xff0c…

Linux vs MacOS ,你更喜欢哪个系统?

大家应该都知道Windows&#xff0c;Linux和MacOS这几个操作系统&#xff0c;它们各有优缺点&#xff0c;比如像游戏等专门的领域&#xff0c;Windows当然是比Linux更好些&#xff0c;但Linux是开源的&#xff0c;安全性和稳定性要比Windows要好&#xff0c;如果是关于视频编辑方…

什么企业适合建设数据中台?

从历史脉络中&#xff0c;看到数据中台凸显价值&#xff0c;数据中台是大数据下一站。所有企业都适合建设数据中台吗&#xff1f;什么样应该建数据中台&#xff1f; 2018年我们在建数据中台前面临的窘境&#xff0c;通过了解我们建数据中台的背景&#xff0c;你也可以对照着看…

CTFShow-WEB入门篇文件上传详细Wp(151-170)

WEB入门篇--命令执行详细Wp 文件上传&#xff1a;Web151&#xff1a;Web152&#xff1a;Web153&#xff1a;Web154&#xff1a;Web155&#xff1a;Web156&#xff1a;Web157&#xff1a;Web158&#xff1a;Web159&#xff1a;Web160&#xff1a;Web161&#xff1a;Web162&#…

基于JAVA SpringBoot和Vue UniApp外卖订餐小程序

随着社会的发展和进步&#xff0c;网络信息技术的迅速发展已经渗透到我们生活的各个角落&#xff0c;传统餐饮业也受到了很大的影响&#xff0c;大部分传统中餐馆都开门&#xff0c;最多只能通过一个电话预约。但是在中国春节长假期间&#xff0c;餐厅不能接待这么多顾客。因此…

学习react,复制一个civitai(C站)-更新3

更新内容 优化了一下加载速度 图片列表 初步更新了199张图片&#xff0c;大部分都有stable diffusion 的prompts。 可以直接复制到AI绘画里面使用。 先来看看效果图吧&#xff1a; 我还是挺喜欢这种砌砖流布局 技术点 同样使用了砌墙瀑布流布局:masonry js 安装方法 npm …

15 - 信号处理设计模式

---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接&#xff1a;&#xff08;更新中&#xff09;Linux系统编程训练营 - 目录 文章目录 1. Linux应用程序安全性讨论1.1 问题1.2 不同场景1.2.1 场景一&#xff1a;不需要处理信号1.2.2 场景二&#xff1a;需要处理信号 2. 场景…

matlab将0 1矩阵显示为黑白图像

解决方法 clear clc pattern cell2mat(struct2cell(load("pattern"))); pic1 squeeze(pattern(1:64,:,:,:)); pic1 logical(permute(pic1, [2,3,1])); temp pic1(:,:,1); imshow(pic1(:,:,1));显示效果 test int8(rand(30,30)); imshow(logical(test));本来想…

初识mysql数据库之索引概念与磁盘效率问题

目录 一、索引的概念及作用 二、实际看看索引的效率提升 三、认识磁盘 1. 简单了解磁盘 2. 数据库文件存储位置 3. 定位扇区 4. 数据读取效率问题 5. 磁盘随机访问与磁盘连续访问 5.1 随机访问 5.2 连续访问 四、mysql与磁盘的交互 五、建立共识 一、索引的概念及…

Flask_使用flask_marshmallow序列化数据

代码如下&#xff1a; from flask import Flask from flask_marshmallow import Marshmallow from flask_sqlalchemy import SQLAlchemy from marshmallow import fieldsapp Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] "mysqlpymysql://root:12…

excel常用操作备忘

excel操作&#xff1a; 1、快速填充多列公式&#xff1a;选中多列后&#xff0c;按ctrlD填 充。 2、快速删除空行&#xff1a;全选行&#xff0c;按ctrlG&#xff0c;空值项前边打上钩&#xff0c;点确定&#xff0c;针对选中的空行&#xff0c;鼠标右击&#xff0c;点删除&…

消息推送(websocket)集群化解决方案

目录 需求分析解决方案实现步骤架构图配置websocket请求地址配置websocket连接前置和连接关闭监听配置websocket处理程序配置redis交换机配置redis订阅监听配置redis发布监听需求分析 及时信息传递:消息推送功能能够确保网站向用户发送及时的重要信息,包括新闻更新、促销活动…

漏洞复现畅捷通CRM SQL注入

免责声明 术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用…

网络安全专业必考的三个证书,初学者建议收藏!

学习网络安全&#xff0c;有三个必考证书&#xff0c;最后一个人手一本&#xff01; 一&#xff0c;NISP证书 NISP即国家信息安全水平考试&#xff0c;由中国信息安全测评中心发证&#xff0c;属于网络安全专业的必考证书。 只有考取NISP一级证书才有机会考取二级&#xff0…

三季度上市,比亚迪海豹DM-i内饰官图发布,延续海洋风格

据报道&#xff0c;比亚迪海洋网旗下全新车型海豹 DM-i今日发布了内饰官方图片。新车内部采用了独特的“海洋美学”设计理念&#xff0c;并体现了海洋网最新一代内饰风格。消息称&#xff0c;这款车型将于第三季度上市&#xff0c;定位为中大型混合动力轿车。 值得注意的是&…

亚马逊会员日结束了,如何防止销量和排名“断崖式”下跌?

令人瞩目的2023亚马逊Prime会员日落下了帷幕&#xff0c;据官方数据显示&#xff0c;48小时售出商品超3.75亿件&#xff0c;再一次创造了历史新纪录&#xff01; 好不容易因为亚马逊会员日提升了销售额和曝光了品牌&#xff0c;那么会员日结束了&#xff0c;如何稳住您的销量和…

java通过url获取视频时长(无需下载文件)

1、导入架包 <!-- jave 核心依赖 --><dependency><groupId>ws.schild</groupId><artifactId>jave-core</artifactId><version>2.4.6</version></dependency><!-- 根据不同操作系统引入不同FFmpeg包 --><!-- wi…

【多线程例题】顺序打印abc线程

顺序打印-进阶版 方法一&#xff1a;三个线程竞争同一个锁&#xff0c;通过count判断是否打印 方法二&#xff1a;三个线程同时start&#xff0c;分别上锁&#xff0c;从a开始&#xff0c;打印后唤醒b 三个线程分别打印A&#xff0c;B&#xff0c;C 方法一&#xff1a;通过co…

keep-alive和router-view配合使用缓存整个路由页面以及路由切换

实现内容&#xff1a;通过vue实现&#xff0c;在页面有侧边栏动态来展示当前页面流程&#xff0c;右边进行页面的切换&#xff0c;左右两边都是组件&#xff0c;但是A/B/C组件的切换是通过keep-alive搭配router-view实现的&#xff0c;首先在当前文件中创建五个文件&#xff1a…