POI批量替换world文档XWPFParagraph.getRuns 出现分段混乱

简介: POI批量替换world文档XWPFParagraph.getRuns 出现分段混乱

问题:在操作POI替换world时发现getRuns将我们预设的${product}自动切换成了

  ${product, }]
${product  }
成了两个部分

解决方法一。(未尝试)

强制把List中的内容合并成一个字符串,替换内容后,把段落中的XWPFRun全部remove掉,然后新建一个含有替换后内容的XPWFRun,并赋给当前段落。

解决方法二.

请用复制粘贴把你的${product}添加进world文档里面即可解决,不要手打 目前发现复制粘贴是没有问题的,感觉像是poi的一个bug不知道立贴为证。

注意:${这里尽量不要存中文,否在还出现上面情况}

下面上代码:

public class WorldUtil {
    public static String doc2String2() {
      try {
        WorldUtil wd = new WorldUtil();
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("reportDate", "2014-02-28");
/*        params.put("appleAmt", "100.00");
        params.put("bananaAmt", "200.00");
        params.put("totalAmt", "300.00");*/
        String filePath = "d:\\1.docx";
        InputStream is = new FileInputStream(filePath);
        XWPFDocument doc = new XWPFDocument(is);
        //替换段落里面的变量  
        wd.replaceInPara(doc, params);
        //替换表格里面的变量  
        wd.replaceInTable(doc, params);
        OutputStream os = new FileOutputStream("d:\\sample.docx");
        doc.write(os);
        wd.close(os);
        wd.close(is);
      } catch (Exception e) {
        // TODO: handle exception
      }
      return null;
    }
      /**
       * 读取doc文件内容
       * @param file 想要读取的文件对象
       * @return 返回文件内容
       */
      public static String doc2String(){
        try {
          FileInputStream stream = new FileInputStream("d://1.docx");
          XWPFDocument doc = new XWPFDocument(stream);// 创建Word文件
          for(XWPFParagraph p : doc.getParagraphs())//遍历段落
          {
            System.out.println(p.getParagraphText());
          }
          for(XWPFTable table : doc.getTables())//遍历表格
          {
             for(XWPFTableRow row : table.getRows())
             {
               for(XWPFTableCell cell : row.getTableCells())
               {
                 System.out.println(cell.getText());
               }
             }
          }
          FileOutputStream out = new FileOutputStream("d://sample.docx");
          doc.write(out);
          out.close();
          stream.close();
      } catch (Exception e) {
        // TODO: handle exception
      }
      return null;
      }
      /** 
       * 替换段落里面的变量 
       * @param doc 要替换的文档 
       * @param params 参数 
       */  
      private void replaceInPara(XWPFDocument doc, Map<String, Object> params) {  
         Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();  
         XWPFParagraph para;  
         while (iterator.hasNext()) {  
            para = iterator.next();  
            this.replaceInPara(para, params);  
         }  
      }  
      /** 
       * 替换段落里面的变量 
       * @param para 要替换的段落 
       * @param params 参数 
       */  
      private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {  
         List<XWPFRun> runs;  
         Matcher matcher;  
         if (matcher(para.getParagraphText()).find()) {  
            runs = para.getRuns();  
            for (int i=0; i<runs.size(); i++) {
               XWPFRun run = runs.get(i);  
               String runText = run.toString();  
               matcher = matcher(runText);  
               System.out.println(runText);
               if (matcher.find()) { 
                 System.out.println("进1");
                   while ((matcher = this.matcher(runText)).find()) {  
                      runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));  
                   }  
                   //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,  
                   //所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。  
                   para.removeRun(i);  
                   para.insertNewRun(i).setText(runText);  
               }  
            }  
         }  
      }  
      /** 
       * 替换表格里面的变量 
       * @param doc 要替换的文档 
       * @param params 参数 
       */  
      private void replaceInTable(XWPFDocument doc, Map<String, Object> params) {  
         Iterator<XWPFTable> iterator = doc.getTablesIterator();  
         XWPFTable table;  
         List<XWPFTableRow> rows;  
         List<XWPFTableCell> cells;  
         List<XWPFParagraph> paras;  
         while (iterator.hasNext()) {  
            table = iterator.next();  
            rows = table.getRows();  
            for (XWPFTableRow row : rows) {  
               cells = row.getTableCells();  
               for (XWPFTableCell cell : cells) {  
                   paras = cell.getParagraphs();  
                   for (XWPFParagraph para : paras) {  
                      this.replaceInPara(para, params);  
                   }  
               }  
            }  
         }  
      }  
      /** 
       * 正则匹配字符串 
       * @param str 
       * @return 
       */  
      private Matcher matcher(String str) {  
         Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);  
         Matcher matcher = pattern.matcher(str); 
         return matcher;  
      }  
      /** 
       * 关闭输入流 
       * @param is 
       */  
      private void close(InputStream is) {  
         if (is != null) {  
            try {  
               is.close();  
            } catch (IOException e) {  
               e.printStackTrace();  
            }  
         }  
      }  
      /** 
       * 关闭输出流 
       * @param os 
       */  
      private void close(OutputStream os) {  
         if (os != null) {  
            try {  
               os.close();  
            } catch (IOException e) {  
               e.printStackTrace();  
            }  
         }  
      }    
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    //doc2String();
    doc2String2();
  }
}
目录
相关文章
|
1月前
|
Java API Apache
Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
【10月更文挑战第29天】Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
122 5
|
3月前
常用文本格式标签例子
常用文本格式标签例子。
37 3
|
7月前
【word】论文、报告:①插入图表题注,交叉引用②快速插入图表目录③删改后一键更新
【word】论文、报告:①插入图表题注,交叉引用②快速插入图表目录③删改后一键更新
754 0
|
7月前
|
机器学习/深度学习 定位技术 数据格式
Python对大量表格文件加以数据截取、逐行求差、跨文件合并等处理的方法
Python对大量表格文件加以数据截取、逐行求差、跨文件合并等处理的方法
138 1
|
7月前
|
PHP Python
基于Python中docx与docxcompose批量合并多个Word文档文件并逐一添加分页符
基于Python中docx与docxcompose批量合并多个Word文档文件并逐一添加分页符
210 1
|
C语言
【C 语言】文件操作 ( 配置文件读写 | 写出或更新配置文件 | 逐行遍历文件文本数据 | 获取文件中的文本行 | 查询文本行数据 | 追加文件数据 | 使用占位符方式拼接字符串 )
【C 语言】文件操作 ( 配置文件读写 | 写出或更新配置文件 | 逐行遍历文件文本数据 | 获取文件中的文本行 | 查询文本行数据 | 追加文件数据 | 使用占位符方式拼接字符串 )
262 0
|
Java
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
258 0
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
|
前端开发
评论列表案例-演示艾特符号替代相对路径的好处
评论列表案例-演示艾特符号替代相对路径的好处
|
Windows
怎么去掉文章或产品介绍中的垃圾代码?怎么过滤这些垃圾代码?
一般从网页或从WORD中复制粘贴时,会带来一些垃圾代码,有可能会导致显示异常,例如如下样例中的灰色方框,无法直接删掉,怎么办? 小技巧:如点右键粘贴不能用,可以用粘贴快捷键:Ctrl+V 1、删掉方法如下:如下图,先点HTML图标,然后 就可以看到下面的代码了,直接删掉就行了。
1261 0
|
Java 移动开发
java正则表达式移除网页中注释代码
/** * 移除网页中注释掉的代码 * * @param str * @return */ public static String removedisablecode(String str) { Pattern pattern = Pattern.
1247 0