這兩天在用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一下。