Domanda

Sto usando HSSF-POI per leggere i dati di Excel. Il problema è che ho valori in una cella che sembrano un numero ma in realtà sono stringhe. Se guardo la cella di formato in Excel, si dice che il tipo è "testo". Tuttavia la cella HSSF pensa che sia numerica. Come posso ottenere il valore come stringa?

Se provo a usare cell.getRichStringValue , ottengo un'eccezione; se cell.toString , non è lo stesso valore del foglio Excel.

Modifica : fino a quando questo non verrà risolto, userò

new BigDecimal(cell.getNumericCellValue()).toString()
È stato utile?

Soluzione

Intendi dire HSSF-POI

cell.getCellType () == Cell.CELL_TYPE_NUMERIC

NON

Cell.CELL_TYPE_STRING come dovrebbe essere?

Penso che sia un bug nel PDI, ma ogni cella contiene una variante e la variante ha un tipo. È un po 'difficile creare un bug lì, quindi penso che Excel usi alcuni dati extra o euristici per riportare il campo come testo. La solita via MS, ahimè.

P.S. Non è possibile utilizzare getString () su una variante contenente valori numerici, poiché la rappresentazione binaria dei dati della variante dipende dal tipo e il tentativo di ottenere una stringa da ciò che è in realtà un numero comporterebbe immondizia: - da qui l'eccezione.

Altri suggerimenti

La classe che stai cercando in PDI è DataFormatter

Quando Excel scrive il file, alcune celle vengono archiviate come stringhe letterali, mentre altre vengono archiviate come numeri. Per quest'ultimo, un valore in virgola mobile che rappresenta la cella viene memorizzato nel file, quindi quando chiedi a POI il valore della cella è quello che ha effettivamente.

A volte però, specialmente quando si fa Estrazione di testo (ma non sempre), si desidera far sembrare il valore della cella come in Excel. Non è sempre possibile ottenerlo esattamente in una stringa (ad esempio un padding non pieno di spazio), ma la classe DataFormatter ti avvicinerà.

Se stai cercando una stringa della cella, che assomigli tanto a come avevi in ??Excel, fai semplicemente:

 // Create a formatter, do this once
 DataFormatter formatter = new DataFormatter(Locale.US);

 .....

 for(Cell cell : row) {
     CellReference ref = new CellReference(cell);
     // eg "The value of B12 is 12.4%"
     System.out.println("The value of " + ref.formatAsString() + " is " + formatter.formatCellValue(cell));
 }

Il formatter restituirà le celle String così come sono e per le celle numeriche applicherà le regole di formattazione sullo stile al numero della cella

Se i documenti che stai analizzando sono sempre in un layout specifico, puoi cambiare il tipo di cella in "stringa". al volo e quindi recuperare il valore. Ad esempio, se la colonna 2 deve sempre contenere dati stringa, imposta il tipo di cella su stringa e quindi leggilo con i metodi get di tipo stringa.

cell.setCellType(Cell.CELL_TYPE_STRING);

Nel mio test, cambiare il tipo di cella non ha modificato il contenuto della cella, ma ha permesso di recuperarlo con uno dei seguenti approcci:

cell.getStringCellValue();

cell.getRichStringCellValue().getString();

Senza un esempio di un valore che non viene convertito correttamente, è difficile sapere se questo si comporterà in modo diverso rispetto all'approccio cell.toString () descritto nella descrizione.

Questo codice di seguito funziona perfettamente per leggere qualsiasi tipo di cella, ma quella cella deve contenere un valore numerico

new BigDecimal(cell.getNumericCellValue()));

per es.

ase.setGss(new BigDecimal(hssfRow.getCell(3).getNumericCellValue()));

dove gss variabile è di tipo BigDecimal.

Excel converte qualsiasi cosa che assomigli a un numero o data o ora da una stringa. Vedi articolo della Microsoft Knowledge Base , che in pratica suggerisce di inserire il numero con un carattere in più che lo rende una stringa.

Probabilmente hai a che fare con un problema di Excel. Quando si crea il foglio di calcolo, il tipo di cella predefinito è Generico. Con questo tipo, Excel indovina il tipo in base all'input e questo tipo viene salvato con ogni cella.

Quando in seguito cambi il formato della cella in Testo, stai semplicemente cambiando il valore predefinito. Excel non cambia automaticamente il tipo di ogni cella. Non ho trovato un modo per farlo automaticamente.

Per confermare ciò, puoi andare su Excel e digitare nuovamente uno dei numeri e vedere se è testo in HSSF.

Puoi anche guardare il tipo di cella reale usando questa funzione,

  @Cell("type", A1)

A1 è la cella per il numero. Mostra " l " per il testo, " v " per i numeri.

Il problema con Excel è che il formato predefinito è generico. Con questo formato Excel memorizza i numeri immessi nella cella come numerici. Devi modificare il formato in prima di inserire i valori. Anche il rientro dei valori dopo aver modificato il formato funzionerà.
Ciò porterà a piccoli triangoli verdi nell'angolo in alto a sinistra delle celle se il contenuto sembra un numero in Excel. In tal caso, il valore viene memorizzato come testo.

Con il nuovo BigDecimal (cell.getNumericCellValue ()). toString () avrai ancora molti problemi. Ad esempio, se si hanno numeri identificativi (ad es. Numeri di parte o numeri di classificazione), probabilmente si hanno casi con zeri iniziali che rappresenteranno un problema con l'approccio getNumericCellValue ().

Cerco di spiegare a fondo come creare correttamente Excel alla parte creando i file che devo gestire con i POI. Se i file vengono caricati dagli utenti finali, ho persino creato un programma di validazione per verificare i tipi di celle previsti se conosco in anticipo le colonne. Come sottoprodotto puoi anche controllare varie altre cose dei file forniti (ad es. Sono le colonne giuste fornite o i valori obbligatori).

" Il problema è che ho valori in una cella che sembrano un numero " = & Gt; sembra un numero se visualizzato in Excel?

" ma in realtà sono stringhe " = & Gt; cosa significa? Come sai che sono davvero stringhe?

" Se guardo la cella di formato " = & Gt; qual è la "cella formato" " ???

'... in Excel, dice che il tipo è " testo "' = & Gt; Per favore, spiega.

" Ancora la cella HSSF pensa che sia numerica. " = & Gt; vuoi dire che the_cell.getCellType () restituisce Cell.CELL_TYPE_NUMERIC?

" Come posso ottenere il valore come stringa? " = & Gt; se è NUMERICO, ottieni il valore numerico usando the_cell.getNumericCellValue (), quindi formattalo come una stringa come desideri.

" Se provo a usare cell.getRichStringValue, ottengo un'eccezione; " = & Gt; quindi non è una stringa.

" if cell.toString, non è lo stesso valore del foglio Excel. " = & Gt; quindi cell.toString () non lo formatta nel modo in cui Excel lo formatta.

Qualunque euristica euristica utilizzi per determinare il tipo è irrilevante per te. È il RISULTATO di quella decisione come archiviato nel file e rivelato da getCellType () che conta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top