likes
comments
collection
share

代码改变生活(二)

作者站长头像
站长
· 阅读数 12

一、起因

由于工作需要,我需要为20多个商家制作打分表。其中商家数据已登记在系统之中,打分表包括商家的名称、联系人、联系电话、地址等信息,已有一个现成的word模板。

二、解决方案

1. 升级商家管理系统

系统由第三方公司开发,暂不具备修改升级的可能性。一方面这个需求很小众,应用范围很窄;另一方面,没有经费支持(穷)。

2. 手动硬刚

步骤大概是这样的,将模板复制20多份,修改文件名为对应商家的名称,逐一打开word文档填充需要的数据。

3. 写个小工具

根据“模板+数据=>输出”的思路,可以读取模板,然后遍历商家数据填充进模板,最终得到我想要的输出结果。

三、技术选型

作为一名合格(懒)的程序员,能用代码实现的事情那肯定坚决不手动完成。我采用写个小工具的方案,由于我主要使用的还是Java语言,所以优先考虑使用Java语言实现。如果有其他更好的解决方案,请在评论区留言讨论。

1. POI

Apache POI 是基于 Office Open XML 标准(OOXML)和 Microsoft 的 OLE 2 复合文档格式(OLE2)处理各种文件格式的开源项目。 简而言之,您可以使用 Java 读写 MS Excel 文件,可以使用 Java 读写 MS Word 和 MS PowerPoint 文件。

使用Apache POI组件读取word模板,然后在表格固定的位置写入数据,最终保存。此方案优点不多,但缺点很明显。

  • poi使用纯Java代码操作word文件,不直观。
  • 在word里面解析表格会遇到一些不可预料到的问题,比如行列与所见不一致。
  • 需要熟悉poi一整套的api使用方案

2. Freemarker

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

Freemarker是专业的模板引擎,首先需要将word模板转为我们能识别修改的word 2007 xml格式,然后在对应的内容位置放置变量。 我早期在开发word文档导出、数据库文档生成工具时采用的就是这个方案。 缺点:

  • word模板转出来的xml文件标签众多、内容超长,不方便查找替换变量。
  • 如果想要修改模板,只能从头来过,简直就是一个噩梦。

3. Velocity

和Freemarker同理

4. poi-tl

Word 模板引擎,基于Microsoft Word模板和数据生成新的文档,并且支持用户自定义函数,函数可以在Word模板的任何位置执行。

poi-tl可以直接在模板文件内放置变量标签,代码也极为简洁。

四、代码

经过上述解决方案的对比,我最终选择了poi-tl作为word模板引擎,数据通过json文件存储。

package org.example;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.deepoove.poi.XWPFTemplate;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.util.Map;

public class Main {

    public static void main(String[] args) throws Exception {

        URL url = Main.class.getClassLoader().getResource("data.json");
        JSONArray arr = JSON.parseArray(url);

        url = Main.class.getClassLoader().getResource("template.docx");
        File file = new File(url.getFile());

        XWPFTemplate template = XWPFTemplate.compile(file);
        for (int i = 0; i < arr.size(); i++) {
            JSONObject item = arr.getJSONObject(i);
            Map<String, Object> params = JSONObject.parseObject(arr.getString(i), new TypeReference<Map<String, Object>>() {});
            template.render(params).write(new FileOutputStream(String.format("%s-打分表.docx", item.getString("enterName"))));
        }
    }

}

五、最后

本以为给我的打分表模板就是最终版本,结果把每个商家的打分表交去给领导看的时候,领导对局部的文字换行、打分项分值和顺序做了调整,幸好我使用了模板+代码方式生成最终的文件,只需要修改下模板重新运行下程序就可以了,如果是手工硬刚出来的,我想我怕是会跳起来打人!

Author: wangsy Link: wangsy.me/2023/code-c…

转载自:https://juejin.cn/post/7247372662456418360
评论
请登录