【问题标题】:Replacing text in .docx with a table, using Apache POI (Java)使用 Apache POI (Java) 将 .docx 中的文本替换为表格
【发布时间】:2019-01-07 16:34:29
【问题描述】:

所以,我正在尝试使用 Apache POI(版本 3.15)在 .docx 文件中的某个点插入一个表。我可以使用下面的代码创建它。这会将我需要的表格扔到文档的末尾。 (如果这是多余的,我很抱歉!试图提供尽可能多的信息!)

    /* Creates table for the questions */
private XWPFTable createMainTable(XWPFDocument doc, ArrayList<String> qs, ArrayList<String> avgScores, ArrayList<String> favScores){ 
    XWPFTable table = doc.createTable();

    int currRow = 0;
    for(String q : qs){
        XWPFTableRow curRow = table.getRow(currRow);
        if(currRow == 0){
            curRow.getCell(0).setText("Question");
        }else{
        curRow.getCell(0).setText(q);
        }
        if(currRow < qs.size()-1){
            table.createRow();
            currRow++;
        }else{
            currRow++;
        }
    }
    currRow = 0;
    for(String avg : avgScores){
        XWPFTableRow curRow = table.getRow(currRow);
        curRow.addNewTableCell();
        if(currRow == 0){
            curRow.getCell(1).setText(" Average Score ");
        }else{
            curRow.getCell(1).setText(avg);
        }
        currRow++;    
    }
    currRow = 0;
    for(String fav : favScores){
        XWPFTableRow curRow = table.getRow(currRow);
        curRow.addNewTableCell();
        if(currRow == 0){
            curRow.getCell(2).setText(" Favorable Score ");
        }else{
            curRow.getCell(2).setText(fav);
        }
        currRow++;
    }
    return table;
}

现在,为了替换文档中的其余文本,我使用以下方法:

    /* Replace text in the document */
private long replaceText(ArrayList<String> comments, String targ, XWPFDocument doc) {
long count = 0;
for (XWPFParagraph paragraph : doc.getParagraphs()) {
  List<XWPFRun> runs = paragraph.getRuns();

    StringBuilder sb = new StringBuilder();
    for (String c : comments){
        sb.append(c);
        sb.append("|");
    }
    String find = targ;
    String repl = sb.toString();
    TextSegement found = paragraph.searchText(find, new PositionInParagraph());
    if ( found != null ) {
      count++;
      if ( found.getBeginRun() == found.getEndRun() ) {
        // whole search string is in one Run
        XWPFRun run = runs.get(found.getBeginRun());
        String runText = run.getText(run.getTextPosition());
        String replaced = runText.replace(find, repl);
        run.setText(replaced, 0);
      } else {
        // The search string spans over more than one Run
        // Put the Strings together
        StringBuilder b = new StringBuilder();
        for (int runPos = found.getBeginRun(); runPos <= found.getEndRun(); runPos++) {
          XWPFRun run = runs.get(runPos);
          b.append(run.getText(run.getTextPosition()));
        }                       
        String connectedRuns = b.toString();
        String replaced = connectedRuns.replace(find, repl);

        // The first Run receives the replaced String of all connected Runs
        XWPFRun partOne = runs.get(found.getBeginRun());
        partOne.setText(replaced, 0);
        // Removing the text in the other Runs.
        for (int runPos = found.getBeginRun()+1; runPos <= found.getEndRun(); runPos++) {
          XWPFRun partNext = runs.get(runPos);
          partNext.setText("", 0);
        }                          
      }
    }     
}
return count;}  

第二种方法的作用是在文档中找到某个关键字,并将其替换为字符串。现在,它传递了一个 ArrayList,但是当我尝试不同的事情时,情况发生了变化。我能够获得要打印的表的内存地址(通过将输入更改为 XWPFTable),但这是我所能得到的。我觉得我错过了一些愚蠢的东西,但我就是想不通。

【问题讨论】:

  • stackoverflow.com/questions/39572996/…。方法:在文档中找到你的段落。然后从该段的org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP 中获取org.apache.xmlbeans.XmlCursor。然后插入由该光标定位的表格。
  • 非常感谢,我不知道怎么在我的所有搜索中都没有找到那个线程!

标签: java apache-poi


【解决方案1】:

非常感谢Axel,我能够得到想要的结果!我稍微改变了我的创建方法,并传递给它一个空表来填充。然后,使用 Axel 建议的光标,它现在找到目标字符串 ("%TABLE"),并将其替换为表格,完全符合我的需要。

    /* Replaces table */
private long replaceTable(XWPFDocument doc, ArrayList<String> qs, ArrayList<String> avgScores, ArrayList<String> favScores) {
    XWPFTable table = null;
    long count = 0;
     for (XWPFParagraph paragraph : doc.getParagraphs()) {
       List<XWPFRun> runs = paragraph.getRuns();
         String find = "%TABLE";
         TextSegement found = paragraph.searchText(find, new PositionInParagraph());
         if ( found != null ) {
           count++;
           if ( found.getBeginRun() == found.getEndRun() ) {
             // whole search string is in one Run
             XmlCursor cursor = paragraph.getCTP().newCursor();
             table = doc.insertNewTbl(cursor);
             XWPFRun run = runs.get(found.getBeginRun());
             // Clear the "%TABLE" from doc
            String runText = run.getText(run.getTextPosition());
            String replaced = runText.replace(find, "");
            run.setText(replaced, 0);
           } else {
             // The search string spans over more than one Run
             StringBuilder b = new StringBuilder();
             for (int runPos = found.getBeginRun(); runPos <= found.getEndRun(); runPos++) {
               XWPFRun run = runs.get(runPos);
               b.append(run.getText(run.getTextPosition()));
             }                       
             String connectedRuns = b.toString();
             XmlCursor cursor = paragraph.getCTP().newCursor();
             table = doc.insertNewTbl(cursor);
             String replaced = connectedRuns.replace(find, ""); // Clear search text

             // The first Run receives the replaced String of all connected Runs
             XWPFRun partOne = runs.get(found.getBeginRun());
             partOne.setText(replaced, 0);
             // Removing the text in the other Runs.
             for (int runPos = found.getBeginRun()+1; runPos <= found.getEndRun(); runPos++) {
               XWPFRun partNext = runs.get(runPos);
               partNext.setText("", 0);
             }
           }
         }     
     }
     fillTable(table, qs, avgScores, favScores);
     return count;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    相关资源
    最近更新 更多