使用POI操作office2007及以上word模板替换变量,变量被分隔成多个XWPFRuns导致替换不了的处理方案...

    我的方案可能不是最好的,却是我经过尝试觉得可用的方案,分享给大家。代码比较拙劣,希望大家指正。刚好在项目中有这个需求,因此我在网上也查了很多blog,大家的处理办法不外乎下边两个,我也是尝试过的,但都不尽如人意:

    word模板:

    98cba1d21d15964d59e4c32504b50b83324.jpg

    1、不要在word中直接输入参数,通过在文本中写好复制粘贴过来。

        经过实践证明某些字段确实可以,但是像我上面的模板中month_fd和month_ld这种还是被分隔到多个runs中,还有其它情况也会被分隔。

    2、将word另存为xml文件,在编辑器中将变量写进去,然后存为docx。

        这种方式最终结果是可以实现的。但是在xml中找非常费神且容易改错,另外如果文档过大,基本上编辑器就被卡死了。

 

经过上面的实践浪费了我很多时间,而且并解决不了问题,所以我就尝试自己想办法处理。方法其实也是非常简单,既然变量被分隔了,那么就可以通过代码合并,将分隔的内容合并回来,然后重新把变量设置进去。下边省略了“[”和“]”可能在文档中是普通文本,替换为非常特殊的字符就可以了。

public XWPFDocument generateDoc(String path,Map param){
 //创建文档对象
 XWPFDocument doc = new XWPFDocument(new FileInputstream(new File("filePath")));
 //获取所有段落
 List paragraphList = doc.getParagraphs();
 for(XWPFParagraph paragraph:paragraphList){
    //遍历获取段落中所有的runs
    List runs = paragraph.getRuns();
     //合并逻辑
    for(Integer i = 0; i < runs.size(); i++){
        String text0 = runs.get(i).getText(runs.get(i).getTextPosition());
       if(text0!=null && text0.startsWith("[")){
           //记录分隔符中间跨越的runs数量,用于字符串拼接和替换
          int num=0;
          int j = i+1;
          for(; j < runs.size(); j++){
              String text1 = runs.get(j).getText(runs.get(j).getTextPosition());
              if(text1!=null && text1.endsWith("]")){
                  num=j-i;
                  break;
              }
          }
          if(num!=0) {
              //num!=0说明找到了[]配对,需要替换
              StringBuilder newText = new StringBuilder();
              for (int s = i; s <= i+num; s++) {
                  String text2 = runs.get(s).getText(runs.get(s).getTextPosition());
                  newText.append(text2);
                  runs.get(s).setText(null, 0);
              }
              runs.get(i).setText(newText.toString(),0);

              //重新定义遍历位置,跳过设置为null的位置
              i=j+1;
          }
       }
    }

    //变量替换逻辑
    for(int i = 0; i < runs.size(); i++){
        XWPFRun run = runs.get(i);
        String text = run.getText(runs.get(i).getTextPosition());
        if(text != null){
            boolean isSetText = false;
            for (Map.Entry entry : param.entrySet()) {
                String key = entry.getKey();
                if(text.indexOf(key) != -1){
                    isSetText = true;
                    Object value = entry.getValue();
                    if (value instanceof String) {//文本替换
                        text = text.replace(key, value.toString());
                    } else if (value instanceof Map) {//图片替换
                        //从map中获取图片的宽、高、位置和描述信息,编写图片定义xml 放入                     
                    }
                }
            }
            if(isSetText){
                run.setText(text,0);
            }
        }
     }
 }
 return doc;
}

 

 

转载于:https://my.oschina.net/heguojun/blog/3082056

你可能感兴趣的:(使用POI操作office2007及以上word模板替换变量,变量被分隔成多个XWPFRuns导致替换不了的处理方案...)