2011-12-06 76 views
1

我正在使用apache POI 3.7。我正在嘗試替換word文檔(docx)中表格列的值。但是,我所做的是不斷追加文檔中當前值的值。但是,如果表列值爲空,它將放置該值。你能給我一些想法如何解決這個問題。以下是我迄今爲止所做的代碼。替換Apache POI中的表列值

在此先感謝。

package test.doc; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.util.List; 

import org.apache.poi.xwpf.usermodel.XWPFDocument; 
import org.apache.poi.xwpf.usermodel.XWPFParagraph; 
import org.apache.poi.xwpf.usermodel.XWPFTable; 
import org.apache.poi.xwpf.usermodel.XWPFTableCell; 
import org.apache.poi.xwpf.usermodel.XWPFTableRow; 

public class POIDocXTableTest { 

    public static void main(String[] args)throws IOException { 
     String fileName = "C:\\Test.docx"; 
     InputStream fis = new FileInputStream(fileName); 
     XWPFDocument document = new XWPFDocument(fis); 
     List<XWPFParagraph> paragraphs = document.getParagraphs(); 

     for (int x=0; x<paragraphs.size();x++) 
     { 
      XWPFParagraph paragraph = paragraphs.get(x); 
      System.out.println(paragraph.getParagraphText()); 
     } 
     List<XWPFTable> tables = document.getTables(); 
     for (int x=0; x<tables.size();x++) 
     { 
      XWPFTable table = tables.get(x); 
      List<XWPFTableRow> tableRows = table.getRows(); 
      tableRows.remove(x); 
      for (int r=0; r<tableRows.size();r++) 
      { 
       System.out.println("Row "+ (r+1)+ ":"); 
       XWPFTableRow tableRow = tableRows.get(r); 
       List<XWPFTableCell> tableCells = tableRow.getTableCells(); 
       for (int c=0; c<tableCells.size();c++) 
       { 
        System.out.print("Column "+ (c+1)+ ": "); 
        XWPFTableCell tableCell = tableCells.get(c); 
        //tableCell.setText("TAE"); 
        String tableCellVal = tableCell.getText(); 
        if ((c+1)==2){ 
         if (tableCellVal!=null){ 
          if (tableCellVal.length()>0){ 
           char c1 = tableCellVal.charAt(0); 
           String s2 = "-TEST"; 
           char c2 = s2.charAt(0); 
           String test = tableCell.getText().replace(tableCellVal,s2); 
           tableCell.setText(test); 
          }else{ 
           //tableCell.setText("NULL"); 
          } 
         } 
        } 
        System.out.println("tableCell.getText(" + (c) + "):" + tableCellVal); 
       } 
      } 
      System.out.println("\n"); 
     } 
     OutputStream out = new FileOutputStream(fileName); 
     document.write(out); 
     out.close(); 
    } 
} 
+0

您是否嘗試過POI 3.8 beta 4? (或者甚至更好的是最近一次的夜間製作?) – Gagravarr

+0

感謝您的回覆。我試圖使用相同的代碼,但它仍然追加值的使用Apache POI 3.8.4(最新版本)。我找到了替換的鏈接,但它適用於段落。任何人都可以提供一些關於如何在表格單元格中做這個的想法? [鏈接] http://apache-poi.1045710.n5.nabble.com/Embed-string-data-to-docx-file-in-java-td3287560.html [鏈接] – jamojo

+0

謝謝你的答案,但它似乎在嘗試替換段落中的文本時它不起作用。因此,我做了這個危險的修改。感謝您的意見:\t \t \t \t p.removeRun(i); { XWPFRun rB4 = rs.get(i-1); String textB4 = rB4.getText(0); textB4 = StringUtils.remove(textB4,searchValue); rB4.setText(textB4); } – hamzali

回答

3

好了,我已經做了類似的東西,以取代由指定的字一個字模板痕跡...:

public DotxTemplateFiller() { 
    String filename = "/poi/ls_Template_modern_de.dotx"; 
    String outputPath = "/poi/output/output" + new Date().getTime() 
      + ".dotx"; 
    OutputStream out = null; 
    try { 
     File file = new File(filename); 
     XWPFDocument template = new XWPFDocument(new FileInputStream(file)); 

     List<XWPFParagraph> xwpfParagraphs = template.getParagraphs(); 
     replaceInParagraphs(xwpfParagraphs); 

     List<XWPFTable> tables = template.getTables(); 
     for (XWPFTable xwpfTable : tables) { 
      List<XWPFTableRow> tableRows = xwpfTable.getRows(); 
      for (XWPFTableRow xwpfTableRow : tableRows) { 
       List<XWPFTableCell> tableCells = xwpfTableRow 
         .getTableCells(); 
       for (XWPFTableCell xwpfTableCell : tableCells) { 
        xwpfParagraphs = xwpfTableCell.getParagraphs(); 
        replaceInParagraphs(xwpfParagraphs); 
       } 
      } 
     } 

     out = new FileOutputStream(new File(outputPath)); 
     template.write(out); 
     out.flush(); 
     out.close(); 
     //System.exit(0); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     if (out != null) { 
      try { 
       out.close(); 
      } catch (IOException e) { 
       // nothing to do .... 
      } 
     } 
    } 
} 

/** 
* @param xwpfParagraphs 
*/ 
private void replaceInParagraphs(List<XWPFParagraph> xwpfParagraphs) { 
    for (XWPFParagraph xwpfParagraph : xwpfParagraphs) { 
     List<XWPFRun> xwpfRuns = xwpfParagraph.getRuns(); 
     for (XWPFRun xwpfRun : xwpfRuns) { 
      String xwpfRunText = xwpfRun.getText(xwpfRun 
        .getTextPosition()); 
      for (Map.Entry<String, String> entry : replacements 
        .entrySet()) { 
       if (xwpfRunText != null 
         && xwpfRunText.contains(entry.getKey())) { 
        xwpfRunText = xwpfRunText.replaceAll(
          entry.getKey(), entry.getValue()); 
       } 
      } 
      xwpfRun.setText(xwpfRunText, 0); 
     } 
    } 
} 

public static void main(String[] args) { 
    new DotxTemplateFiller(); 
} 

首先我是做定期的段落在MS Word模板和比表格單元格中的段落要多。 希望它對你有所幫助,我希望我能理解你的問題... :-)

祝你好運。

+0

嗨,謝謝你的例子。 是否可以在特定位置替換/插入圖像,如果可能請給我解決方案。 – softmage99

5

防止段落樣式和找到不同風格的搜索字符串最好的解決方法是這樣的方法:

private long replaceInParagraphs(Map<String, String> replacements, List<XWPFParagraph> xwpfParagraphs) { 
    long count = 0; 
    for (XWPFParagraph paragraph : xwpfParagraphs) { 
     List<XWPFRun> runs = paragraph.getRuns(); 

     for (Map.Entry<String, String> replPair : replacements.entrySet()) {  
     String find = replPair.getKey(); 
     String repl = replPair.getValue(); 
     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; 
    } 

此方法適用於搜索字符串跨越一個以上的運行。被替換的部分從第一次找到的Run中獲取樣式。

+0

它只適用於表格內的段落..它不適用於文檔中的段落...您能否告訴我解決方案 – Anand

+0

我對整個文檔(包括頁眉和頁腳)使用此方法。通常它應該可以工作,但是您需要使用不同部分的段落結果調用此方法。 – Josh

+0

它不適用於文本框中編寫的文本..任何想法如何使它工作? – Anand