Poi-tl、freemarker以及xdocreport 生成word文件的方式




简单介绍

在项目中经常会遇到报表相关的需求,而大多数会以excel出现,今天咱们说说word导出的一些事


文章目录

前言

Java对word导出支持不太友好,由于本人水平有限,知道两种方式生成word文件。

1.freemarker+ftl

2.xdocreport开源工具


freemarker+ftl

引入freemarker包,准备好需要生成word模板的ftl文件。该文件是有word生成xml,在由xml修改后缀名得到的temp.ftl文件

 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

缺点:word —>xml —>ftl 的过程繁琐且容易出错,ftl为标签内容不易读,如果模板变更又要重复word —>xml —>ftl 的过程。需要强大的内心和耐心。

xdocreport开源工具

该开源工具填写word模板语法一致,但不需要生成ftl文件作为模板,本身word就可直接作为导出模板。

<dependency>
     <groupId>fr.opensagres.xdocreport</groupId>
     <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
     <version>2.0.2</version>
</dependency>
<dependency>
     <groupId>fr.opensagres.xdocreport</groupId>
     <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
     <version>2.0.2</version>
</dependency>

优点:可读性提高,修改模板是可以增量操作,无需复杂操作再次生成ftl文件


一、freemarker导出word步骤

  • 新建word文档,写入内容样式,然后将动态获取的值放置内容展示区域
  • 将文件保存后,另存为xml格式
  • 打开文档显示内容如下,修改xml文件后缀名为ftl文件即可。
  • private void exportDoc(String fileName, HttpServletResponse response, String tempName) {
        PrintWriter writer = null;
    	Map<String, Object> dataMap = new HashMap<>();
        // 将要写入模板的数据塞到dataMap中。
    	dataMap.put("name":"i am kobe");
        try {
            Configuration configuration = new Configuration(new Version("2.3.0"));
            configuration.setDefaultEncoding("utf-8");
            // 上面配置模板的路径
            configuration.setClassForTemplateLoading(DocServiceImpl.class, "/templates");
            configuration.setTemplateLoader(new ClassTemplateLoader(DocServiceImpl.class, "/templates"));
            response.setContentType("application/msword");
            response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(fileName.getBytes("GBK"), "ISO-8859-1") + "\"");
            response.setCharacterEncoding("utf-8");
            writer = response.getWriter();
            // tempName是模板的文件名称
            Template template = configuration.getTemplate(tempName, "utf-8");
            template.process(dataMap, writer);
        } catch (Exception e) {
            logger.error("导出word文档异常 : {}", e);
        } finally {
            writer.flush();
            writer.close();
        }
    }

    这样就完成了freemarker配置以及下载word文档的功能了。


二、xdocreport导出word步骤

  • 还是之前那个文档,同样的属性 name字段,之前是${name} 现在变成 word加域的形式
  • 如何加域,请看图片
  • 点击上方缺点即可。模板已经配置完成了,是不是方便了许多呢?
  • 上Java代码,直接撸代码了。
  • public void download(HttpServletRequest request,HttpServletResponse response){
    	try{
    		InputStream inputStream = new FileInputStream(new File("D:\\template.docx"));
    		IXDocReport report = XDocReportRegistry.getRegistry().loadReport(inputStream, TemplateEngineKind.Freemarker);
    		IContext context = report.createContext();
    		report.setFieldsMetadata(fieldsMetadata);
    		//替换word模板中创建的域的变量
    		context.put("name", "我叫张三");
    		//导出word
    		ByteArrayOutputStream bout = new ByteArrayOutputStream();
    		// 获取OutputStream 也就是写入bout
    		report.process(context, bout);
    		//创建文件输出流
    		FileOutputStream out = new FileOutputStream("d:\\daochudeword.docx");
    		out.write(bout.toByteArray());
    		out.close();
    		bout.close();
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }


三、常见语法介绍

使用才是开始,语法才是修行。xdocreport的语法是兼容freemarker的。

if判断的使用,下面是判断list集合是否为空且长度是否大于0

[#if list?? && (list?size>0)]

[#else]
    list 集合为空
[/#if]


[#if list?? && (list?size>0)]

[/#if]

对象判空

[#if obj??]

[/#if]

数组的使用,循环输出多条数据

[#list list as temp]
    ${temp}
[/#list]

四、Poi-tl开源工具

pom.xml包引入
<dependency>
  <groupId>com.deepoove</groupId>
  <artifactId>poi-tl</artifactId>
  <version>1.12.0</version>
</dependency>
public static void main(String[] args) {
        Map<String, Object> params = new HashMap<>();
        // 渲染文本
        params.put("dep","知识研发中心");
        params.put("apply_man","知识追寻者");
        params.put("project","搭建个人网站 https://zszxz.com/index 费用");
        params.put("money","19998");
        params.put("count","8");
        params.put("year","2020");
        params.put("month","02");
        params.put("day","8");
		
    	// 模板路径
        String templatePath = "C:/mydata/generator/demo/template.docx";
        // 生成word的路径
        String fileDir = "C:/mydata/generator/demo";
        // 生成word的文件
        String fileName = "zszxz.docx";
        String wordPath = createWord(templatePath, fileDir, fileName, params);
        System.out.println("生成文档路径:" + wordPath);
    }




private static Logger logger = LoggerFactory.getLogger(TemplateController.class);
   /**
    * @author lsc
    * @param templatePath word模板文件路径
    * @param fileDir      生成的文件存放地址
    * @param fileName     生成的文件名
    * @param paramMap     参数集合
    * @return 返回word生成的路径
    */
    public static String createWord(String templatePath, String fileDir, String fileName, Map<String, Object> paramMap) {
        Assert.notNull(templatePath, "word模板文件路径不能为空");
        Assert.notNull(fileDir, "生成的文件存放地址不能为空");
        Assert.notNull(fileName, "生成的文件名不能为空");
        File dir = new File(fileDir);
        if (!dir.exists()) {
            logger.info("目录不存在,创建文件夹{}!", fileDir);
            dir.mkdirs();
        }
        String filePath = fileDir +"\\"+ fileName;
        // 读取模板渲染参数
        XWPFTemplate template = XWPFTemplate.compile(templatePath).render(paramMap);
        try {
            // 将模板参数写入路径
            template.writeToFile(filePath);
            template.close();
        } catch (Exception e) {
            logger.error("生成word异常{}", e.getMessage());
            e.printStackTrace();
        }
        return filePath;
    }

总结

很多语法不是很常用,if和list是本人在项目中运用的较多的,后续会及时更新相关语法。

Poi-tl 开源工具兼容性更好、操作更加简单、文档根据齐全,非常之方便 Poi-tl Documentation

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
FreeMarkerPoi-tl 都是基于模板的生成方式,需要先创建一个 Word 文档模板,然后将数据填充到模板中,最终生成一个完整的 Word 文档。它们之间的主要区别在于生成方式和操作方法。 1. 生成方式 FreeMarker生成方式是基于模板的,需要程序员先创建一个 Word 文档模板,然后使用 FreeMarker 引擎将数据模型中的数据填充到模板中,并生成一个完整的 Word 文档。 Poi-tl 也是基于模板的生成方式,但它提供了更加方便的模板编辑方式Poi-tl 可以使用 Microsoft Office 软件创建模板,也可以使用 Poi-tl 提供的 API 直接创建模板。 2. 操作方法 FreeMarkerPoi-tl 都是使用 API 对文档进行操作,例如修改样式、替换变量、插入图片等等。但是它们的操作方法略有不同。 FreeMarker 使用类似于 JSP 的语法,即通过 ${} 表示一个变量,将数据模型中的数据填充到相应的变量位置上。同时,FreeMarker 还提供了一些内置的指令,如 if、list 等,可以用于逻辑控制和循环操作。 Poi-tl 则使用类似于 Word 的书签的方式,它将模板中的变量替换成书签,然后使用 Poi-tl 提供的 API 将数据填充到书签位置上。同时,Poi-tl 还提供了一些针对 Word 模板的 API,例如修改样式、替换变量、插入图片等等。 3. 使用场景 由于 FreeMarkerPoi-tl 是基于模板的生成方式,因此适用于需要批量生成相似结构的 Word 文档的场景,例如生成合同、报告、简历等。 4. 功能 FreeMarkerPoi-tl 都提供了丰富的 API,可以对 Word 文档进行各种操作,例如修改样式、替换变量、插入图片等等。但是它们的功能略有不同。 FreeMarker 主要是通过填充模板来生成 Word 文档,并提供了一些基本的操作 API,例如对模板中的变量进行替换、对模板中的样式进行修改、插入图片等等。 Poi-tl 则提供了更加方便的模板编辑方式,可以使用 Microsoft Office 软件创建模板,也可以使用 Poi-tl 提供的 API 直接创建模板。同时,Poi-tl 还提供了针对 Word 模板操作的 API,例如修改样式、替换变量、插入图片等等。 综上所述,FreeMarkerPoi-tl 都是用于生成 Word 文档的工具,它们之间有着不同的生成方式、操作方法、使用场景和功能。选择哪个工具应根据具体的需求和场景进行判断。如果需要批量生成相似结构的 Word 文档,可以选择 FreeMarkerPoi-tl;如果需要更加方便的模板编辑方式和针对 Word 模板的操作 API,可以选择 Poi-tl

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值