java用poi實現對word讀取和修改操作(轉)
java程式設計要實現對word的操作沒有vb那種程式語言來得容易,得藉助一些開源元件,其中就包括jacob、poi等, 而poi應用得最為廣泛,對word2003和2007的讀和寫word操作都十分方便。它是Apache組織的一個專案,早在2001年就已經發布了第 一個版本,可以說是apache組織的一個老牌專案,到現在已經走過了10年光輝歷程,目前最新版本是3.8的beta版本。下面就以該版本來演示如何實 現對word進行讀取和改寫值操作。
1.下載
下載3.8beta4版本,請記得一定要下載該版本,其他版本讀取word模板並改寫內容生成新的檔案後,開啟新檔案時會提示“word無法讀取文件,文件可能損壞。”,見下圖
低版本poi生成word文件開啟時的錯誤
2.整合到專案
這一步很簡單,只要把下載後解壓得到的poi-3.8-beta4-20110826.jar和poi-scratchpad-3.8-beta4-20110826.jar兩個檔案複製到java web專案的lib目錄下就行了
3.製作word模板
把需要變動的值全部用程式碼來代替,例如你需要改變名稱的值,則可以在模板中用name來表示。詳細見附件中的doc檔案。
4.呼叫介面方法實現對word的讀寫操作
整個過程就是先讀取模板,然後修改內容,再重新生成新的文件儲存到本地或者輸出檔案流提供下載,下面分別是生成新文件和輸出檔案流兩種方式的程式碼片斷,詳細的程式碼請見下列程式碼中的readwriteWord()兩個過載方法。
==========================================================================
//======================生成新文件的方式::==========================
package work.tool;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.FieldsDocumentPart;
import org.apache.poi.hwpf.usermodel.Field;
import org.apache.poi.hwpf.usermodel.Fields;
import org.apache.poi.hwpf.usermodel.Range;
/**
* 實現java用poi實現對word讀取和修改操作
* @author fengcl
*
*/
public class ReadAndWriteDoc {
/**
* 實現對word讀取和修改操作
* @param filePath word模板路徑和名稱
* @param map 待填充的資料,從資料庫讀取
*/
public static void readwriteWord(String filePath, Map<String,String> map){
//讀取word模板
// String fileDir = new File(base.getFile(),"http://www.cnblogs.com/http://www.cnblogs.com/../doc/").getCanonicalPath();
FileInputStream in = null;
try {
in = new FileInputStream(new File(filePath));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
HWPFDocument hdt = null;
try {
hdt = new HWPFDocument(in);
} catch (IOException e1) {
e1.printStackTrace();
}
Fields fields = hdt.getFields();
Iterator<Field> it = fields.getFields(FieldsDocumentPart.MAIN).iterator();
while(it.hasNext()){
System.out.println(it.next().getType());
}
//讀取word文字內容
Range range = hdt.getRange();
System.out.println(range.text());
//替換文字內容
for (Map.Entry<String,String> entry: map.entrySet()) {
range.replaceText("$" + entry.getKey() + "$",entry.getValue());
}
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
String fileName = ""+System.currentTimeMillis();
fileName += ".doc";
FileOutputStream out = null;
try {
out = new FileOutputStream("E:\\test\\"+fileName,true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
hdt.write(ostream);
} catch (IOException e) {
e.printStackTrace();
}
//輸出位元組流
try {
out.write(ostream.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
ostream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//======================輸出檔案流下載方式:==========================
/**
* 實現對word讀取和修改操作
* @param response 響應,設定生成的檔案型別,檔案頭編碼方式和檔名,以及輸出
* @param filePath word模板路徑和名稱
* @param map 待填充的資料,從資料庫讀取
*/
public static void readwriteWord(HttpServletResponse response, String filePath, Map<String, String> map){
//讀取word模板檔案
// String fileDir = new File(base.getFile(),"http://www.cnblogs.com/http://www.cnblogs.com/../doc/").getCanonicalPath();
// FileInputStream in = new FileInputStream(new File(fileDir+"/laokboke.doc"));
FileInputStream in;
HWPFDocument hdt = null;
try {
in = new FileInputStream(new File(filePath));
hdt = new HWPFDocument(in);
} catch (Exception e1) {
e1.printStackTrace();
}
Fields fields = hdt.getFields();
Iterator<Field> it = fields.getFields(FieldsDocumentPart.MAIN).iterator();
while(it.hasNext()){
System.out.println(it.next().getType());
}
//替換讀取到的word模板內容的指定欄位
Range range = hdt.getRange();
for (Map.Entry<String,String> entry:map.entrySet()) {
range.replaceText("$" + entry.getKey() + "$",entry.getValue());
}
//輸出word內容檔案流,提供下載
response.reset();
response.setContentType("application/x-msdownload");
String fileName = ""+System.currentTimeMillis()+".doc";
response.addHeader("Content-Disposition", "attachment; filename="+fileName);
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
OutputStream servletOS = null;
try {
servletOS = response.getOutputStream();
hdt.write(ostream);
servletOS.write(ostream.toByteArray());
servletOS.flush();
servletOS.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}