公司项目最近需要使用操作word文档的功能,对于我来说也是第一次使用Java来操作word,于是在网上去寻找一些好的方法,无意中发现poi-tl这个工具,是真的好用,在此感谢作者,也希望大家多多支持作者。GitHub地址:https://github.com/Sayi/poi-tl

话不多说,开始正题:我这里的项目是对FTP上的word文档进行操作,实现的是对多个word文档先下载到本地再进行合并成一个word,然后对合并的word进行整体的参数替换及图片插入。

代码如下:(请先阅读poi-tl相关方法)

//多文档集合
List<NiceXWPFDocument> list = new ArrayList<NiceXWPFDocument>();
//这里我是把文件上传FTP的记录存在数据库,所有这里下载文件需要文件的主键ID,用逗号隔开多个word的主键
String[] fileId = fileIds.split(",");
Path path = Paths.get(url); //url为你下载word的路径:E:\\test
String fileUrl = path+"/"+你的文件名称加后缀;
//判断文件是否存在(这里是不存在需要下载)
if(!FileUtil.isExistFile(fileUrl)){
    //获取文件
    NiceXWPFDocument docx = null;
    //获取段落末尾
    XWPFRUN runs = null;
    for(int i = 0,i < fileId.length,i ++){
        FTPUtil.downLoadPath(fileUrl);  //这里用你自己的FTP下载方法
        String url = fileUrl.replaceAll("\\\\","/");
        //最重要步骤:逐个读取下载文档,确定初始文件
        if(i == 0){
            docx = new NiceXWPFDocument(new FileInputStream(url));
            runs = docx.createParagraph().createRun();
        }else{
            NiceXWPFDocument doc = new NiceXWPFDocument(new FileInputStream(url));
            list.add(doc);
        }
    }
    NiceXWPFDocument  newDoc = docx.merge(list,runs); //合并多个
    //输出一个新的文档
    FileOutputStream out = new FileOutputStream("自定义输出路径");
    newDoc。write(out);
    newDoc.close();
    out.close;
}

这里可能有人会觉得诧异,为什么不能直接操作FTP上的文件?而需要麻烦的下载到本地来操作,我一开始也是这么想的,但是测试发现poi-tl都是从本地路径来取附件,我不知道是我自己写的方法有问题还是技术能力有限,了解的同学欢迎讲解告知。

好了,这里就完成了多个文件的合并,其实原理还是很简单,就是先读取一个文档的文本结尾,再把第二个文件整体添加至第一个人文档结尾,以此类推。

然后整体替换:(outputStream为网络流)

//url为新文档路径
XWPFTemplate template = XWPFTemplate.compile(url).render(
    new HashMap<String,Object>(){{
    put("替换字段","替换参数"); //普通字段替换
    //网络图片
    put("替换图片字段",new PictureRenderData(700,300,".jpg",
    BytePictureUtils.getUrlBufferedImage("图片全路径")));
}});
  template.write(outputStream);
  outputStream.flush();
  outputStream.close();
  template.close();

PictureRenderData里面的参数表示:长,宽,图片后缀,图片路径(图片能在浏览器访问)

好了,这里就完成了多个word文档的合并以及模板的替换。我也是第一次搞这个,可能有很多不足之处。其实方法和思路还有很多,比如:可以使用apache原生的poi也能实现。还可以换种思路:先替换每个word参数后再进行合并。对于不同的业务代码可能会做不同的调整,只要能实现相关功能就好,希望对大家有帮助。

如有什么不足之处,望大家指出,相互讨论学习,一起进步。