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();
  }
}
目录
相关文章
|
21天前
|
Java API Apache
Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
【10月更文挑战第29天】Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
89 5
|
3月前
|
开发框架 前端开发 JavaScript
利用Aspose.Word对Word文件添加印章处理以及实现业务数据的替换处理
利用Aspose.Word对Word文件添加印章处理以及实现业务数据的替换处理
|
6月前
查看word文档的修改痕迹
查看word文档的修改痕迹
42 0
|
6月前
|
C# 开发工具 数据安全/隐私保护
C#实现基于Word保护性模板文件的修改
C#实现基于Word保护性模板文件的修改
|
6月前
|
机器学习/深度学习 定位技术 数据格式
Python对大量表格文件加以数据截取、逐行求差、跨文件合并等处理的方法
Python对大量表格文件加以数据截取、逐行求差、跨文件合并等处理的方法
133 1
|
6月前
|
PHP Python
基于Python中docx与docxcompose批量合并多个Word文档文件并逐一添加分页符
基于Python中docx与docxcompose批量合并多个Word文档文件并逐一添加分页符
202 1
|
C语言
【C 语言】文件操作 ( 配置文件读写 | 写出或更新配置文件 | 逐行遍历文件文本数据 | 获取文件中的文本行 | 查询文本行数据 | 追加文件数据 | 使用占位符方式拼接字符串 )
【C 语言】文件操作 ( 配置文件读写 | 写出或更新配置文件 | 逐行遍历文件文本数据 | 获取文件中的文本行 | 查询文本行数据 | 追加文件数据 | 使用占位符方式拼接字符串 )
262 0
|
索引 Python
【VBA脚本】提取word文档中所有批注的信息和待解决状态
【VBA脚本】提取word文档中所有批注的信息和待解决状态
257 0
【VBA脚本】提取word文档中所有批注的信息和待解决状态
|
Java
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
255 0
编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中
|
Java
编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内
编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内
289 0
编写Java程序,在硬盘中选取一个 txt 文件,读取该文档的内容后,追加一段文字“[ 来自新华社 ]”,保存到一个新的 txt 文件内