style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

HSSF no tan bueno como esperé

Como en casi todos los proyectos empresariales, nunca falta el cliente que te pide exporte todas las tablas de información a hojas de cálculo (específicamente excel) o importe datos de ellas.

Hace tiempo que utilizo apache poi para resolver esta cuestion, con la cual siempre había trabajado sin problemas. Sin embargo presisamente hoy tuve un problema el cual hizo que me decidiera por cambiar de libreria, lo peor del caso es que el problemita que tuve es realmente tonto.

Resulta que necesito importar datos de una columna en forma de texto. Apache poi maneja varios tipos de celdas dependiendo la información que contiene. Tengo una columna que tiene formato de texto pero contenido numerico, es decir, que las cadenas de cada celda contienen puros dígitos. Cuando intento hacer un cell.getCellString() de la api del apache poi me marca una excepción diciendo que no puedo obtener una string de una celda numérica.... que?? pero si es de tipo texto!, o acaso se asemeja a linux en cuanto a que trata los objetos por el contenido?. Si al contenido de la celda le antepongo un espacio, entonces si puedo obtener el text muy bien. Pero que pasa si son mas de 5 mil registros, le tengo que decir al usuario que debe anteponerles un espacio a cada celda de la columna en específico? por que diantes no solo tiene un cell.toString() ??

bueno solo queria deshacerme de esta pequeña frustación que me causó esa libreria, digo no es que insulte su trabajo mas bien lo agradesco, pero pues es una funcionalidad que uno espera.

bueno pal caso hay otra libreria mucho mas simple de usar y que trae la funcion que necesito:

http://jexcelapi.sourceforge.net/

sobres

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

Poi es libre...

Puedes bajar el código fuente y meterte a la implementación del método toString() y agregar la condición de que si es numérico te devuelva la descripción como cadena...

Given the choice of dancing pigs and security, users will choose dancing pigs, every single time. - Steve Riley

Imagen de Nopalin

Eso deberia hacer

Eso mismo pensé en hacer también, sin embargo mientras buscaba una solución encontre con que otros se han encontrado este problema también y hay quienes pusieron hasta un workaround al problema medio complejo, sin embargo el team del apache poi sigue sin poner esa funcionalidad, entonces es cuando me pregunto el por qué.

Tal vez ese método le agrega una condición que no quieren que lleve su código? funcionalidad muy poca usada? la mera neta ni idea, pero mejor voy a preguntar en su lista de correo antes de... no vaya a ser que boten mi cambio, como le paso a linus cuando envió una mejora de gnome, jejeje

sobres

Imagen de ezamudio

submit

El cambio lo puedes realizar en la versión que tú tienes, si no lo aceptan ni modo, no pasa nada... solamente cada vez que quieras usar una nueva versión de Poi vas a tener que checar si ya hace lo que necesitas o si necesitas volver a modificar la nueva versión (que luego ya es muy rápido porque ya vas a saber dónde está el cambio).

Yo tengo una bronca así con otro software en C al que le hice unos cambios pero para que me los aceptaran los autores tenia que enviar una carta firmada y no se que tanta madre y me dio hueva. Desde entonces cada vez que bajo una versión nueva de ese software le aplico mi cambio para usarla.

El truco es que tanto GPL como ASL te restringen en la distribución del software, no su uso. Es decir puedes bajar Poi y hacerle todo lo que quieras y no tienes que darle nada a nadie, si es para tu uso nada más. Pero si lo redistribuyes (y eso incluye que le instales tu versión modificada a un cliente), tienes que entregar tu fuente modificado, si te lo piden junto con el binario.

Given the choice of dancing pigs and security, users will choose dancing pigs, every single time. - Steve Riley

manejo de datos

Bueno en lo personal la aportacion de apache se me hace maravillosa, yo llevo poco tiempo, utilizandola y me tope con la misma problematica la intentar
leer los inventarios de mis clientes en excel y pasarlos a una base datos relacional utilizando hibernate, la solucion que encontre fue generar una intermediario en mi codigo una calse la cual interpretara al objeto Cell de POI y me devolviera sus metadatos como un simple POJO, de esa manera pude llegar a manipularlo, anque mi pequeña utileria aun tiene muchos detalles, me gustaria poder compartir esta clase que comento con ustedes, ya que me agrada la filosofia Opensource si gustan, que les comprat el codigo completo por afavor haganmelo saber y con todo gusto se los comparto como bien dice el articulo "Catedral y e bazar" con muchos ojos salen a resulucir las pulgas :

  1. import org.apache.poi.ss.usermodel.Cell;;
  2. public class ExcelEntity {
  3. private int row = 0;
  4. private String column = "";
  5. private String value = "";
  6. private String type = "";
  7. public ExcelEntity(int row, String column, Cell cell ){
  8. this.row = row;
  9. this.column = column;
  10. defineType(cell);
  11. }
  12. public int getRow(){
  13. return row;
  14. }
  15. public String getColumn(){
  16. return column;
  17. }
  18. public String getValue(){
  19. return value;
  20. }
  21. public String getType(){
  22. return type;
  23. }
  24. /**
  25. * Este metodo optiene el valor de la celda, asignadolo a un String(value)
  26. * al igual que identifica el tipo de dato al cual pertence la celda
  27. * y lo guarda en una variable tipo String(type) para que al obtener el objeto
  28. * se pueda saber, porque tipo de datos debe ser castado
  29. * VOID = null
  30. * FORMULA = String
  31. * NUMERIC = double
  32. * STRING = String
  33. * @param cell celda optenida de la hoja de calculo
  34. * */
  35. private final void defineType(Cell cell){
  36. if(cell!=null){
  37. switch (cell.getCellType())
  38. {
  39. case Cell.CELL_TYPE_BLANK :
  40. value = "";
  41. type = "VOID";
  42. break;
  43. case Cell.CELL_TYPE_FORMULA :
  44. value = cell.getCellFormula();
  45. type = "FORMULA";
  46. break;
  47. case Cell.CELL_TYPE_NUMERIC :
  48. value = ""+cell.getNumericCellValue();
  49. type = "NUMERIC";
  50. break;
  51. case Cell.CELL_TYPE_STRING :
  52. value = ""+cell.getRichStringCellValue();
  53. type = "STRING";
  54. default :
  55. }
  56. }else{
  57. value = "";
  58. type = "VOID";
  59. }
  60. }
  61. }
Imagen de Nopalin

no tan simple

No he probado tu código tu código todavia, pero lo que veo que haces es que obtienes el valor por el tipo de celda y ese lo conviertes a string, muy válido.

Ein embargo el problema con que yo me encontre es que en una celda que es de tipo texto en excel pero contiene puros números, supongamos un 21 (inclusive esta alienada a la izquierda como tod buen texto), el apache poi me dice que es tipo numérica!! (no he checado el código para saber por que), y si intento hace un cell.getStringValue() me marca una excepción bien docuemntadita. Entonces tengo que obtener el valor numerico y como es un numpero cerrado (no decimales) al hacer un toString me regresa "21.0", la cual no es la cadena que está contenida en la celda y en mi proceso 21.0 es diferente a 21 y pues falla.

Como comenté en mi primer post, cambié de libreria y esta jexcelapi aparte de ser mas ligera, funciona bastante bien.

Ojo, no estoy criticando a apache, solo critico esta falta de funcionalidad en especial en el poi.

sobres

Imagen de ezamudio

No concatenes...

Como diria Mr Garrison "concatenation is bad, m'kay?"

En vez de ""+cell.getNumericCellValue() y ""+cell.getRichStringCellValue(), invoca a toString(). Te ahorras que internamente se cree un StringBuffer y se haga la concatenación de la cadena vacia con la conversión a string del valor de esos dos métodos.

cell.getNumericCellValue().toString()

Si lo estas concatenando por miedo a que vaya a ser nulo, y no quieres meter if's, usa statements condicionales:

value = cell == null ? "" : cell.getNumericCellValue().toString();

en vez de "" puedes poner "null" que es lo que sale ahorita con tu código si cell es nulo.

Given the choice of dancing pigs and security, users will choose dancing pigs, every single time. - Steve Riley

Imagen de benek

Solo una corrección... no

Solo una corrección... no es Garrison, es Mr. Mackey........... mmmm'kay??

Jajajaja, saludos!

--
Javier Benek

Imagen de ezamudio

cierto

Mr Garrison es el de Mr Hat...

Given the choice of dancing pigs and security, users will choose dancing pigs, every single time. - Steve Riley

gracias por la recomendacion

:) gracias por el comentario lo implementare al codigo, siempre me a gsutado estar trabajando en los detalles de mi codigo

Querido amigo Jesus, Tengo

Querido amigo Jesus,

Tengo esta misma necesidad de pasar registros de una tabla en excel a mi base de datos. Podrías compartir conmigo tu código para no intentar re-inventar la rueda?

Muchas gracias de antemano.

John

Imagen de bferro

API Docs

public interface Cell
High level representation of a cell in a row of a spreadsheet.

Cells can be numeric, formula-based or string-based (text). The cell type specifies this.

String cells cannot contain numbers and numeric cells cannot contain strings (at least according to our model).

Client apps should do the conversions themselves.

AYUDA!!!

Quería saber si es posible me facilites tu código, tengo problemas para lograr tratar los datos que se obtienen del excel y así tratarla y generar un xml.

Saludos

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">