这两天在用POI提取 Microsoft 格式文档的内容的时候莫名其妙的遇到了一个问题,困扰了我3天:
我的POI版本为:
poi-3.0.2-FINAL-20080204.jar;
poi-contrib-3.0.2-FINAL-20080204.jar;
poi-scratchpad-3.0.2-FINAL-20080204.jar;
开发环境为:jdk1.6;
IDE为Eclipse3.2;
以下是我提取excel格式文本的程序:
HSSFWorkbook book = new HSSFWorkbook(is);
int sheetNumber = book.getNumberOfSheets();// 获取excel文件中的表单数量
for (int i = 0; i < sheetNumber; i++) {
if (book.getSheetAt(i) != null) {
HSSFSheet sheet = book.getSheetAt(i);// 读取第i个表单
int totalRow = sheet.getPhysicalNumberOfRows();// 表单含有的行的数目
for (int j = 0; j < totalRow; j++) {
if (sheet.getRow(j) != null) {
HSSFRow row = sheet.getRow(j);// 读取第i个表单的第j行
for (short cellNumOfRow = 0; cellNumOfRow < row
.getPhysicalNumberOfCells(); cellNumOfRow++) {
if (row.getCell(cellNumOfRow) != null) {
HSSFCell cell = row.getCell(cellNumOfRow);
int cellType = cell.getCellType();// 获取单元格类型
switch (cellType) {
case HSSFCell.CELL_TYPE_NUMERIC:// 类型为double
str.append(cell.getNumericCellValue())
.append(separator);
break;
case HSSFCell.CELL_TYPE_STRING:// 类型为string
str.append(cell.getStringCellValue())
.append(separator);
break;
default:// 其他类型格式不进行提取
break;
}
}
}
}
}
}
}
以下是我提取ppt文档文本内容的程序:
StringBuffer pptText = new StringBuffer("");
SlideShow ss = new SlideShow(new HSLFSlideShow(is));// 通过is输入流建立SlideShow
Slide[] slides = ss.getSlides();// 获取每一张幻灯片
for (int i = 0; i < slides.length; i++) {
TextRun[] t = slides[i].getTextRuns();// 获取幻灯片中文字内容
for (int j = 0; j < t.length; j++) {
pptText.append(t[j].getText());
}
}
但是最开始我发现每次运行这两个程序的时候都会出现异常:ArrayIndexOutOfBoundsException。
具体描述如下:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
at org.apache.poi.util.HexDump.toHex(HexDump.java:406)
at org.apache.poi.util.HexDump.toHex(HexDump.java:397)
at
org.apache.poi.hpsf.UnsupportedVariantTypeException.<init>(UnsupportedVariantTypeException.java:46)
at
org.apache.poi.hpsf.ReadingNotSupportedException.<init>(ReadingNotSupportedException.java:45)
at org.apache.poi.hpsf.VariantSupport.read(VariantSupport.java:267)
at org.apache.poi.hpsf.Property.<init>(Property.java:146)
at org.apache.poi.hpsf.Section.<init>(Section.java:281)
at org.apache.poi.hpsf.PropertySet.init(PropertySet.java:452)
at org.apache.poi.hpsf.PropertySet.<init>(PropertySet.java:249)
at org.apache.poi.hpsf.PropertySetFactory.create(PropertySetFactory.java:59)
at org.apache.poi.hslf.HSLFSlideShow.getPropertySet(HSLFSlideShow.java:214)
at org.apache.poi.hslf.HSLFSlideShow.readProperties(HSLFSlideShow.java:182)
at org.apache.poi.hslf.HSLFSlideShow.<init>(HSLFSlideShow.java:105)
at org.apache.poi.hslf.HSLFSlideShow.<init>(HSLFSlideShow.java:85)
at org.apache.poi.hslf.HSLFSlideShow.<init>(HSLFSlideShow.java:72)
at
无论我采取任何的其他构造方式都会出现同样的错误,我想到这个可能是一个尚未修正的bug,我去poi官网上面的mail-list进行查找发现很多人都反映这个问题(不是个体原因)。终于我发现了这个问题的根源所在:
首先确认你的程序使用是你所导入的poi版本
import org.apache.poi.hslf.extractor.*;
public class TestWherePPT {
public static void main(String[] args) throws Exception {
Class extractorClass = PowerPointExtractor.class;
ClassLoader loader = extractorClass.getClassLoader();
String extractorFrom =
loader.getResource("org/apache/poi/hslf/extractor/PowerPointExtractor.class").toString();
String hpsfFrom =
loader.getResource("org/apache/poi/hpsf/PropertySet.class").toString();
System.out.println(extractorFrom);
System.out.println(hpsfFrom);
}
}
jar:file:/C:/opt/eclipse-rc/eclipse/workspace/project/lib/textmining/poi-scratchpad-3.0.2-FINAL-20080204.jar!/org/apache/poi/hslf/extractor/PowerPointExtractor.class
jar:file:/C:/opt/eclipse-rc/eclipse/workspace/project/lib/textmining/poi-3.0.2-FINAL-20080204.jar!/org/apache/poi/hpsf/PropertySet.class
确认版本,如果显示的版本不是你所认为的版本,请检查classpath看是否含有poi的其他版本。如果含有请将其去除,问题如果还是没有解决请查看你的classpath中间导入的poi的jar文件是否位于最后,如下是我的project中的classpath的位置:
如图所示我的poi文件位于classpath的最后,这个时候运行就会出现上述的ArrayIndexOutOfBoundsException,我将classpath中的jar文件位置进行调换使得poi文件不位于classpath的最后,如下:
这个时候异常就不会再出现了。在poi的bug列表里面这个bug为 36416,有兴趣可以去fix一下。