Como posso ler cordas numéricos em células do Excel como corda (e não números)?

StackOverflow https://stackoverflow.com/questions/1072561

  •  21-08-2019
  •  | 
  •  

Pergunta

  1. Eu tenho arquivo excel com o seguinte conteúdo:

    • A1: SomeString

    • A2: 2

    Todos os campos são definidos para o formato da cadeia.

  2. Quando eu li o arquivo em java usando POI, ele diz que A2 é em formato de célula numérico.

  3. O problema é que o valor em A2 pode ser 2 ou 2.0 (e eu quero ser capaz de distingui-los) para que eu não pode apenas usar .toString().

O que posso fazer para ler o valor como uma string?

Foi útil?

Solução

Eu tive mesmo problema. Eu fiz cell.setCellType(Cell.CELL_TYPE_STRING); antes de ler o valor da cadeia, que resolveu o problema, independentemente de como o usuário formatado da célula.

Outras dicas

Eu não acho que nós tivemos essa classe de volta quando você fez a pergunta, mas hoje há uma resposta fácil.

O que você quer fazer é usar a DataFormatter classe . Você passa essa célula um, e ele faz o seu melhor para fazê-lo retornar uma string contendo o Excel iria mostrar-lhe para essa célula. Se você passar uma célula corda, você vai ter a volta string. Se você passar uma célula numérico com regras de formatação aplicado, ele irá formatar o número com base neles e dar-lhe a volta string.

Para o seu caso, eu assumir que as células numéricas têm um inteiro regra de formatação aplicado a eles. Se você perguntar DataFormatter para formatar as células, ele vai lhe dar de volta uma string com a string inteiro nele.

Além disso, nota que muitas pessoas sugiro fazer cell.setCellType(Cell.CELL_TYPE_STRING), mas o Apache POI JavaDocs muito claramente estado que você não deve fazer isso ! Fazendo a chamada setCellType vai perder a formatação, como os javadocs explicar a única maneira de converter em uma string com a formatação restante é usar o class DataFormatter .

O código a seguir trabalhou para mim em qualquer tipo de célula.

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

}

Eu recomendaria a seguinte abordagem ao modificar tipo de célula é indesejável:

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

NumberToTextConverter pode corretamente converter o valor duplo para um texto usando as regras do Excel sem perda de precisão.

Como já mencionado no JavaDocs do Poi ( https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html#setCellType%28int%29 ) não use:

cell.setCellType(Cell.CELL_TYPE_STRING);

mas o uso:

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

Mais exemplos sobre http://massapi.com/class/da/DataFormatter.html

Sim, isso funciona perfeitamente

recomendado:

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

antiga:

cell.setCellType(Cell.CELL_TYPE_STRING);

mesmo se você tiver um problema com a recuperação de um valor de cell tendo a fórmula, ainda funciona.

Tente:

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

Se formatar o número corretamente.

Enquanto a célula está em formato de texto antes de o usuário digita o número, POI lhe permitirá obter o valor como uma string. Uma chave é que, se há um pequeno triângulo verde no canto superior esquerdo da célula que está formatado como texto, você será capaz de recuperar o seu valor como uma string (o triângulo verde aparece sempre que algo que parece ser um número é coagido a um formato de texto). Se você tiver texto formatado células que contêm números, mas POI não vai deixar você buscar esses valores como strings, existem algumas coisas que você pode fazer para os dados da planilha para permitir que:

  • Clique duas vezes na célula para que o cursor de edição está presente no interior da célula, em seguida, clique em Enter (que pode ser feito apenas uma célula de cada vez).
  • Use a função de conversão de texto Excel 2007 (que pode ser feito em várias células de uma vez).
  • Cortar os valores ofensivo para outro local, reformatar as células da planilha como texto, então repaste previamente cortada valores como Valores não formatadas volta para a área adequada.

Uma última coisa que você pode fazer é que se você estiver usando POI para obter dados de uma planilha do Excel 2007, você pode a classe celular método 'getRawValue ()'. Isso não importa o que o formato é. Ele simplesmente irá retornar uma string com os dados brutos.

Quando lemos valor de célula numérico do MS Excel usando a biblioteca Apache POI, ele lê-lo como numérico. Mas em algum momento nós queremos que ele lida como cordas (por exemplo, números de telefone, etc.). Isto é como eu fiz isso:

  1. Inserir uma nova coluna com primeira célula = CONCATENATE ( "!", D2). Presumo D2 é ID de célula da coluna telefone-número. nova célula arrastar até ao final.

  2. Agora, se você ler a célula usando POI, ele irá ler a fórmula em vez do valor calculado. Agora não seguinte:

  3. Adicionar outra coluna

  4. Selecionar coluna completa criada no passo 1. e escolha Editar-> COPY

  5. Ir para a célula superior da coluna criada no passo 3. e Select Editar-> Colar especial

  6. Na janela aberta, selecione "Valores" botão de rádio

  7. Selecionar "OK"

  8. Agora, leia usando POI API ... depois de ler em Java ... apenas remover o primeiro caractere ou seja "!"

Eu também tive um problema semelhante em um conjunto de dados de milhares de números e eu acho que eu encontrei uma maneira simples de resolver. Eu precisava para obter o apóstrofo inserido antes de um número para que uma importação DB separado sempre vê os números como texto. Antes deste o número 8 será importado como 8.0.

Solução:

  • Mantenha toda a formatação como o general.
  • Números Aqui eu estou supondo que são armazenados na coluna A partir de Row 1.
  • Coloque na 'na coluna B e anote tantas linhas conforme necessário. Nada aparece na planilha, mas clicando na célula você pode ver a apostophe na barra de fórmulas.
  • Na Coluna C: = B1 e A1.
  • Selecione todas as células na coluna C e fazer uma pasta especial na Coluna D usando a opção Valores.

voilá todos os números, mas armazenado como texto.

getStringCellValue retorna NumberFormatException se o tipo de célula é numérico. Se você não quiser alterar o tipo de célula para string, você pode fazer isso.

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

Muitas dessas respostas referência velho documentação POI e classes. No mais novo POI 3,16, celular com os tipos int está obsoleto

Cell.CELL_TYPE_STRING

enter descrição da imagem aqui

Em vez do CellType enum lata ser utilizado.

CellType.STRING 

Apenas certifique-se de atualizar o seu pom com a dependência poi, bem como a dependência poi-OOXML para a nova versão 3.16 caso contrário você vai continuar a receber exceções. Uma vantagem com esta versão é que você pode especificar o tipo de célula no momento é criado a célula eliminando todas as etapas extras descritos nas respostas anteriores:

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

Eu prefiro ir a rota da resposta do wil ou Vinayak Dornala, infelizmente, eles efetuada meu desempenho muito longe para muito. Eu fui para um HACKY solução de conversão implícita:

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

Eu não sugiro que você fizer isso, para a minha situação funcionou por causa da natureza de como o sistema funcionava e eu tinha uma origem de arquivo confiável.

Nota de rodapé: numericColumn É um int que é gerada a partir de ler o cabeçalho do arquivo processado.

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

Eu tentei isso e ele trabalhou para mim

Nós tivemos o mesmo problema e forçou nossos usuários para formatar as células como 'texto' antes introduzir o valor. Dessa forma, o Excel armazena corretamente mesmo os números como texto. Se o formato for alterado depois Excel só muda a forma como o valor é exibido, mas não muda a forma como o valor é armazenado a menos que o valor é inserido novamente (por exemplo, pressionando retorno quando na célula).

Quer ou não Excel corretamente armazenados o valor como texto é indicado pelo pequeno triângulo verde que Excel exibe no canto esquerdo superior da célula se ele acha que a célula contém um número, mas é formatada como texto.

Você controla a planilha excel de qualquer maneira? Existe um modelo que os usuários têm para dar-lhe a entrada? Se assim for, você pode ter formato de código as células de entrada para você.

Parece que este não pode ser feito na versão atual do POI, com base no fato de que este bug:

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

ainda está pendente.

cell.setCellType (Cell.CELL_TYPE_STRING); está funcionando bem para mim

elenco para um int em seguida, fazer uma .toString(). É feio, mas ele funciona.

Este perfeita funcionou para mim.

Double legacyRow = row.getCell(col).getNumericCellValue();
String legacyRowStr = legacyRow.toString();
if(legacyRowStr.contains(".0")){
    legacyRowStr = legacyRowStr.substring(0, legacyRowStr.length()-2);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top