poi 针对word模板内容替换 - homeSicker - 博客园

最近多了一个需求,需要对word模板内容进行替换,一开始用的是word03版的,替换起来比较简单,主要是range对像替换非常方便,而且可以保留替换前的字体样式。

复制代码; "复制代码")

1 InputStream is = new FileInputStream(srcFath); 2 OutputStream os = new FileOutputStream(tempFile); 3 XWPFDocument doc = new XWPFDocument(is); 4 Range range = doc.getRange(); 5 range.replaceText("${name}","aaa"); 6 doc.write(os); 7 is.close(); 8 os.flush(); 9 os.close();

复制代码; "复制代码")

最后看到word里包含了图片,需要同时保存一张png图片,对于jpg的图片是可以的,但是png的显示不出来,改为操作2007的文档,07版的没有了Range,使用XWPFParagraph和XWPFRun来操作。XWPFParagraph表示段落,有的word里有表格内容,需要使用XWPFTable来处理,与段落区分开来处理。

复制代码; "复制代码")

private void replaceText(XWPFDocument doc, Map<String, Object> params) {

      Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();  
      XWPFParagraph para; while (iterator.hasNext()) {  
         para = iterator.next(); this.replaceInPara(para, params);  
      }  
   } private  void replaceText(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); if (matcher.find()) { while ((matcher = matcher(runText)).find()) {  
                   runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));  
                }    
                para.removeRun(i); //重新插入run里内容格式可能与原来模板的格式不一致

para.insertNewRun(i).setText(runText);

            }  
         }  
      }  
   }

  private Matcher matcher(String str) {
    Pattern pattern = Pattern.compile("\$\{(.+?)\}", Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(str);
    return matcher;
  }

复制代码; "复制代码")

再次处理替换内容的格式问题,通过一个临时文件先保存替换模板变量后的文件,在与之前模板文档一起通过正则匹配出变量位置,由于替换变量时先删除再插入,所以位置是一致的。

复制代码; "复制代码")

private void setStyle(XWPFDocument doc,XWPFDocument tempdoc, Map<String, Object> params) {

      Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();  
      Iterator<XWPFParagraph> iterator2 = tempdoc.getParagraphsIterator();  
      XWPFParagraph para ;  
      XWPFParagraph para2; while (iterator.hasNext()) {  
         para = iterator.next();  
         para2 = iterator2.next(); this.styleInPara(para,para2, params);  
      }  
   } private  void setStyle(XWPFParagraph para, XWPFParagraph para2,Map<String, Object> params) {  
      List<XWPFRun> runs;  
      List<XWPFRun> runs2;  
      Matcher matcher; if (matcher(para.getParagraphText()).find()) {  
         runs = para.getRuns();  
         runs2 = para2.getRuns(); for (int i=0; i<runs.size(); i++) {  
            XWPFRun run = runs.get(i);  
            XWPFRun run2 = runs2.get(i);  
            String runText = run.toString();  
            matcher = matcher(runText); if (matcher.find()) { //按模板文件格式设置格式

run2.getCTR().setRPr(run.getCTR().getRPr());

            }  
         }  
      }  
   } 

复制代码; "复制代码")

按照原模板格式设置好替换后格式后显示正常。

ps:XWPFRun表示有相同属性的一段文本,所以模板里变量内容需要从左到右的顺序写,${userName},如果先写${},再添加内容,会拆分成几部分,不能正常使用


原网址: 访问
创建于: 2023-05-09 14:28:17
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论