java实现word模板导出

java实现word模板导出

以下文档为例
在这里插入图片描述

方案一 通过freemarker模板引擎

步骤
1.制作模板
使用freemark语法填充变量
在这里插入图片描述

另存为xml格式
在这里插入图片描述

使用记事本工具检查${}是否连贯,把中间的内容删除即可
在这里插入图片描述

在循环处增加<#list 集合名 as 变量名></#list>
在这里插入图片描述
在这里插入图片描述

将xml文件的后缀改为.ftl

2.代码实现

添加依赖

<!--freemark模板引擎-->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.28</version>
</dependency>
@RestController
@RequestMapping("/word")
public class WordExportController {
    @GetMapping("/export")
    public void wordExport(HttpServletResponse response) {
        Map<String, Object> data = new HashMap<>();
        data.put("name", "年终总结大会");
        data.put("place", "第一会议室");
        data.put("time", "2021年3月25日");
        data.put("sponsor", "张三");
        List<User> users = Lists.newArrayList(
                new User("张三", "组织部", "10:00"),
                new User("李四", "宣传部", "10:00"));
        data.put("userList", users);
        FreeMarkerUtil.createLocalDoc(data, response);
    }
}

public static void createLocalDoc(Map<String, Object> data, HttpServletResponse response) {
    try {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/msword");
        response.setHeader("Content-disposition", "attachment;filename=" + new String("会议签到表".getBytes("utf-8"), "ISO8859-1"));
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
        configuration.setDefaultEncoding("UTF-8");
        configuration.setDirectoryForTemplateLoading(new File("C:\\Users\\luban\\Desktop"));
        Template template = configuration.getTemplate("test.ftl");
        OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
        template.process(data, writer);
        writer.flush();
        writer.close();
    } catch (Exception e) {
        e.printStackTrace();
        log.info("生成word文档发生异常<{}>", e.getMessage());
    }
}

3.效果如下
在这里插入图片描述

4.补充
以上方法导出的word文档直接用ms打开没什么问题,但是要再java中使用pdf转换还是不行,因为其本质上还是一个xml文件,所以需要结合zip文件将其转换为word对应格式
另存为mht(包含富文本必须用此格式) 或者word xml
使用这种方法对普通变量,少量图片处理基本没啥问题
需要使用远程模板参考https://blog.csdn.net/MrSpirit/article/details/100770060
word标签解析参考https://blog.csdn.net/renfufei/article/details/77481753

方案二 Xdocreport和Freemaker生成docx

只使用freemaker生成简单的word文档很容易,但是当word文档需要插入动态图片,带循环数据,且含有富文本时解决起来相对比较复杂,但是使用Xdocreport可以轻易解决。
Xdocreport既可以实现文档填充也可以实现文档转换,此处只介绍其文档填充功能。
源码地址;https://github.com/opensagres/xdocreport
文档地址:https://github.com/opensagres/xdocreport/wiki/GettingStarted
步骤:
1.制作模板
以以下文档为例
在这里插入图片描述

会议内容为一段富文本
我们需要在变量替换的位置通过快捷键Ctrl+F9 或 工具栏“插入”->“文档部件或文本”->“域”
在这里插入图片描述

选择邮件合并,添加对应属性

在这里插入图片描述
在这里插入图片描述

遇到需要循环的位置
在第一列的里
在这里插入图片描述

“@before-row[#list userList as user]”
@after-row[/#list]
遇到图片,先插入一张图片,再为图片添加书签

在这里插入图片描述
在这里插入图片描述

这样模板就制作完成,不需要保存为xml,ftl。直接使用doc或者docx后缀即可
2.代码实现
引入依赖

<dependency>
    <groupId>fr.opensagres.xdocreport</groupId>
    <artifactId>xdocreport</artifactId>
    <version>2.0.2</version>
</dependency>

核心代码

public static void createXdocreport() {
        try {
            //使用远程模板
//            InputStream inputStream = new URL(templateUrl).openConnection().getInputStream();
            File inputPath = new File("C:\\Users\\luban\\Desktop\\summary.docx");
            FileInputStream inputStream = new FileInputStream(inputPath);
            File outputPath = new File("C:\\Users\\luban\\Desktop\\test.docx");
            FileOutputStream outputStream = new FileOutputStream(outputPath);
            IXDocReport report = XDocReportRegistry
                    .getRegistry()
                    .loadReport(inputStream, TemplateEngineKind.Freemarker);
            // 设置特殊字段
            FieldsMetadata metadata = report.createFieldsMetadata();
            metadata.addFieldAsTextStyling("content", SyntaxKind.Html);
            metadata.addFieldAsImage("avatar", "user.avatar", NullImageBehaviour.RemoveImageTemplate);
            report.setFieldsMetadata(metadata);
            // 创建内容-text为模版中对应都变量名称
            String content = "&#x3c;p&#x3e;我在这里放了一段富文本&#x3c;/p&#x3e;" +
                    "&#x3c;p&#x3e;我准备测试富文本的处理&#x3c;/p&#x3e;";
            content = HtmlUtils.htmlUnescape(content);
            IContext context = report.createContext();
            context.put("name", "年终总结大会");
            context.put("time", "2021年3月26日");
            context.put("place", "线上");
            context.put("sponsor", "张三");
            context.put("content", content);
            //图片这里放图片的输入流
            InputStream p1 = new FileInputStream(new File("C:\\Users\\luban\\Desktop\\图片1.png"));
            InputStream p2 = new FileInputStream(new File("C:\\Users\\luban\\Desktop\\图片2.jpg"));
            List<UserAvatar> users = Lists.newArrayList(
                    new UserAvatar("张三", "组织部", new ByteArrayImageProvider(p1)),
                    new UserAvatar("李四", "宣传部", new ByteArrayImageProvider(p2)));
            context.put("userList", users);
            // 生成文件
            report.process(context, outputStream);
            inputStream.close();
            outputStream.close();
        } catch (Exception e) {
            log.info("生成纪要文件发生异常:<{}>", e.getMessage());
        }
    }

测试

public static void main(String[] args) {
    createXdocreport();
}

效果如下
在这里插入图片描述

源码地址
https://github.com/lubanjune/word-export.git
参考博文
https://blog.csdn.net/renfufei/article/details/53283320
https://blog.csdn.net/weixin_44569204/article/details/86543711
https://blog.csdn.net/erpenggg/article/details/106714402

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值