使用poi-tl嵌套方法将一个Word模板标签合并到另外一个Word模板操作没有效果

念生kz
  • 18

一、问题描述

现在我手边有两个word模板文档,分别是:
base.docx
image

paragraph.docx
image

我想要将paragraph.docx渲染后的内容,合并到base.docx中去,但是参考了官方示例后没有成功


二、问题出现的环境背景及自己尝试过哪些方法

外部环境

Maven依赖如下:

<dependencies>
  <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
 <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad -->
 <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>4.1.2</version>
  </dependency>
  <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-examples</artifactId>
    <version>4.1.2</version>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
  </dependency>
  <!-- POI-tl -->
 <dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.9.1</version>
  </dependency>
  <!-- slf4j报错配置项 -->
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-nop</artifactId>
    <version>1.7.2</version>
  </dependency>
  <!-- Spring Expression Language -->
 <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
    <version>4.3.6.RELEASE</version>
  </dependency>
</dependencies>

回到代码层面

控制台没有报错,也没有任何报错信息,于是初步判断:

1.非文件IO流问题
读取模板文件没有报错,两个模板文件都正确读取

2.写入数据非空
写入paragraph.docx文档中的wordParagraphData数据非空,经过调试后可知
image

3.模板标签没有错误
首先根据使用经验来看,如果是将poi-tl标签从语法层面上写错,base.docx应该会把paragraph.docx文件中的标签显示出来,或者直接在控制台报错;然后我比照了Java属性与标签,也参考了示例代码,发现都能对应上并无问题。


三、相关代码

首先是提供两个模型类:

WordData.java

 public class WordData {
  private WordHomeData wordHomeData;
 
  private DocxRenderData wordParagraphData;
 
  public WordHomeData getWordHomeData() {
  return wordHomeData;
  }
 
  public void setWordHomeData(WordHomeData wordHomeData) {
  this.wordHomeData = wordHomeData;
  }
 
  public DocxRenderData getWordParagraphData() {
  return wordParagraphData;
  }
 
  public void setWordParagraphData(DocxRenderData wordParagraphData) {
  this.wordParagraphData = wordParagraphData;
  }
 
  @Override
  public String toString() {
  return "WordData{" +
  "wordHomeData=" + wordHomeData +
  ", wordParagraphData=" + wordParagraphData +
  '}';
  }
 }

WordParagraphData.java

 public class WordParagraphData {
  /**
  * 段落级别:标题级别
  */
  private  int titleLevel;
 
  /**
  * 段落信息
  */
  private  String text;
 
  public int getTitleLevel() {
  return titleLevel;
  }
 
  public void setTitleLevel(int titleLevel) {
  this.titleLevel = titleLevel;
  }
 
  public String getText() {
  return text;
  }
 
  public void setText(String text) {
  this.text = text;
  }
 
  @Override
  public String toString() {
  return "WordParagraphData{" +
  "titleLevel=" + titleLevel +
  ", text='" + text + ''' +
  '}';
  }
 }

其中WordData对应着base.docx,WordParagraphData对应着paragraph.docx。


现在我想要将paragraph.docx中的渲染结果合并到base.docx中,合并流程大致如下:

image


为了达到这种效果,我参考了官方示例,使用到了嵌套的方法,相关代码如下:

  public static void writeToWord(WordModle wordModle) {
  TheameData theameData = init(wordModle);
  WordData wordData = theameData.getWordData();
  List<WordParagraphData> wordParagraphData = theameData.getWordParagraphDataList();
 
  wordData.setWordParagraphData(Includes.ofLocal("src/模板集合/paragraph.docx").setRenderModel(wordParagraphData).create());
 
 
  XWPFTemplate.compile("E:\\base.docx").render(wordData).writeToFile("output.docx");
  }


四、你期待的结果是什么?实际看到的错误信息又是什么?

如果将paragraph.docx渲染后的内容成功合并到base.docx中去
预期设想如下:
image

但是结果实际上这样的:
image

回复
阅读 1.5k
1 个回答
距离这个问题正式发出已经过去了一周多,我也找到了问题发生原因并解决,不过因为那几天sf问题编辑有问题,无法对问题进行编辑,于是导致了问题更新的迟缓。

只能说我真是太一根筋了,一直在纠结是不是自己代码有误、是不是模板文件的问题,结果刚才排查到,居然是:
地!址!写!错!了!


原本我是这样的项目布局:

|-src
|-模板文件

然后我代码使用的是这样的地址来读取文件的:

wordData.setWordParagraphData(Includes.ofLocal("src/模板集合/paragraph.docx").setRenderModel(wordParagraphData).create());

读的到才有鬼啊!!


正确的操作应该是,将项目结构改成这样:

|-src
    |-main
        |-java
            |-resource
                |-模板集合

然后将java路径进行修改:

 wordData.setWordParagraphData(
    Includes.ofLocal("src/main/resource/模板集合/paragraph.docx").setRenderModel(wordParagraphData).create());
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏