Microsoft的Office系列产品拥有大量的用户,Word、Excel也成为办公文件的首选。在Java中,已经有很多对于Word、Excel的开源的解决方案,其中比较出色的是Apache的Jakata项目的POI子项目。该项目的官方网站是http://jakarta.apache.org/poi/。
POI包括一系列的API,它们可以操作基于MicroSoft OLE 2 Compound Document Format的各种格式文件,可以通过这些API在Java中读写Excel、Word等文件。POI是完全的Java Excel和Java Word解决方案。POI子项目包括:POIFS、HSSF、HDF、HPSF。表7-2对它们进行了简要介绍。
表7-2 POI子项目介绍
子项目名 |
说明 |
POIFS(POI File System) |
POIFS是POI项目中最早的最基础的一个模块,是Java到OLE 2 Compound Document Format的接口,支持读写功能,所有的其他项目都依赖与该项目。 |
HSSF(Horrible Spreadsheet Format) |
HSSF是Java到Microsoft Excel 97(-2002)文件的接口,支持读写功能 |
HWPF(Horrible Word Processing Format) |
HWPF是Java到Microsoft Word 97文件的接口,支持读写功能,但目前该模块还处于刚开始开发阶段,只能实现一些简单文件的操作,在后续版本中,会提供更强大的支持 |
HPSF(Horrible Property Set Format) |
HPSF 是Java到OLE 2 Compound Document Format文件的属性设置的接口,属性设置通常用来设置文档的属性(标题,作者,最后修改日期等),还可以设置用户定义的属性。HPSF支持读写功能,当前发布版本中直支持读功能。 |
7.3.1 对Excel的处理类
下面通过HSSF提供的接口对Excel文件经行处理。首先需要下载POI的包,可以到apache的官方网站下载,地址为:http://apache.justdn.org/jakarta/poi/,本书采用的是poi-2.5.1-final-20040804.jar,读者可以下载当前的稳定版本。把下载的包按照前面介绍的方式加入Build Path,然后新建一个ch7.poi包,并创建一个ExcelReader类。
ExcelReader类可以读取一个XLS文件,然后将其内容逐行提取出来,写入文本文件。其代码如下。
代码7.6
public class ExcelReader {
// 创建文件输入流
private BufferedReader reader = null;
// 文件类型
private String filetype;
// 文件二进制输入流
private InputStream is = null;
// 当前的Sheet
private int currSheet;
// 当前位置
private int currPosition;
// Sheet数量
private int numOfSheets;
// HSSFWorkbook
HSSFWorkbook workbook = null;
// 设置Cell之间以空格分割
private static String EXCEL_LINE_DELIMITER = " ";
// 设置最大列数
private static int MAX_EXCEL_COLUMNS = 64;
// 构造函数创建一个ExcelReader
public ExcelReader(String inputfile) throws IOException, Exception {
// 判断参数是否为空或没有意义
if (inputfile == null || inputfile.trim().equals("")) {
throw new IOException("no input file specified");
}
// 取得文件名的后缀名赋值给filetype
this.filetype = inputfile.substring(inputfile.lastIndexOf(".") + 1);
// 设置开始行为0
currPosition = 0;
// 设置当前位置为0
currSheet = 0;
// 创建文件输入流
is = new FileInputStream(inputfile);
// 判断文件格式
if (filetype.equalsIgnoreCase("txt")) {
// 如果是txt则直接创建BufferedReader读取
reader = new BufferedReader(new InputStreamReader(is));
}
else if (filetype.equalsIgnoreCase("xls")) {
// 如果是Excel文件则创建HSSFWorkbook读取
workbook = new HSSFWorkbook(is);
// 设置Sheet数
numOfSheets = workbook.getNumberOfSheets();
}
else {
throw new Exception("File Type Not Supported");
}
}
// 函数readLine读取文件的一行
public String readLine() throws IOException {
// 如果是txt文件则通过reader读取
if (filetype.equalsIgnoreCase("txt")) {
String str = reader.readLine();
// 空行则略去,直接读取下一行
while (str.trim().equals("")) {
str = reader.readLine();
}
return str;
}
// 如果是XLS文件则通过POI提供的API读取文件
else if (filetype.equalsIgnoreCase("xls")) {
// 根据currSheet值获得当前的sheet
HSSFSheet sheet = workbook.getSheetAt(currSheet);
// 判断当前行是否到但前Sheet的结尾
if (currPosition > sheet.getLastRowNum()) {
// 当前行位置清零
currPosition = 0;
// 判断是否还有Sheet
while (currSheet != numOfSheets - 1) {
// 得到下一张Sheet
sheet = workbook.getSheetAt(currSheet + 1);
// 当前行数是否已经到达文件末尾
if (currPosition == sheet.getLastRowNum()) {
// 当前Sheet指向下一张Sheet
currSheet++;
continue;
} else {
// 获取当前行数
int row = currPosition;
currPosition++;
// 读取当前行数据
return getLine(sheet, row);
}
}
return null;
}
// 获取当前行数
int row = currPosition;
currPosition++;
// 读取当前行数据
return getLine(sheet, row);
}
return null;
}
// 函数getLine返回Sheet的一行数据
private String getLine(HSSFSheet sheet, int row) {
// 根据行数取得Sheet的一行
HSSFRow rowline = sheet.getRow(row);
// 创建字符创缓冲区
StringBuffer buffer = new StringBuffer();
// 获取当前行的列数
int filledColumns = rowline.getLastCellNum();
HSSFCell cell = null;
// 循环遍历所有列
for (int i = 0; i < filledColumns; i++) {
// 取得当前Cell
cell = rowline.getCell((short) i);
String cellvalue = null;
if (cell != null) {
// 判断当前Cell的Type
switch (cell.getCellType()) {
// 如果当前Cell的Type为NUMERIC
case HSSFCell.CELL_TYPE_NUMERIC: {
// 判断当前的cell是否为Date
if (HSSFDateUtil.isCellDateFormatted(cell)) {
// 如果是Date类型则,取得该Cell的Date值
Date date = cell.getDateCellValue();
// 把Date转换成本地格式的字符串
cellvalue = cell.getDateCellValue().toLocaleString();
}
// 如果是纯数字
else {
// 取得当前Cell的数值
Integer num = new Integer((int) cell
.getNumericCellValue());
cellvalue = String.valueOf(num);
}
break;
}
// 如果当前Cell的Type为STRIN
case HSSFCell.CELL_TYPE_STRING:
// 取得当前的Cell字符串
cellvalue = cell.getStringCellValue().replaceAll("'", "''");
break;
// 默认的Cell值
default:
cellvalue = " ";
}
} else {
cellvalue = "";
}
// 在每个字段之间插入分割符
buffer.append(cellvalue).append(EXCEL_LINE_DELIMITER);
}
// 以字符串返回该行的数据
return buffer.toString();
}
// close函数执行流的关闭操作
public void close() {
// 如果is不为空,则关闭InputSteam文件输入流
if (is != null) {
try {
is.close();
} catch (IOException e) {
is = null;
}
}
// 如果reader不为空则关闭BufferedReader文件输入流
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
reader = null;
}
}
}
}
7.3.2 ExcelReader的运行效果
下面创建一个main函数,用来测试上面的ExcelReader类,代码如下。
代码7.7
public static void main(String[] args) {
try{
ExcelReader er=new ExcelReader("c:\\xp.xls");
String line=er.readLine();
while(line != null){
System.out.println(line);
line=er.readLine();
}
er.close();
}catch(Exception e){
e.printStackTrace();
}
}
main函数先创建一个ExcelReader类,然后调用它提供的接口readLine,对XLS文件进行读取,打印到控制台,处理前的XLS文件如图7-12所示。
图7-12 处理前的XLS文件内容
运行main函数进行内容提取后,Eclipse的控制台输出如图7-13所示。
图7-13 输出结果
可以看到,Excel文件中的内容已经被成功的输出了出来。
7.3.3 POI中Excel文件Cell的类型
在读取每一个Cell的值的时候,通过getCellType方法获得当前Cell的类型,在Excel中Cell有6种类型,如表7-3所示。
表7-3 Cell的类型
CellType |
说明 |
CELL_TYPE_BLANK |
空值 |
CELL_TYPE_BOOLEAN |
布尔型 |
CELL_TYPE_ERROR |
错误 |
CELL_TYPE_FORMULA |
公式型 |
CELL_TYPE_STRING |
字符串型 |
CELL_TYPE_NUMERIC |
数值型 |
本例采用了CELL_TYPE_STRING和CELL_TYPE_NUMERIC类型,因为在Excel文件中只有字符串和数字。如果Cell的Type为CELL_TYPE_NUMERIC时,还需要进一步判断该Cell的数据格式,因为它有可能是Date类型,在Excel中的Date类型也是以Double类型的数字存储的。Excel中的Date表示当前时间与1900年1月1日相隔的天数,所以需要调用HSSFDateUtil的isCellDateFormatted方法,判断该Cell的数据格式是否是Excel Date类型。如果是,则调用getDateCellValue方法,返回一个Java类型的Date。
实际上Excel的数据格式有很多,还支持用户自定义的类型,在Excel中,选择一个单元格然后右键选择“设置单元格格式”,在弹出的单元格格式中选中“数字”,如图7-14所示。
图7-14 Excel的单元格格式
图中的数据有数值、货币、时间、日期、文本等格式。这些数据格式在POI中的HSSFDataFormat类里都有相应的定义。
HSSFDataFormat是HSSF子项目里面定义的一个类。类HSSFDataFormat允许用户新建数据格式类型。HSSFDataFormat类包含静态方法static java.lang.String getBuiltinFormat(short index),它可以根据编号返回内置数据类型。另外static short getBuiltinFormat(java.lang.String format)方法则可以根据数据类型返回其编号,static java.util.List getBuiltinFormats()可以返回整个内置的数据格式列表。
在HSSFDataFormat里一共定义了49种内置的数据格式,如表7-4所示。
表7-4 HSSFDataFormat的数据格式
内置数据类型 |
编号 |
"General" |
0 |
"0" |
1 |
"0.00" |
2 |
"#,##0" |
3 |
"#,##0.00" |
4 |
"($#,##0_);($#,##0)" |
5 |
"($#,##0_);[Red]($#,##0)" |
6 |
"($#,##0.00);($#,##0.00)" |
7 |
"($#,##0.00_);[Red]($#,##0.00)" |
8 |
"0%" |
9 |
"0.00%" |
0xa |
"0.00E+00" |
0xb |
"# ?/?" |
0xc |
"# ??/??" |
0xd |
"m/d/yy" |
0xe |
"d-mmm-yy" |
0xf |
"d-mmm" |
0x10 |
"mmm-yy" |
0x11 |
"h:mm AM/PM" |
0x12 |
"h:mm:ss AM/PM" |
0x13 |
"h:mm" |
0x14 |
"h:mm:ss" |
0x15 |
"m/d/yy h:mm" |
0x16 |
保留为过国际化用 |
0x17 - 0x24 |
"(#,##0_);(#,##0)" |
0x25 |
"(#,##0_);[Red](#,##0)" |
0x26 |
"(#,##0.00_);(#,##0.00)" |
0x27 |
"(#,##0.00_);[Red](#,##0.00)" |
0x28 |
"_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)" |
0x29 |
"_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)" |
0x2a |
"_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)" |
0x2b |
"_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)" |
0x2c |
"mm:ss" |
0x2d |
"[h]:mm:ss" |
0x2e |
"mm:ss.0" |
0x2f |
"##0.0E+0" |
0x30 |
"@" - This is text format |
0x31 |
在上面表中,字符串类型所对应的是数据格式为"@"(最后一行),也就是HSSFDataFormat中定义的值为0x31(49)的那行。Date类型的值的范围是0xe-0x11,本例子中的Date格式为""m/d/yy"",在HSSFDataFormat定义的值为0xe(14)。
需要注意的一点是,所创建的Excel必须是在Microsoft Excel 97到Excel XP的版本上的,如果在Excel 2003中创建文件后,在使用POI进行解析时,可能会出现问题。它会把Date类型当作自定义类型。POI目前只提供对Microsoft Excel XP以下的版本的支持,在以后的版本中,希望会提供对Microsoft Excel 2003更好的支持。
7.3.4 对Word的处理类
除了支持对Excel文件的读取外,POI还提供对Word的DOC格式文件的读取。但在它的发行版本中没有发布对Word支持的模块,需要另外下载一个POI的扩展的Jar包。用户可以到http://www.ibiblio.org/maven2/org/textmining/tm-extractors/0.4/下载,本书采用的是tm-extractors-0.4_zip。
下载后,把该包加入工程的Build Path中,然后在ch7.poi包下新建一个类WordReader,该类提供一个静态方法readDoc,读取一个DOC文件并返回文本。函数内容很简单,就是调用WordExtractor的API来提取DOC的内容到字符串,该函数的代码如下。
代码7.8
public static String readDoc(String doc) throws Exception {
// 创建输入流读取DOC文件
FileInputStream in = new FileInputStream(new File(doc));
WordExtractor extractor = null;
String text = null;
// 创建WordExtractor
extractor = new WordExtractor();
// 对DOC文件进行提取
text = extractor.extractText(in);
return text;
}
在同一个类里创建一个main函数,测试WordReader,该main函数代码如下。
代码7.9
public static void main(String[] args) {
try{
String text = WordReader.readDoc("c:/test.doc");
System.out.println(text);
}catch(Exception e){
e.printStackTrace();
}
}
处理前的Doc文件如图7-15所示。
图7-15 处理前的Word文档
使用代码处理后的文本如图7-16所示。
图7-16 处理后的结果
可以看到Word文档内的文本已经全部被提取了出来。
相关推荐
使用POI来处理Excel和Word文件格式
7_3 使用POI来处理Excel和Word文件格式
。。。
。。。
POI处理EXCEL和WORD文件的JAR包和详细资料
利用POI读取excel写入到word 利用POI读取excel写入到word 利用POI读取excel写入到word,压缩包里包含了jar包
POI处理EXCEL和WORD文件的JAR包和资料
值得注意的是 POI 在读取 word 文件的时候不会读取 word 文件中的图片信息 还有就是对于 2007 版的 word docx 如果 word 文件中有表格 所有表格中的数据都会在读取出来的字符串的最后 ">这是一个POI读取word 2003 和 ...
poi excel poi excel poi excel poi excel poi excel poi excel poi excel poi excel
POI是java对Word和Excel 文件操作的插件,这文档主要是教我们怎么使用POI插件对Word和Excel文件进行读写操作
相同格式的excel进行合并,或者对多个word文档进行合并,word文档包含图片。
java 中通过 poi组件操作word文档以及 excel 表格的演示,如何获取 excel中数据以及如何通过模板将对象数据动态生成 excel表格
里面有工具类,包含word和excel。支持doc。docx xls和xlsx等格式。还有稀缺的所有jar包。绝对物有所值
可以运行的POI导出Excel文件实例,里面有两种方法,一个是Servlet,一个是main
java使用poi读取xls格式和xlsx格式的excel文件
poi读取大文件Excel,使用xml格式解析,速度实测50mb文件13s,可指定sheet页内容,带工具类和测试类
Javapoi对excel的文档处理,对时间日期的格式一些方法
java实现word、excel在线预览。版本2003和2007都支持在线预览,项目需要导入一些poi相关的jar,jar之间的版本有要求。在我的资源列表,有相关的jar包可以下载。
文件包含了 1.POI导入导出的工具类; 2.图片URL导出成图片文件; 3.导出excel和图片压缩包格式文件。 如果下载后有任何问题,可以联系我哦!
使用poi解析excel文件,并将数据写入到数据库 项目说明 这个项目实现的功能是读取excel文件中的数据,解析并写入数据库。 读取的excel文件位于项目目录下的 excel\0805.xlsx 使用IntelliJ IDEA开发此项目 使用MYSQL...