我有一個 Word 檔案(docx);我想對該檔案進行更改并將結果另存為另一個檔案,將原始檔案保留在原處。我有以下代碼說明我當前的問題:
package sandbox.word.doccopy;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
public class CopyTest
{
public static void main(String[] args) throws Exception
{
String sourceFilename = "CopyTestSource.docx";
String destinationFilename = "CopyTestResult.docx";
CopyTest docCopy = new CopyTest();
docCopy.copyTesting(sourceFilename, destinationFilename);
System.out.println("done");
}
public void copyTesting(String source, String destination)
throws IOException, InvalidFormatException
{
XWPFDocument doc = new XWPFDocument(OPCPackage.open(source));
// for each paragraph that has runs,
// put an exclamation at the end of the first run.
for (XWPFParagraph par : doc.getParagraphs())
{
List<XWPFRun> runs = par.getRuns();
if (runs.size() > 0)
{ XWPFRun run = par.getRuns().get(0);
String text = run.getText(0);
text = text "!";
run.setText(text, 0);
}
}
// FileOutputStream fos = new FileOutputStream(destination);
// doc.write(fos);
// fos.close();
doc.close();
}
}
我運行了三種方法,更改類檔案底部的注釋行。如您所見,有三行代碼使用目標檔案名創建檔案輸出流、寫入并關閉它,還有一行代碼只關閉當前檔案。
如果我注釋掉 3 行并保留 1 行,則不會向當前檔案寫入任何更改(當然,也不會創建副本檔案)。
如果我不注釋所有 4 行,則會創建帶有更改的副本檔案,并且更改也會寫入源檔案。
如果我注釋掉第 4 行,我會得到一個包含更改的目標檔案,而源檔案保持不變。
最后一個是我想要的,我可以撰寫我的代碼來做到這一點。但我希望在更改后關閉檔案會更改或不更改它,并且更改它不會取決于我是否已將更改寫入另一個檔案。
任何人都可以對此有所了解嗎?
uj5u.com熱心網友回復:
罪魁禍首是:XWPFDocument doc = new XWPFDocument(OPCPackage.open(source));
. 特別是這個:OPCPackage.open(source)
。
雖然靜態 OPCPackage open(java.lang.String path)從具有讀/寫權限OPCPackage
的檔案路徑的基礎檔案中打開。path
此外,它直接連接到底層檔案。這節省了一些記憶體,但也有缺點,正如您現在將看到的。
所有更改XWPFDocument
都在其中進行,OPCPackage
但首先在隨機存取存盤器中進行。
在呼叫doc.write
POIXMLDocument.write (java.io.OutputStream stream)時,首先OPCPackage
更新底層。然后更改OPCPackage
通過給定的保存在目標檔案中OutputStream stream
。因此,如果不呼叫doc.write
,檔案中不會發生任何變化,而只會保留在隨機存取存盤器中。
然后同時doc.close()
呼叫OPCPackage.close。這將關閉打開的可寫包并保存其內容。由于OPCPackage
直接連接到底層檔案,它會將內容保存到該檔案中。這就是為什么更改也會寫入源檔案的原因。
這應該可以解釋您的觀察結果。
XWPFDocument
還提供了建構式
XWPFDocument (java.io.InputStream is)。這在內部呼叫OPCPackage.open(java.io.InputStream in)。這OPCPackage
從InputStream
. 然后OPCPackage
僅在隨機存取存盤器中并且獨立于源檔案。這會使用更多的記憶體,因為整體OPCPackage
需要在隨機存取記憶體中,但OPCPackage.close
不會導致源檔案的更改。
所以我要做的是:
...
XWPFDocument doc = new XWPFDocument(new FileInputStream(source));
...
FileOutputStream fos = new FileOutputStream(destination);
doc.write(fos);
fos.close();
doc.close();
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/433421.html
標籤:爪哇 apache-poi
上一篇:KafkaStreams:java.lang.IllegalArgumentException:VoidDeserializer的資料應該為空