Pergunta

Eu estou usando HSSF-POI para a leitura de dados do Excel. O problema é que tenho valores em uma célula que se parecem com um número, mas realmente são strings. Se eu olhar para a célula formato no Excel, ele diz que o tipo é "texto". Ainda o celular HSSF acha que é numérico. Como posso obter o valor como uma string?

Se eu tentar usar cell.getRichStringValue, fico com exceção; se cell.toString, não é exatamente o mesmo valor que na folha de Excel.

Editar : até que isso é resolvido, vou usar

new BigDecimal(cell.getNumericCellValue()).toString()
Foi útil?

Solução

Você quer dizer HSSF-POI diz

cell.getCellType() == Cell.CELL_TYPE_NUMERIC

não

Cell.CELL_TYPE_STRING como deveria ser?

Eu acho que é um bug no POI, mas cada célula contém um Variant, e Variant tem um tipo. É meio difícil de fazer um bug lá, então ao invés disso eu acho que Excel usa alguns dados extras ou heurística para relatar o campo como texto. MS habituais maneira, infelizmente.

P.S. Você não pode usar qualquer getString() em um contendo numérico Variant, como a representação binária dos dados Variant depende de seu tipo, e tentar obter uma corda do que é realmente um número resultaria em lixo -., Portanto, a exceção

Outras dicas

A classe que você está procurando em POI é DataFormatter

Quando o Excel grava o arquivo, algumas células são armazenadas como strings literais, enquanto outros são armazenados como números. Para este último, um valor de ponto flutuante que representa a célula é armazenada no arquivo, então quando você perguntar POI para o valor da célula que é o que ele realmente tem.

Às vezes, porém, especialmente quando se faz a extração de texto (mas nem sempre), você quer fazer o valor da célula olhar como ele faz no Excel. Nem sempre é possível conseguir isso exatamente em uma String (preenchimento de espaço não completo, por exemplo), mas a classe DataFormatter vai chegar perto.

Se você é depois de uma série da célula, procurando tanto quanto você tinha que olhar no Excel, basta fazer:

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

O formatador voltará células de corda como está, e para Numeric células aplicará as regras de formatação no estilo com o número da célula

Se os documentos que você estiver analisando estão sempre em um layout específico, você pode alterar o tipo de célula para "string" on the fly e, em seguida, recuperar o valor. Por exemplo, se a coluna 2 deve ser sempre dados de cadeia, defina o tipo de célula a corda e, em seguida, lê-lo com os métodos get do tipo string.

cell.setCellType(Cell.CELL_TYPE_STRING);

Em meus testes, alterando o tipo de célula não modificou o conteúdo da célula, mas lhe permitia ser recuperados com um dos seguintes abordagens:

cell.getStringCellValue();

cell.getRichStringCellValue().getString();

Sem um exemplo de um valor que não é converter corretamente, é difícil saber se isso vai se comportar de forma diferente do que a cell.toString () se aproximar de você descrito na descrição.

Este código abaixo fino trabalha para ler qualquer CellType mas essa célula deve conter valor numérico

new BigDecimal(cell.getNumericCellValue()));

por exemplo.

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

onde GSS variável é do tipo BigDecimal.

Excel irá converter qualquer coisa que se parece com um número ou data ou a hora de um string. Ver MS conhecimentos Artigo de base , que basicamente sugere para introduzir o número com um carácter adicional que torna uma string.

Você provavelmente estão lidando com um problema de Excel. Ao criar a planilha, o tipo de célula padrão é genérico. Com este tipo, Excel adivinha o tipo com base na entrada e este tipo é salvo com cada célula.

Quando você posteriormente alterar o formato da célula de texto, você está apenas mudando o padrão. O Excel não alterar o tipo de cada célula automaticamente. Eu não encontrei uma maneira de fazer isso automaticamente.

Para confirmar isso, você pode ir para o Excel e escreva novamente um dos números e ver se ele de texto em HSSF.

Você também pode olhar para o tipo de célula real usando essa função,

  @Cell("type", A1)

A1 é a célula para o número. Ele mostra "l" para o texto, "v" para os números.

O problema com o Excel é que o formato padrão é genérico. Com este formato Excel armazena números inserido na célula como numérico. Você tem que mudar o formato de texto antes inserindo os valores. Reinserir os valores depois de mudar o formato também funcionará.
Isso vai levar a pequenos triângulos verdes no canto superior esquerdo das células se os olhares de conteúdo como um número para Excel. Se este for o caso, o valor é realmente armazenado como texto.

Com a nova BigDecimal (cell.getNumericCellValue ()). ToString () você ainda vai ter um monte de problemas. Por exemplo, se você identificar números (números de peça por exemplo, ou números de classificação), você provavelmente tem casos que têm zeros à esquerda que vai ser um problema com a abordagem getNumericCellValue ().

Eu tento explicar minuciosamente como criar corretamente o Excel para a festa criar os arquivos que têm de lidar com POI. Se os arquivos são enviados por usuários finais que eu mesmo criei um programa de validação para verificar se há tipos de células esperados se eu sei as colunas com antecedência. Como um subproduto você também pode verificar várias outras coisas dos arquivos fornecidos (por exemplo, são as colunas da direita fornecido ou valores obrigatórios).

"O problema é que tenho valores em uma célula que se parecem com um número" => olhar como o número quando visto no Excel?

"mas realmente são cadeias" => o que isso significa? Como você sabe que eles são realmente cordas?

"Se eu olhar para a célula formato" => o que é "a célula formato" ???

'... no Excel, ele diz que o tipo é "texto"' => Por favor, explique.

"Ainda o celular HSSF acha que é numérico." => Que você quer dizer que the_cell.getCellType () retorna Cell.CELL_TYPE_NUMERIC?

"Como posso obter o valor como uma string?" => Se é NUMERIC, obter o valor numérico usando the_cell.getNumericCellValue (), em seguida, formatá-lo como uma cadeia de qualquer maneira que você quiser.

"Se eu tentar usar cell.getRichStringValue, fico com exceção;" => Por isso não é uma string.

"se cell.toString, não é exatamente o mesmo valor que na folha de Excel." => Assim cell.toString () não formatá-lo da maneira que Excel formata-lo.

Whatever heurística Excel utiliza para determinar o tipo é irrelevante para você. É o resultado dessa decisão como armazenado no arquivo e revelado por getCellType () que importa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top