2012-12-19 57 views
7

ローカルシステム上で1つのExcelファイルを読み込んでいます。 POI jarバージョン3.7を使用していますが、エラーが発生しています。 -2300849302551019537または16進数0xE011BDBFEFBDBFEF、 -2226271756974174256または16進数0xE11AB1A1E011CFD0となります。無効なヘッダーの読み取りxlsファイル

Excelでxlsファイルを開くと正常に動作します。

コードブロック発生場所: 誰でも知っていますか?

/** 
* create a new HeaderBlockReader from an InputStream 
* 
* @param stream the source InputStream 
* 
* @exception IOException on errors or bad data 
*/ 
public HeaderBlockReader(InputStream stream) throws IOException { 
    // At this point, we don't know how big our 
    // block sizes are 
    // So, read the first 32 bytes to check, then 
    // read the rest of the block 
    byte[] blockStart = new byte[32]; 
    int bsCount = IOUtils.readFully(stream, blockStart); 
    if(bsCount != 32) { 
     throw alertShortRead(bsCount, 32); 
    } 

    // verify signature 
    long signature = LittleEndian.getLong(blockStart, _signature_offset); 

    if (signature != _signature) { 
     // Is it one of the usual suspects? 
     byte[] OOXML_FILE_HEADER = POIFSConstants.OOXML_FILE_HEADER; 
     if(blockStart[0] == OOXML_FILE_HEADER[0] && 
      blockStart[1] == OOXML_FILE_HEADER[1] && 
      blockStart[2] == OOXML_FILE_HEADER[2] && 
      blockStart[3] == OOXML_FILE_HEADER[3]) { 
      throw new OfficeXmlFileException("The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)"); 
     } 
     if ((signature & 0xFF8FFFFFFFFFFFFFL) == 0x0010000200040009L) { 
      // BIFF2 raw stream starts with BOF (sid=0x0009, size=0x0004, data=0x00t0) 
      throw new IllegalArgumentException("The supplied data appears to be in BIFF2 format. " 
        + "POI only supports BIFF8 format"); 
     } 

     // Give a generic error 
     throw new IOException("Invalid header signature; read " 
           + longToHex(signature) + ", expected " 
           + longToHex(_signature)); 
    } 
+1

あなたはあなたのコードからこの例外を投げていますか?新しいIOExceptionをスローしますか?あなたの質問で混乱し、あなた自身が例外をスローし、あなたはなぜ尋ねていますか? –

+0

例外はApache Poi Libraryによってスローされ、上にスローされるコードがあります。 – dutchman79

+0

apache poiがエラーをスローしていない場合、コードが "新しいIOException("無効なヘッダーシグネチャ、 " –

答えて

15

mavenを使用している場合は、リソースタグのフィルタリングがfalseに設定されていることを確認してください。あなたのプロジェクトがMavenのプロジェクトであればそうでない場合 Mavenのは、コピー・フェーズ

+0

in あなたのpom.xmlに – Felix

+0

素晴らしい!それがトリックでした。 – dutchman79

11

例外は、ファイルが有効なOLE2ベースの.xlsファイルではないことを示しています。

Excelでファイルを開くことは実際のガイドではありません。エクステンションが何であってもExcelはそれを知っているファイルをうれしく開きます。 .csvファイルを取り込み、.xlsに名前を変更しても、Excelは引き続き開きますが、改名によって魔法のように.xls形式になることはありませんので、POIはあなたのために開きません。

Excelでファイルを開き、Save-Asを実行すると、実際のExcelファイルとして書き出すことができます。実際にどのファイルかを知りたい場合は、--detectのTika CLIで

を使用してください。Apache Tikaを使用してみてください。

有効なファイルではないことを確認するにはどうすればよいですか?あなたはsection 2.2に、マイクロソフト、そして頭からOLE2 file format specification docを見ればあなたは次のように表示されます:

ヘッダシグネチャ(8バイト):複合ファイル構造のための識別署名、および0xD0値に設定しなければなりません、 0xCF、0x11、0xE0、0xA1、0xB1、0x1A、0xE1。

これらのバイトを丸めて(OLE2はリトルエンディアンです)、例外からマジック番号0xE11AB1A1E011CFD0を取得します。あなたのファイルはそのマジックナンバーで始まらないので、本当に有効なOLE2文書ではないので、POIはその例外を与えます。

+0

ExcelとSave-Asで同じ問題が発生する場合は、Apache Tika jarをダウンロードして--detectオプションを指定して実行してください:application/vnd .ms-excel – dutchman79

+0

あなたのファイルシステムはおそらく壊れていますか?ディスクが死んでいますか?実際には有効ではないファイルヘッダーの更新された回答を参照してください! – Gagravarr

+0

さらに奇妙なものにするには: src/main/resourcesフォルダ内の場所を指定します。しかし、私はgetResourceAsStream()でこれを読み取ろうとすると、この無効なヘッダ値が得られます... – dutchman79

0

で壊れたXLSファイルに傾向があり、次のコードが役立つことがあります。

/** 
* Get input stream of excel. 
* <p> 
*  Get excel from src dir instead of target dir to avoid causing POI header exception. 
* </p> 
* @param fileName file in dir PROJECT_PATH/src/test/resources/excel/ , proceeding '/' is not needed. 
* @return 
*/ 
private static InputStream getExcelInputStream(String fileName){ 
    InputStream inputStream = null; 
    try{ 
     inputStream = new FileInputStream(getProjectPath() + "/src/test/resources/excel/" + fileName); 
    }catch (URISyntaxException uriE){ 
     uriE.printStackTrace(); 
    }catch (FileNotFoundException fileE){ 
     fileE.printStackTrace(); 
    } 
    return inputStream; 
} 

private static String getProjectPath() throws URISyntaxException{ 
    URL url = YourServiceImplTest.class.getResource("/"); 
    Path path = Paths.get(url.toURI()); 
    Path subPath = path.subpath(0, path.getNameCount() -2); 
    return "/" + subPath.toString(); 
} 
関連する問題