Domanda

  1. Ho file excel con tali contenuti:

    • A1: SomeString

    • A2: 2

    Tutti i campi sono impostati in formato stringa.

  2. Quando ho letto il file in Java utilizzando POI, si dice che è in formato A2 cella numerica.

  3. Il problema è che il valore in A2 può essere 2 o 2.0 (e voglio essere in grado di distinguere loro) quindi non posso semplicemente usare .toString().

Che cosa posso fare per leggere il valore come stringa?

È stato utile?

Soluzione

Ho avuto lo stesso problema. Ho fatto cell.setCellType(Cell.CELL_TYPE_STRING); prima di leggere il valore della stringa, che ha risolto il problema a prescindere da come l'utente formattato della cella.

Altri suggerimenti

Non credo che abbiamo avuto questa classe indietro quando lei ha chiesto la questione, ma oggi c'è una risposta facile.

Che cosa si vuole fare è utilizzare il DataFormatter classe . Si passa questo una cella, e fa del suo meglio per restituire una stringa contenente ciò che Excel si dovrebbe mostrare per quella cella. Se si passa una cella di stringa, si otterrà la corda. Se si passa una cella numerica con regole di formattazione applicate, sarà formato il numero basata su di essi e vi darà la corda.

Per il vostro caso, mi piacerebbe pensare che le cellule numerici hanno una regola di formattazione intero applicato a loro. Se chiedete DataFormatter formattare quelle cellule, che ti do indietro una stringa con la stringa intero in esso.

Si noti inoltre che molte persone suggeriscono di fare cell.setCellType(Cell.CELL_TYPE_STRING), ma il JavaDocs Apache POI abbastanza chiaramente che non si deve fare questo ! Facendo la chiamata setCellType perderà la formattazione, come il javadocs spiegano l'unico modo per convertire in una stringa con formattazione restante è quello di utilizzare il class DataFormatter .

Il codice di seguito ha lavorato per me per qualsiasi tipo di cellula.

InputStream inp =getClass().getResourceAsStream("filename.xls"));
Workbook wb = WorkbookFactory.create(inp);
DataFormatter objDefaultFormat = new DataFormatter();
FormulaEvaluator objFormulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) wb);

Sheet sheet= wb.getSheetAt(0);
Iterator<Row> objIterator = sheet.rowIterator();

while(objIterator.hasNext()){

    Row row = objIterator.next();
    Cell cellValue = row.getCell(0);
    objFormulaEvaluator.evaluate(cellValue); // This will evaluate the cell, And any type of cell will return string value
    String cellValueStr = objDefaultFormat.formatCellValue(cellValue,objFormulaEvaluator);

}

Consiglio la seguente approccio quando si modifica il tipo di cella è indesiderabile:

if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
    String str = NumberToTextConverter.toText(cell.getNumericCellValue())
}

NumberToTextConverter in grado di convertire in modo corretto valore doppio di un testo usando le regole di Excel senza perdita di precisione.

Come già accennato nella JavaDocs del POI ( https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html#setCellType%28int%29 ) non utilizzare:

cell.setCellType(Cell.CELL_TYPE_STRING);

ma l'uso:

DataFormatter df = new DataFormatter();
String value = df.formatCellValue(cell);

Ulteriori esempi su http://massapi.com/class/da/DataFormatter.html

Sì, questo funziona perfettamente

consigliato:

        DataFormatter dataFormatter = new DataFormatter();
        String value = dataFormatter.formatCellValue(cell);

antiche:

cell.setCellType(Cell.CELL_TYPE_STRING);

, anche se hai un problema con il recupero di un valore compreso tra cell formula, ancora funziona.

Prova:

new java.text.DecimalFormat("0").format( cell.getNumericCellValue() )

In caso di formattare il numero in modo corretto.

Fino a quando la cellula è in formato testo prima l'utente digita il numero, POI vi permetterà di ottenere il valore come una stringa. Una chiave è che se c'è un piccolo triangolo verde nell'angolo superiore sinistro della cella che è formattato come testo, si sarà in grado di recuperare il suo valore come una stringa (il triangolo verde appare ogni volta che qualcosa che sembra essere un numero è costretto in un formato di testo). Se si dispone di celle di testo formattato che contengono numeri, ma di POI non lascerai si recupera quei valori come stringhe, ci sono alcune cose che potete fare per i dati da fogli per consentire che:

  • Fare doppio clic sulla cella in modo che il cursore di modifica è presente all'interno della cellula, quindi fare clic su Inserisci (che può essere fatto solo una cella alla volta).
  • Utilizza il 2007 funzione di conversione di testo di Excel (che può essere fatto su più celle contemporaneamente).
  • Tagliare i valori offendere in un'altra posizione, riformattare le celle del foglio di calcolo come testo, quindi repaste i valori precedentemente tagliati fuori come Valori non formattati di nuovo nella zona corretta.

Un'ultima cosa che si può fare è che se si sta utilizzando POI per ottenere dati da un foglio di calcolo Excel 2007, è metodo può la classe cellulare 'getRawValue ()'. Questo non importa ciò che il formato è. Sarà semplicemente restituire una stringa con i dati grezzi.

Quando leggiamo il valore numerico delle cellule di MS Excel utilizzando la libreria Apache POI, che lo lesse come numerico. Ma qualche volta vogliamo che letto come stringa (ad esempio numeri di telefono, ecc.) Ecco come ho fatto:

  1. Inserire una nuova colonna con prima cella = CONCATENA ( "!", D2). Presumo D2 è id cella della colonna telefono-numero. Trascinate nuova cella fino alla fine.

  2. Ora, se si legge la cella utilizzando POI, si leggerà la formula invece del valore calcolato. Ora non seguente:

  3. Aggiungi un'altra colonna

  4. Seleziona colonna completo creato nel passaggio 1. e scegliere Composizione> Copia

  5. Torna all'inizio cella della colonna creata nel passaggio 3. Selezionare e Edit-> Incolla speciale

  6. Nella finestra aperta, selezionare "Valori" pulsante di opzione

  7. Selezionare "OK"

  8. Ora leggere utilizzando POI API ... dopo aver letto in Java ... basta rimuovere il primo carattere vale a dire "!"

Ho anche avuto un problema simile su un insieme di dati di migliaia di numeri e penso che ho trovato un modo semplice per risolvere. Avevo bisogno di ottenere l'apostrofo inserita prima di un numero in modo che un'importazione DB separata vede sempre i numeri come testo. Prima di questo il numero 8 sarebbe importato come 8.0.

Soluzione:

  • Tenere tutta la formattazione come generale.
  • numeri Qui io parto dal presupposto sono memorizzati nella colonna A partire da Riga 1.
  • Mettere in 'nella colonna B e copiare le tante righe, se necessario. Nulla appare nel foglio di lavoro, ma cliccando sulla cella si può vedere l'apostophe nella barra della formula.
  • In Colonna C: = B1 e A1.
  • selezionare tutte le celle nella colonna C e fare un Incolla speciale in colonna D utilizzando l'opzione Valori.

Hey Presto tutti i numeri, ma memorizzati come testo.

getStringCellValue ritorna NumberFormatException se il tipo di cellula è numerico. Se non si desidera modificare il tipo di cellula a stringa, si può fare questo.

String rsdata = "";
try {
    rsdata = cell.getStringValue();
} catch (NumberFormatException ex) {
    rsdata = cell.getNumericValue() + "";
}

Molte di queste risposte riferimento vecchia documentazione POI e le classi. Nella più recente POI 3.16, cellulare con i tipi int è stato deprecato

Cell.CELL_TYPE_STRING

entrare descrizione dell'immagine qui

Invece il tipo di cellule enum può essere utilizzato.

CellType.STRING 

Basta essere sicuri di aggiornare il pom con la dipendenza poi così come la dipendenza POI-OOXML alla nuova versione 3.16 altrimenti si continuerà a ottenere eccezioni. Un vantaggio con questa versione è che è possibile specificare il tipo di cella al momento della creazione della cellula eliminando tutti i passaggi aggiuntivi descritti nelle risposte precedenti:

titleRowCell = currentReportRow.createCell(currentReportColumnIndex, CellType.STRING);

Avrei preferito andare via della risposta del wil o Vinayak Dornala, purtroppo effettuate mio rendimento lontano per molto. Sono andato per un hacky la soluzione di fusione implicita:

for (Row row : sheet){
String strValue = (row.getCell(numericColumn)+""); // hack
...

Non suggerisco di fare questo, per la mia situazione ha funzionato a causa della natura di come il sistema ha funzionato e ho avuto una fonte affidabile file.

Nota:     numericColumn È un int che viene generato dalla lettura l'intestazione del file elaborato.

public class Excellib {
public String getExceldata(String sheetname,int rownum,int cellnum, boolean isString) {
    String retVal=null;
    try {
        FileInputStream fis=new FileInputStream("E:\\Sample-Automation-Workspace\\SampleTestDataDriven\\Registration.xlsx");
        Workbook wb=WorkbookFactory.create(fis);
        Sheet s=wb.getSheet(sheetname);
        Row r=s.getRow(rownum);
        Cell c=r.getCell(cellnum);
        if(c.getCellType() == Cell.CELL_TYPE_STRING)
        retVal=c.getStringCellValue();
        else {
            retVal = String.valueOf(c.getNumericCellValue());
        }

Ho provato questo e ha funzionato per me

Abbiamo avuto lo stesso problema e costretti ai nostri utenti di formattare le celle come 'testo' prima l'immissione del valore. In questo modo Excel memorizza correttamente i numeri pari come testo. Se il formato è cambiato in seguito Excel cambia solo il modo in cui viene visualizzato il valore, ma non cambia il modo in cui il valore viene memorizzato meno che il valore viene immesso di nuovo (ad esempio premendo il tasto di ritorno quando nella cella).

o meno Excel correttamente memorizzato il valore come testo è indicato con il piccolo triangolo verde che Excel visualizza nell'angolo superiore sinistro della cella se si pensa che la cella contiene un numero, ma è formattato come testo.

si fa a controllare il foglio di lavoro di Excel in ogni caso? Esiste un modello gli utenti hanno per darvi l'ingresso? Se è così, si può avere formato di codice le celle di input per voi.

Sembra che questo non può essere fatto nella versione corrente di PDI, sulla base del fatto che questo bug:

https://issues.apache.org/bugzilla/show_bug.cgi? id = 46136

è ancora in sospeso.

cell.setCellType (Cell.CELL_TYPE_STRING); sta lavorando bene per me

Cast ad un int poi fare un .toString(). E 'brutto, ma funziona.

Questo ha funzionato perfetto per me.

Double legacyRow = row.getCell(col).getNumericCellValue();
String legacyRowStr = legacyRow.toString();
if(legacyRowStr.contains(".0")){
    legacyRowStr = legacyRowStr.substring(0, legacyRowStr.length()-2);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top