2012-12-19 5 views
7

Sto leggendo un file excel sul mio sistema locale. Sto usando POI jar Versione 3.7, ma ricevo errore Firma di intestazione non valida; leggere -2300849302551019537 o in esadecimale 0xE011BDBFEFBDBFEF, previsto -2226271756974174256 o in esadecimale 0xE11AB1A1E011CFD0.Lettura intestazione non valida xls file

L'apertura del file xls con Excel funziona correttamente.

Il codeblock dove capita: Chiunque un'idea?

/** 
* 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

si sta gettando questa eccezione dal codice? lanciare nuove IOException? confuso dalla tua domanda, tu stesso fai l'eccezione e ti chiedi perché? –

+0

L'eccezione viene generata dalla libreria Apache Poi e sopra c'è il codice che la lancia. – dutchman79

+0

apache poi non sta lanciando l'errore, il tuo codice lancia "nuova IOException (" Firma intestazione non valida; leggi " –

risposta

15

Solo un idee, se stai usando Maven rendere sicuro nel filtraggio tag risorsa è impostata su false. Altrimenti Maven tende a file XLS corrotti nella fase di copiatura

+0

in nel tuo pom.xml – Felix

+0

Grande! Questo ha fatto il trucco. – dutchman79

11

Tale eccezione vi sta dicendo che il file non è un file .xls OLE2 a base valida.

Essere in grado di aprire il file in Excel non è un vera e propria guida - Excel sarà lieto di aprire qualsiasi file è a conoscenza non importa quale sia l'estensione è su di esso. Se si prende un file .csv e lo si rinomina in .xls, Excel lo aprirà comunque, ma la ridenominazione non è stata magicamente creata nel formato .xls, quindi POI non la aprirà per te.

Se si apre il file in Excel e fare Save-As, che lascerà lo si scrive come un vero file di Excel. Se volete sapere quale file che realmente è, provare a utilizzare Apache Tika - la Tika CLI con --detect dovrebbe essere in grado di dirvi

.

Come posso essere sicuro che non è un file valido? Se si guarda alla OLE2 file format specification doc da Microsoft, e la testa di section 2.2 vedrete il seguente:

Intestazione Firma (8 byte): firma di identificazione per la struttura file composito, e deve essere impostato il valore 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1.

vibrazione di coloro byte rotonda (OLE2 è little endian) e si ottiene 0xE11AB1A1E011CFD0, il numero magico dal l'eccezione. Il tuo file non inizia con quel numero magico, in quanto in realtà non è un documento OLE2 valido e quindi POI ti dà quell'eccezione.

+0

Ok, l'apertura in Excel e Save-As ha lo stesso problema, quindi ho scaricato il vaso Apache Tika e l'ho eseguito con l'opzione --detect: application/vnd .ms-excel – dutchman79

+0

Il tuo filesystem è rotto forse? Disco che muore? Vedi la risposta aggiornata, l'intestazione del file che hai davvero non è valida! – Gagravarr

+0

Per renderlo ancora più strano: quando leggo lo stesso file di template rivolgendolo direttamente al suo posizione nella cartella src/main/resources funziona.Tuttavia, quando provo a leggerlo con getResourceAsStream() ottengo questo valore di intestazione non valido ... – dutchman79

0

Se il progetto è il progetto Maven, il seguente codice può aiutare:

/** 
* 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(); 
}