java讀取word文檔時,雖然網上介紹了很多插件poi、java2Word、jacob、itext等等,poi無法讀取格式(新的API估計行好像還在處於研發階段,不太穩定,做項目不太敢用);java2Word、jacob容易報錯找不到注冊,比較詭異,我曾經在不同的機器上試過,操作方法完全一致,有的機器不報錯,有的報錯,去他們論壇找高人解決也說不出原因,項目部署用它有點玄;itxt好像寫很方便但是我查了好久資料沒有見到過關於讀的好辦法。經過一番選擇還是折中點采用rtf最好,畢竟rtf是開源格式,不需要借助任何插件,只需基本IO操作外加編碼轉換即可。rtf格式文件表面看來和doc沒啥區別,都可以用word打開,各種格式都可以設定。
----- 實現的功能:讀取rtf模板內容(格式和文本內容),替換變化部分,形成新的rtf文檔。
----- 實現思路:模板中固定部分手動輸入,變化的部分用$info$表示,只需替換$info$即可。
1、采用字節的形式讀取rtf模板內容
2、將可變的內容字符串轉為rtf編碼
3、替換原文中的可變部分,形成新的rtf文檔
主要程序如下:
/**
* 將制定的字符串轉換為rtf編碼
*/
public String bin2hex(String bin) {
char[] digital = "0123456789ABCDEF".toCharArray();
StringBuffer sb = new StringBuffer("");
byte[] bs = bin.getBytes();
int bit;
for (int i = 0; i < bs.length;i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append("\\'");
sb.append(digital[bit]);
bit = bs[i] & 0x0f;
sb.append(digital[bit]);
}
return sb.toString();
}
/**
* 字節形式讀取rtf模板內容
*/
public String readByteRtf(InputStream ins, String path){
String sourcecontent = "";
try{
ins = new FileInputStream(path);
byte[] b = new byte[1024];
if (ins == null) {
System.out.println("源模板文件不存在");
}
int bytesRead = 0;
while (true) {
bytesRead = ins.read(b, 0, 1024); // return final read bytes counts
if(bytesRead == -1) {// end of InputStream
System.out.println("讀取模板文件結束");
break;
}
sourcecontent += new String(b, 0, bytesRead); // convert to string using bytes
}
}catch(Exception e){
e.printStackTrace();
}
}
以上為核心代碼,剩余部分就是替換,從新組裝java中的String.replace(oldstr,newstr);方法可以實現,在這就不貼了。源代碼部分詳見附件。運行源代碼前提:
c盤創建YQ目錄,將附件中"模板.rtf"復制到YQ目錄之下,運行OpreatorRTF.java文件即可,就會在YQ目錄下生成文件名如:21時15分19秒_cheney_記錄.rtf 的文件。。。。。文件名是在程序中指定的呵呵。由於是由商業軟件中拆分出的demo所以只是將自己原來的寫的程序分離,合並在一個java文件中,所以有的方法在示例程序中看似多余,沒有必要那么麻煩。
對於替換部分需要循環的特例程序,我不好拆分,里面很容易暴露商業軟件的東西,所以就不貼了,有需要的話可以加我QQ或者MSN,一起討論呵呵。附件傳了半天也沒有傳上去,沒有辦法只有這樣搞了呵呵。模板文件附件無法存放,需要的直接聯系呵呵。其實直接看以下的java程序部分,就會明白
/**
* 以下部分是java源代碼
*/
package com;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
public class OperatorRTF {
/**
* 字符串轉換為rtf編碼
* @param content
* @return
*/
public String strToRtf(String content){
char[] digital = "0123456789ABCDEF".toCharArray();
StringBuffer sb = new StringBuffer("");
byte[] bs = content.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append("\\'");
sb.append(digital[bit]);
bit = bs[i] & 0x0f;
sb.append(digital[bit]);
}
return sb.toString();
}
/**
* 替換文檔的可變部分
* @param content
* @param replacecontent
* @param flag
* @return
*/
public String replaceRTF(String content,String replacecontent,int flag){
String rc = strToRtf(replacecontent);
String target = "";
/*if(flag==0){
target = content.replace("$time$",rc);
}*/
if(flag==0){
target = content.replace("$timetop$",rc);
}
if(flag==1){
target = content.replace("$info$",rc);
}
if(flag==2){
target = content.replace("$idea$",rc);
}
if(flag==3){
target = content.replace("$advice$",rc);
}
if(flag==4){
target = content.replace("$infosend$",rc);
}
return target;
}
/**
* 獲取文件路徑
* @param flag
* @return
*/
public String getSavePath() {
String path = "C:\\YQ";
File fDirecotry = new File(path);
if (!fDirecotry.exists()) {
fDirecotry.mkdirs();
}
return path;
}
/**
* 半角轉為全角
*/
public String ToSBC(String input){
char[] c = input.toCharArray();
for (int i = 0; i < c.length; i++){
if (c[i] == 32){
c[i] = (char) 12288;
continue;
}
if (c[i] < 127){
c[i] = (char) (c[i] + 65248);
}
}
return new String(c);
}
public void rgModel(String username, String content) {
// TODO Auto-generated method stub
/* 構建生成文件名 targetname:12時10分23秒_username_記錄.rtf */
Date current=new Date();
SimpleDateFormat sdf=new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String targetname = sdf.format(current).substring(11,13) + "時";
targetname += sdf.format(current).substring(14,16) + "分";
targetname += sdf.format(current).substring(17,19) + "秒";
targetname += "_" + username +"_記錄.rtf";
/* 字節形式讀取模板文件內容,將結果轉為字符串 */
String strpath = getSavePath();
String sourname = strpath+"\\"+"模板.rtf";
String sourcecontent = "";
InputStream ins = null;
try{
ins = new FileInputStream(sourname);
byte[] b = new byte[1024];
if (ins == null) {
System.out.println("源模板文件不存在");
}
int bytesRead = 0;
while (true) {
bytesRead = ins.read(b, 0, 1024); // return final read bytes counts
if(bytesRead == -1) {// end of InputStream
System.out.println("讀取模板文件結束");
break;
}
sourcecontent += new String(b, 0, bytesRead); // convert to string using bytes
}
}catch(Exception e){
e.printStackTrace();
}
/* 修改變化部分 */
String targetcontent = "";
/**
* 拆分之后的數組元素與模板中的標識符對應關系
* array[0]:timetop
* array[1]:info
* array[2]:idea
* array[3]:advice
* array[4]:infosend
*/
String array[] = content.split("~");
/**
* 2008年11月27日:更新模板之后時間無需自動填充
*/
/*String nowtime = sdf.format(current).substring(0,4) + "年";
nowtime += sdf.format(current).substring(5,7) + "月";
nowtime += sdf.format(current).substring(8,10) + "日";*/
for(int i=0;i<array.length;i++){
/*if(i==0){
targetcontent = documentDoc.replaceRTF(sourcecontent,nowtime,i);
}else{
targetcontent = documentDoc.replaceRTF(targetcontent,array[i-1],i);
}*/
if(i==0){
targetcontent = replaceRTF(sourcecontent, array[i], i);
}else{
targetcontent = replaceRTF(targetcontent, array[i], i);
}
}
/* 結果輸出保存到文件 */
try {
FileWriter fw = new FileWriter(getSavePath()+"\\" + targetname,true);
PrintWriter out = new PrintWriter(fw);
if(targetcontent.equals("")||targetcontent==""){
out.println(sourcecontent);
}else{
out.println(targetcontent);
}
out.close();
fw.close();
System.out.println(getSavePath()+" 該目錄下生成文件" + targetname + " 成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
OperatorRTF oRTF = new OperatorRTF();
/**
* 被替換內容以"~"符號分割,處理的時候將其拆分為數組即可
*/
String content = "2008年10月12日9時-2008年10月12日6時~我們參照檢驗葯品的方法~我們參照檢驗葯品的方法~我們參照檢驗葯品的方法~我們參照檢驗葯品的方法";
oRTF.rgModel("cheney",content);
}
}
