2016-11-11 118 views
1

我正在編寫一個代碼來讀取.doc文件作爲模板,並在各種迭代後將數據寫入新的.doc文件。我的代碼似乎有一個簡單的問題,我無法弄清楚。Java Apache POI:從.doc文件讀取/寫入問題

下面是我寫的代碼,[我某處計算器基本骨架只。]

public class HWPFTest { 

    public static void main(String[] args) { 
     String inputFile = "F:\\docx\\input.doc"; 
     String outputFile = "F:\\docx\\output.doc"; 
     POIFSFileSystem fs = null; 

     try { 
       for (int i = 0; i < 3; i++) { 
        fs = new POIFSFileSystem(new FileInputStream(inputFile)); 
        HWPFDocument doc = new HWPFDocument(fs); 
        System.out.println("LOOOOOOOOOOOOP ----> " + i); 
        doc = replaceText(doc, "$count", String.valueOf(i)); 
        doc = replaceText(doc, "$filename", "FileName" + i); 
        doc = replaceText(doc, "$inputFile", "Input" + i); 
        doc = replaceText(doc, "$outputFile", "Output" + i); 
        doc = replaceText(doc, "$message", "Message" + i); 
        doc = replaceText(doc, "$snap", "Snapshot" + i); 
        saveWord(outputFile, doc); 
       } 
       System.out.println("DONE..."); 
     } 
     catch (FileNotFoundException e) { 
       e.printStackTrace(); 
     } catch (IOException e) { 
       e.printStackTrace(); 
     } 
    } 

    private static HWPFDocument replaceText(HWPFDocument doc, String findText, String replaceText) { 
     Range r1 = doc.getRange(); 
     for (int i = 0; i < r1.numSections(); ++i) { 
       Section s = r1.getSection(i); 
       for (int x = 0; x < s.numParagraphs(); x++) { 
        Paragraph p = s.getParagraph(x); 
        for (int z = 0; z < p.numCharacterRuns(); z++) { 
          CharacterRun run = p.getCharacterRun(z); 
          String text = run.text(); 
          if (text.contains(findText)) { 
           run.replaceText(findText, replaceText); 
           System.out.println("findText: " + findText + " replaceText: " + replaceText); 
          } 
        } 
       } 
     } 
     return doc; 
    } 


    private static void saveWord(String filePath, HWPFDocument doc) throws FileNotFoundException, IOException { 
     FileOutputStream out = null; 
     try { 
       // Add true to make the data append possible in output stream. 
       out = new FileOutputStream(filePath, true); 
       doc.write(out); 
       out.flush(); 
     } catch (Exception ex) { 
       ex.printStackTrace(); 
     } finally { 
       out.close(); 
     } 
    } 

}

代碼工作沒有任何問題。以下是input.doc的外觀: input.doc

成功運行後,還會生成output.doc。但問題是它只包含第一個循環的數據。

從理論上講,它應該包含所有3次迭代的數據,但它只包含第一個數據,然後就沒有任何數據。它在執行期間也不顯示任何錯誤/異常。我也確保outputstream將附加選項視爲true。

這是output.doc的外觀, output.doc

不知道,我在做什麼錯。

當我運行該程序,我可以在下面的輸出看,

LOOOOOOOOOOOOP ----> 0 findText: $count replaceText: 0 findText: $filename replaceText: FileName0 findText: $inputFile replaceText: Input0 findText: $outputFile replaceText: Output0 findText: $message replaceText: Message0 findText: $snap replaceText: Snapshot0 LOOOOOOOOOOOOP ----> 1 findText: $count replaceText: 1 findText: $filename replaceText: FileName1 findText: $inputFile replaceText: Input1 findText: $outputFile replaceText: Output1 findText: $message replaceText: Message1 findText: $snap replaceText: Snapshot1 LOOOOOOOOOOOOP ----> 2 findText: $count replaceText: 2 findText: $filename replaceText: FileName2 findText: $inputFile replaceText: Input2 findText: $outputFile replaceText: Output2 findText: $message replaceText: Message2 findText: $snap replaceText: Snapshot2 DONE...

正如我開始輸入文件作爲新的每次迭代。所以我會在迭代過程中找到所有$元素。只是它們不會被附加到最終文件中。

有人可以幫忙嗎?非常感謝。

回答

0

顯然和令人驚訝的,Apache的POI不具有附加到現有的Word文檔編寫任何方法。所以上述方法不起作用。

我也嘗試過Apache FileUtils,但它不保留word文檔的格式化。我也嘗試過docx4j,但只適用於docx文件,它的合併工具類是付費的。

還有另一個框架Aspose Words,它提供了更好的控制和靈活性。它允許您將內容追加到現有文檔中,限制爲1150個字符。但是對於我的要求而言,這太多了,因爲我的寫作不超過設定的限制。

所以我用它來實現我想要做的事情。終於成功了。

感謝您的幫助@D。 Krauchanka

1

您正在打開模板文件,更改內容並保存到「F:\ docx \ output.doc」。你每次覆蓋輸出文件3次。

在循環中準備字符串然後在文檔中只替換一次會好很多。你main方法是這樣的:

public static void main(String[] args) { 
     String inputFile = "F:\\docx\\input.doc"; 
     String outputFile = "F:\\docx\\output.doc"; 
     POIFSFileSystem fs = null; 

     String counts = ""; 

     try { 
      for (int i = 0; i < 3; i++) { 
       counts += String.valueOf(i) + "; "; 
      } 
      fs = new POIFSFileSystem(new FileInputStream(inputFile)); 
      HWPFDocument doc = new HWPFDocument(fs); 
      doc = replaceText(doc, "$count", counts); 
      saveWord(outputFile, doc); 
     } 
     catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
+0

我已經添加了上述問題的控制檯輸出,我在運行該程序時看到。它還表示$元素被發現並被每次迭代所取代。 – WebNoob

+0

是的,我有點不對)您打開您的模板文件,更改內容並保存到「F:\\ docx \\ output.doc」。你每次覆蓋輸出文件3次。所以,請嘗試我提供的答案。 –

+0

其實,我正在展示的內容是虛擬內容,爲了簡化,每個人都可以閱讀。實際內容將是帶有路徑的文件名,並且還將在文件名或文件路徑中包含特殊字符。所以如果我嘗試在字符串中添加它,它會因此而中斷。 我現在所擁有的完美作品。唯一的問題是我不知道POI中的任何方法會幫助我將所有迭代的內容附加到單個文件中。你是否知道可能有效的其他技術。 – WebNoob