使用Java读取Word文件的简单例子分享
作者:ISH_ICODE 发布时间:2022-12-17 02:15:19
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文档
主要程序如下:
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("读取模板文件结束");
break;
}
sourcecontent += new String(b, 0, bytesRead); // convert to string using bytes
}
}catch(Exception e){
e.printStackTrace();
}
return sourcecontent ;
}
以上为核心代码,剩余部分就是替换,从新组装java中的String.replace(oldstr,newstr);方法可以实现,在这就不贴了。源代码部分详见附件。
运行源代码前提:
c盘创建YQ目录,将附件中"模板.rtf"复制到YQ目录之下,运行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("读取模板文件结束");
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文件的表格数据的示例:
<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>


猜你喜欢
- 比如定义了一个错误的枚举类型public enum eErrorDetailCode : int &nbs
- ELK是三款软件的简称,分别是Elasticsearch、Logstash、Kibana组成,在发展的过程中,又有新成员Beats的加入,所
- 做了Android开发这么久了,经常会遇到一个问题是adb端口被占用,大家都知道Android默认的adb端口是5037,电脑上有一些应用的
- Android数据存储几种方式SharePreferences数据库SQLite存储卡的文件操作Application一、共享参数Share
- 本文实例为大家分享了Android仿微信长按录制视频并播放功能的具体代码,供大家参考,具体内容如下一、点击按钮进行录制首先要获取摄像拍照的权
- 一、运算符运算符包括下面几种:算术运算符赋值运算符比较运算符逻辑运算符位运算符三目运算符最不常用的是位运算符,但也是最接近计算机底层的。1、
- 1. 去官方下载log4j 2,导入jar包,基本上你只需要导入下面两个jar包就可以了(xx是乱七八糟的版本号):log4j-core-x
- 前言其实不管是哪种滑动方式,基本思想都是类似的:当点击事件传递到View时,系统记下触摸点的坐标,手指移动的时候,系统记下移动后的坐标,并计
- 前言 为什么在kotlin要使用协程呢,这好比去了重庆不吃火锅一样的道理。协程的概念并
- 本文实例讲述了java执行Linux命令的方法。分享给大家供大家参考。具体实现方法如下:public class StreamGobbler
- 今天在做一个联系人管理的C#设计时,遇到了这个问题,我需要将父窗体中的textBox中的值传到子窗体并进行数据库查询操作,我用了new 父窗
- 以卖票的例子来介绍多线程和资源共享,下面我们
- 前言在开发中,或多或少会使用唤醒锁(wake lock),有的是为了保持屏幕长亮,有的是为了保持 CPU 运行。唤醒锁的本质,其实是对屏幕状
- Java类加载器1、BootClassLoader: 用于加载Android Framework层class文件。2、PathClassLo
- 关于Windows10 Java环境变量配置问题的解决办法由于最近有一些时间,所以想要把之前学过一段时间的Java重新捡起来看看,之前的学习
- 1.简介使用线程池可以避免线程的频繁创建以及销毁。JAVA中提供的用于实现线程池的API:Executor、ExecutorService、
- 本文实例讲述了C#实现客户端弹出消息框封装类。分享给大家供大家参考。具体如下:asp.net在服务器端运行,是不能在服务器端弹出对话框的,但
- 本文实例讲述了Android编程实现加载等待ProgressDialog的方法。分享给大家供大家参考,具体如下:显示progressDial
- ListView在虚模式下,CheckBox无法点击,可以用此方法实现private void lvwTitle_MouseDown(obj
- Junit中的基本注解:@Test:使用该注解标注的public void方法会表示为一个测试方法;@BeforeClass:表示在类中的任