2016-02-14 83 views
2

我正在使用Apache POI 3.13並試圖從給定的模板文件中搜索和替換文本,然後保存新生成的.docx。這裏是我的代碼:Java如何避免在搜索和替換Apache POI時覆蓋模板文件

public static void main(String[] args) throws InvalidFormatException, IOException { 
    String filePath = "Sample.docx"; 
    File outputfile = new File("SampleProcessed.docx"); 

    XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath)); 

    for (XWPFParagraph p : doc.getParagraphs()) { 
     List<XWPFRun> runs = p.getRuns(); 
     if (runs != null) { 
      for (XWPFRun r : runs) { 
       String text = r.getText(0); 
       if (text != null && text.contains("$VAR")) { 
        text = text.replace("$VAR", "JohnDoe"); 
        r.setText(text, 0); 
       } 
      } 
     } 
    } 

    doc.write(new FileOutputStream(outputfile)); 
    doc.close(); 
    System.out.println("Done"); 
    Desktop.getDesktop().open(outputfile); 
} 

這看起來很簡單,但是當我運行此代碼,「Sample.docx」的文件也被替換。最後,我有兩個具有相同內容的文檔。

這是POI的正常行爲嗎?我認爲打開文檔只會將其加載到內存中,然後執行'doc.write(OutputStream);'會將其刷新到磁盤。

我試圖寫入相同的'文件路徑',但正如所料,它會引發異常,因爲我試圖寫入當前打開的文件。

唯一有效的工作是當我先複製模板文件並改爲使用該副本。但是現在,我有3個文件,第一個是原始模板「Sample.docx」,其餘2個文件的內容相同(SampleProcessed.docx和SampleProcessedOut.docx)。

它的工作,但它是很浪費。有什麼辦法嗎?我做錯了什麼,也許我打開錯誤的文字?

回答

4

由於您使用

XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath)); 

創建XWPFDocument,一個OPCPackagefilePathREAD_WRITE模式打開。如果這將被關閉,它也將被保存。見https://poi.apache.org/apidocs/org/apache/poi/openxml4j/opc/OPCPackage.html#close%28%29

OPCPackage將被關閉,而XWPFDocument將被關閉。

但是,爲什麼你這樣做呢?爲什麼不是

XWPFDocument doc = new XWPFDocument(new FileInputStream(filePath)); 

與此XWPFDocument將在內存中創建只有一個新的OPCPackage沒有關係的文件。

+0

這工作!謝謝!我錯過了。對不起,我應該事先閱讀文檔。我認爲OPCPackage是打開.docx文件的唯一方法。再次感謝! – yev

+0

還有一個open()的版本,它有一個參數PackageAccess,您可以在其中指定READ作爲開放模式,從而避免寫回數據,請參閱https://poi.apache.org/apidocs/org/ apache/poi/openxml4j/opc/OPCPackage.html#open(java.io.File,%20org.apache.poi.openxml4j.opc.PackageAccess) – centic

+0

@centic:你試過這個嗎?如果OPCPackage被打開,你將如何改變'Run'中的文本? –