使用Java讀取Word文件的簡單例子分享
java讀取word文檔時,雖然網(wǎng)上介紹了很多插件poi、java2Word、jacob、itext等等,poi無法讀取格式(新的API估計行好像還在處于研發(fā)階段,不太穩(wěn)定,做項目不太敢用);java2Word、jacob容易報錯找不到注冊,比較詭異,我曾經(jīng)在不同的機器上試過,操作方法完全一致,有的機器不報錯,有的報錯,去他們論壇找高人解決也說不出原因,項目部署用它有點玄;itxt好像寫很方便但是我查了好久資料沒有見到過關(guān)于讀的好辦法。經(jīng)過一番選擇還是折中點采用rtf最好,畢竟rtf是開源格式,不需要借助任何插件,只需基本IO操作外加編碼轉(zhuǎn)換即可。rtf格式文件表面看來和doc沒啥區(qū)別,都可以用word打開,各種格式都可以設(shè)定。
----- 實現(xiàn)的功能:讀取rtf模板內(nèi)容(格式和文本內(nèi)容),替換變化部分,形成新的rtf文檔。
----- 實現(xiàn)思路:模板中固定部分手動輸入,變化的部分用$info$表示,只需替換$info$即可。
1、采用字節(jié)的形式讀取rtf模板內(nèi)容
2、將可變的內(nèi)容字符串轉(zhuǎn)為rtf編碼
3、替換原文中的可變部分,形成新的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();
}
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("讀取模板文件結(jié)束");
break;
}
sourcecontent += new String(b, 0, bytesRead); // convert to string using bytes
}
}catch(Exception e){
e.printStackTrace();
}
return sourcecontent ;
}
以上為核心代碼,剩余部分就是替換,從新組裝java中的String.replace(oldstr,newstr);方法可以實現(xiàn),在這就不貼了。源代碼部分詳見附件。
運行源代碼前提:
c盤創(chuàng)建YQ目錄,將附件中"模板.rtf"復(fù)制到Y(jié)Q目錄之下,運行OpreatorRTF.java文件即可,就會在YQ目錄下生成文件名如:21時15分19秒_cheney_記錄.rtf 的文件。
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 {
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();
}
public String replaceRTF(String content,String replacecontent,int flag){
String rc = strToRtf(replacecontent);
String target = "";
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;
}
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
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("讀取模板文件結(jié)束");
break;
}
sourcecontent += new String(b, 0, bytesRead); // convert to string using bytes
}
}catch(Exception e){
e.printStackTrace();
}
String targetcontent = "";
String array[] = content.split("~");
for(int i=0;i<array.length;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);
}
}
使用POI讀取word文件的表格數(shù)據(jù)的示例:

<span style="font-size:14px;">package com.poi.world;
import java.io.FileInputStream;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableIterator;
import org.apache.poi.hwpf.usermodel.TableRow;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
public class POI_Word{
public static void main(String[] args){
try {
String[] s=new String[20];
FileInputStream in=new FileInputStream("D:\\mayi.doc");
POIFSFileSystem pfs=new POIFSFileSystem(in);
HWPFDocument hwpf=new HWPFDocument(pfs);
Range range =hwpf.getRange();
TableIterator it=new TableIterator(range);
int index=0;
while(it.hasNext()){
Table tb=(Table)it.next();
for(int i=0;i<tb.numRows();i++){
//System.out.println("Numrows :"+tb.numRows());
TableRow tr=tb.getRow(i);
for(int j=0;j<tr.numCells();j++){
//System.out.println("numCells :"+tr.numCells());
// System.out.println("j :"+j);
TableCell td=tr.getCell(j);
for(int k=0;k<td.numParagraphs();k++){
//System.out.println("numParagraphs :"+td.numParagraphs());
Paragraph para=td.getParagraph(k);
s[index]=para.text().trim();
index++;
}
}
}
}
// System.out.println(s.toString());
for(int i=0;i<s.length;i++){
System.out.println(s[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}</span>
相關(guān)文章
SpringSecurity rememberme功能實現(xiàn)過程解析
這篇文章主要介紹了SpringSecurity rememberme功能實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
springboot 事件監(jiān)聽的實現(xiàn)方法
這篇文章主要介紹了springboot 事件監(jiān)聽的實現(xiàn)方法,并詳細(xì)的介紹了四種監(jiān)聽方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04
關(guān)于SpringCloud?Ribbon替換輪詢算法問題
Spring?Cloud?Ribbon是基于Netlix?Ribbon實現(xiàn)的一套客戶端負(fù)載均衡的工具。接下來通過本文給大家介紹SpringCloud?Ribbon替換輪詢算法問題,需要的朋友可以參考下2022-01-01
詳解Spring與Mybatis的整合方法(基于Eclipse的搭建)
這篇文章主要介紹了Spring與Mybatis的整合方法(基于Eclipse的搭建),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10
spring mvc DispatcherServlet之前端控制器架構(gòu)詳解
這篇文章主要為大家詳細(xì)介紹了spring mvc DispatcherServlet之前端控制器架構(gòu),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
關(guān)于java關(guān)鍵字this和super的區(qū)別和理解
這篇文章主要給大家介紹了關(guān)于java關(guān)鍵字this和super的區(qū)別和理解的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

