web-dev-qa-db-de.com

Wie kann ich numerische Zeichenfolgen in Excel-Zellen als Zeichenfolge (nicht als Zahlen) lesen?

  1. Ich habe eine Excel-Datei mit solchen Inhalten: 

    • A1: SomeString

    • A2: 2

    Alle Felder sind auf das String-Format gesetzt.

  2. Wenn ich die Datei in Java mithilfe von POI lese, wird A2 als numerisches Zellenformat angezeigt.

  3. Das Problem ist, dass der Wert in A2 2 oder 2,0 sein kann (und ich möchte sie unterscheiden können). Ich kann also nicht einfach .toString() verwenden.

Was kann ich tun, um den Wert als Zeichenfolge zu lesen?

130
joycollector

Ich hatte das gleiche Problem. Vor dem Lesen des Zeichenfolgenwerts habe ich cell.setCellType(Cell.CELL_TYPE_STRING); ausgeführt, wodurch das Problem unabhängig davon gelöst wurde, wie der Benutzer die Zelle formatiert hat.

292
wil

Ich glaube nicht, dass wir diesen Unterricht damals hatten, als Sie die Frage stellten, aber heute gibt es eine einfache Antwort.

Sie möchten die DataFormatter-Klasse verwenden. Sie übergeben dies eine Zelle, und es wird empfohlen, eine Zeichenfolge zurückzugeben, die enthält, was Excel für diese Zelle anzeigen würde. Wenn Sie eine Zeichenfolge-Zelle übergeben, erhalten Sie die Zeichenfolge zurück. Wenn Sie eine numerische Zelle mit angewendeten Formatierungsregeln übergeben, wird die Zahl basierend auf ihnen formatiert und die Zeichenfolge zurückgegeben.

In Ihrem Fall würde ich davon ausgehen, dass auf die numerischen Zellen eine Ganzzahl-Formatierungsregel angewendet wird. Wenn Sie DataFormatter bitten, diese Zellen zu formatieren, wird eine Zeichenfolge mit der Ganzzahlzeichenfolge zurückgegeben.

Beachten Sie auch, dass viele Leute vorschlagen, cell.setCellType(Cell.CELL_TYPE_STRING) zu verwenden, aber die Apache POI JavaDocs erklären ganz klar, dass Sie dies nicht tun sollten ! Wenn Sie den Aufruf setCellType ausführen, verlieren Sie die Formatierung. Die javadocs erklären . Die einzige Möglichkeit zur Umwandlung in einen String mit verbleibender Formatierung besteht in der Verwendung der DataFormatter-Klasse .

86
Gagravarr

Der untenstehende Code funktionierte für jede Art von Zelle.

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);

}
44
Vinayak Dornala

Ich würde den folgenden Ansatz empfehlen, wenn das Ändern des Zelltyps unerwünscht ist:

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

NumberToTextConverter kann doppelten Wert unter Verwendung der Regeln von Excel ohne Präzisionsverlust korrekt in einen Text konvertieren.

24

Wie bereits in den JavaDocs des Poi ( https://poi.Apache.org/apidocs/org/Apache/poi/ss/usermodel/Cell.html#setCellType%28int%29 ) erwähnt, verwenden Sie nicht 

cell.setCellType(Cell.CELL_TYPE_STRING);

aber verwenden Sie:

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

Weitere Beispiele auf http://massapi.com/class/da/DataFormatter.html

15
userM1433372

Ja, das funktioniert perfekt

empfohlen:

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

alt:

cell.setCellType(Cell.CELL_TYPE_STRING);

selbst wenn Sie Probleme beim Abrufen eines Werts aus der cell-Formel haben, funktioniert dies immer noch.

5
Rajesh Mbm

Versuchen:

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

Sollte die Zahl korrekt formatieren.

4
iTake

Solange sich die Zelle im Textformat befindet, bevor der Benutzer die Nummer eingibt, können Sie den Wert als POI abrufen. Ein Schlüssel ist, dass wenn ein kleines grünes Dreieck in der oberen linken Ecke der Zelle als Text formatiert ist, Sie dessen Wert als Zeichenfolge abrufen können (das grüne Dreieck erscheint immer dann, wenn etwas als Zahl erscheint.) wird in ein Textformat gezwungen). Wenn Sie über Text-formatierte Zellen verfügen, die Zahlen enthalten, der POI diese Werte jedoch nicht als Zeichenfolgen abrufen kann, gibt es einige Möglichkeiten, die Sie mit den Kalkulationsdaten tun können. 

  • Doppelklicken Sie auf die Zelle, damit sich der Bearbeitungscursor in der Zelle befindet, und klicken Sie dann auf die Eingabetaste (dies kann jeweils nur eine Zelle sein).
  • Verwenden Sie die Textkonvertierungsfunktion von Excel 2007 (die für mehrere Zellen gleichzeitig ausgeführt werden kann).
  • Schneiden Sie die fehlerhaften Werte an einem anderen Ort aus, formatieren Sie die Tabellenzellen als Text und formatieren Sie die zuvor ausgeschnittenen Werte wieder als Unformatierte Werte in den richtigen Bereich.

Wenn Sie einen POI verwenden, um Daten aus einer Excel 2007-Kalkulationstabelle zu erhalten, können Sie die Cell-Klasse 'getRawValue ()' verwenden. Dies ist egal, was das Format ist. Es wird einfach ein String mit den Rohdaten zurückgegeben.

1
Mark Farnsworth

Ich hatte auch ein ähnliches Problem in einem Datensatz mit Tausenden von Zahlen und ich denke, dass ich einen einfachen Weg gefunden habe, um das Problem zu lösen. Ich musste den Apostroph vor eine Zahl einfügen, damit ein separater DB-Import die Zahlen immer als Text sieht. Davor würde die Nummer 8 als 8.0 importiert.

Lösung:

  • Behalten Sie alle Formatierungen als Allgemein bei.
  • Ich gehe davon aus, dass Zahlen in Spalte A ab Zeile 1 gespeichert sind. 
  • Geben Sie in 'in Spalte B' ein und kopieren Sie so viele Zeilen wie nötig. Im Arbeitsblatt wird nichts angezeigt, aber durch Klicken auf die Zelle wird der Apostroph in der Formelleiste angezeigt. 
  • In Spalte C: = B1 & A1. 
  • Wählen Sie alle Zellen in Spalte C aus und führen Sie mit Hilfe der Option Werte ein Einfügen in Spalte D durch.

Hey Presto alle Zahlen aber als Text gespeichert.

0
Mark Holmes

Ich würde lieber den Weg der Antwort des Willens oder Vinayak Dornala gehen, leider beeinflussten sie meine Leistung viel zu sehr ... Ich nahm eineHACKYLösung des impliziten Castings:

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

Ich schlage nicht vor, dass Sie das tun, denn in meiner Situation hat es funktioniert, weil das System funktioniert und ich eine zuverlässige Dateiquelle hatte.

Fußnote: numericColumnIst ein int, das durch Lesen des Headers der verarbeiteten Datei generiert wird.

0
KeaganFouche

getStringCellValue gibt NumberFormatException zurück, wenn der Zelltyp numerisch ist. Wenn Sie den Zellentyp nicht in eine Zeichenfolge ändern möchten, können Sie dies tun.

String rsdata = "";
try {
    rsdata = cell.getStringValue();
} catch (NumberFormatException ex) {
    rsdata = cell.getNumericValue() + "";
}
0
zawhtut
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());
        }

Ich habe es versucht und es funktionierte für mich 

0
Prasanna

Wenn wir den numerischen Zellenwert von MS Excel mithilfe der Apache-POI-Bibliothek lesen, wird er als numerisch gelesen. Aber manchmal möchten wir, dass es als Zeichenfolge gelesen wird (z. B. Telefonnummern usw.). So habe ich es gemacht:

  1. Fügen Sie eine neue Spalte mit der ersten Zelle = CONCATENATE ("!", D2) ein. Ich gehe davon aus, dass D2 die Zell-ID Ihrer Telefonnummernspalte ist. Ziehen Sie die neue Zelle nach oben.

  2. Wenn Sie nun die Zelle mit POI lesen, wird die Formel anstelle des berechneten Werts gelesen. Nun mache folgendes:

  3. Fügen Sie eine weitere Spalte hinzu

  4. Markieren Sie die in Schritt 1 erstellte vollständige Spalte und wählen Sie Bearbeiten -> Kopieren

  5. Gehen Sie zur obersten Zelle der in Schritt 3 erstellten Spalte und wählen Sie Bearbeiten -> Inhalte einfügen

  6. Wählen Sie im geöffneten Fenster das Optionsfeld "Werte"

  7. Wähle "OK"

  8. Jetzt mit POI API lesen ... nach dem Lesen in Java ... einfach das erste Zeichen entfernen, d. H. "!"

0
Asif Shahzad

Viele dieser Antworten beziehen sich auf alte POI-Dokumentationen und -Klassen. Im neuesten POI 3.16 wurde Zelle mit den Int-Typen nicht mehr unterstützt 

Cell.CELL_TYPE_STRING

 enter image description here

Stattdessen kann das CellType-Enum verwendet werden.

CellType.STRING 

Stellen Sie sicher, dass Sie Ihr Pom mit der Poi-Abhängigkeit sowie der Poi-Ooxml-Abhängigkeit auf die neue Version 3.16 aktualisieren. Andernfalls werden Sie weiterhin Ausnahmen erhalten. Ein Vorteil dieser Version ist, dass Sie den Zelltyp zum Zeitpunkt der Erstellung der Zelle angeben können, wodurch alle zusätzlichen Schritte entfallen, die in den vorherigen Antworten beschrieben wurden:

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