Skip to content

Nonit0/excell2database

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Proyecto excel2database

Programa ejemplo en Java (Maven) que vuelca un archivo Excel (.xlsx) a una base de datos MySQL y viceversa.

Índice de contenidos

Descripción

Este programa genérico en Java es un ejercicio simple que permite:

  • Leer un libro Excel y volcarlo a una base de datos MySQL.
  • Escribir desde una base de datos MySQL a un fichero Excel.
  • Configurar la conexión y los ficheros de entrada/salida mediante un archivo config.properties.

El programa lee la configuración de la base de datos de un fichero de propiedades de Java y, con Apache POI, procesa las hojas del Excel:

  • El nombre de cada hoja se convierte en el nombre de la tabla.
  • La primera fila define los nombres de los atributos.
  • La segunda fila se utiliza para inferir el tipo de dato de cada columna.

La estructura principal es el libro, que contiene una lista de tablas, y cada tabla contiene tuplas con nombre de campo y tipo de dato.

Uso del programa

Con argumentos:

excel2database -f fichero.xlsx -db agenda

Sin argumentos (modo por defecto): Se utiliza la configuración definida manualmente en el archivo config.properties.

Instalando Java para que funcione

Asegúrate de tener instalado Java (JDK 8 o superior) y Maven.

Cómo crear este proyecto maven desde cero

Instalamos las dependencias Maven:

  • apache poi
  • apache poi ooxml
  • mysql

El archivo de propiedades

Creamos el archivo config.properties:

# 1.- Usuario de la base de datos
user=root
# 2.- Contraseña del usuario de la BBDD
password=s83n38DGB8d72
# 3.- Charset Unicode para evitar problemas con acentos o caracteres especiales
useUnicode=yes
# 4.- Ajuste de zona horaria para JDBC compatible
useJDBCCompliantTimezoneShift=true
# 5.- Puerto de conexión MySQL
port=33307
# 6.- Nombre de la base de datos
database=agenda
# 7.- Host de la BBDD (localhost indica que está en la misma máquina)
host=localhost
# 8.- Tipo de driver de base de datos
driver=MySQL
# 9.- Archivo de salida para exportar datos (BBDD → Excel)
outputFile=datos/salida.xlsx
# 10.- Archivo de entrada para importar datos (Excel → BBDD)
inputFile=datos/entrada.xlsx
# 11.- Desactivar SSL para conexiones locales
useSSL=false
# 12.- Configurar zona horaria del servidor
serverTimezone=Europe/Madrid
# 13.- Permitir recuperación de clave pública (requerido para MySQL 8+)
allowPublicKeyRetrieval=true

# 14.- Acción que se ejecutará al iniciar Excel2Database
# Puede ser "download" (exportar BBDD → Excel)
action=download

# 15.- Acción alternativa para importar Excel → BBDD
# action=save

# 16.- Archivo de Excel que se usará como entrada para "save"
file=datos/entrada/test.xlsx

# 17.- Archivo de Excel donde se guardarán los datos exportados para "download"
fileDownload=datos/salida/salidatest.xlsx

En producción jamás debemos de usar estos parámetros:

  • useSSL=false: No encripta la conexión.
  • allowPublicKeyRetrieval=true: No comprueba el certificado (como el candado rojo del navegador)

Detectando qué tipo de dato hay con Apache POI

Con Apache POI puedes inspeccionar el tipo de dato almacenado en una celda de Excel (.xlsx) y actuar según corresponda. Cuando trabajas con una celda (Cell), POI te permite preguntar su tipo con:

cell.getCellType()

Esto devuelve un valor del enum CellType, que puede ser:

Tipo (CellType) Significado
NUMERIC Número (entero o decimal, o incluso fecha/hora si el formato lo indica)
STRING Texto
BOOLEAN Verdadero/Falso
FORMULA Celda con una fórmula
BLANK Celda vacía
ERROR Celda con error

Excel almacena las fechas y horas como números (un número de días desde el 1/1/1900). Para distinguirlas, Apache POI ofrece un método:

DateUtil.isCellDateFormatted(cell)

Si devuelve true, el contenido es una fecha o una hora, y puedes obtenerla así:

Date fecha = cell.getDateCellValue();

Si no, puedes tratarlo como número:

double valor = cell.getNumericCellValue();

En Excel, todos los números se almacenan como double internamente. No existe distinción “formal” entre enteros y decimales dentro del archivo. Por eso, Apache POI siempre te devuelve NUMERIC y cell.getNumericCellValue() da un double. Como Excel no distingue formalmente entre ellos: ambos son NUMERIC, podemos comprobarlo fácilmente así:

double valor = cell.getNumericCellValue();
if (valor == Math.floor(valor)) {
    System.out.println("Entero: " + (int) valor);
} else {
    System.out.println("Decimal: " + valor);
}

Un ejemplo de cómo hacer la detección sería:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.DateUtil;

public class ExcelUtils {

    private static final double EPSILON = 1e-10;

    /**
     * Devuelve un String indicando el tipo de dato de la celda.
     * Puede ser: Entero, Decimal, Texto, Booleano, Fecha, Vacía, Fórmula, Error
     */
    public static String getTipoDato(Cell cell) {
        if (cell == null) {
            return "Vacía";
        }

        switch (cell.getCellType()) {
            case STRING:
                return "Texto";

            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return "Fecha";
                } else {
                    double valor = cell.getNumericCellValue();
                    if (Math.abs(valor - Math.floor(valor)) < EPSILON) {
                        return "Entero";
                    } else {
                        return "Decimal";
                    }
                }

            case BOOLEAN:
                return "Booleano";

            case FORMULA:
                // Puedes decidir si quieres evaluar la fórmula o solo indicar que es fórmula
                return "Fórmula";

            case BLANK:
                return "Vacía";

            case ERROR:
                return "Error";

            default:
                return "Desconocido";
        }
    }
}

Apéndice: Repaso de SQL

Para crear una base de datos en MySQL hacemos:

create database `agenda`;

Para borrar una base de datos en MySQL hacemos:

drop database `agenda`;
CREATE DATABASE `agenda` COLLATE 'utf16_spanish_ci';

Crear una tabla de personas:

DROP TABLE IF EXISTS `personas`;

CREATE TABLE `personas` (
  `nombre` varchar(100) NOT NULL,
  `apellidos` varchar(300) NOT NULL,
  `email` varchar(100),
  `telefono` varchar(12),
  `genero` enum('FEMENINO','MASCULINO','NEUTRO','OTRO') NOT NULL,
  `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY
) ENGINE='InnoDB';

DROP TABLE IF EXISTS `probando`;

CREATE TABLE `probando` (
  `idprobando` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `probando` VARCHAR(100),
  `movidas` VARCHAR(100),
  `teleco` VARCHAR(100),
  `aaaaa` VARCHAR(100),
  `puesweso` VARCHAR(100)
) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_spanish_ci;


INSERT INTO `personas` (nombre, apellidos, email, telefono, genero)
VALUES
('GABRIEL', 'VAZQUEZ CASTRO', 'gvazcas@mail2webtop.com', '771234646', 'MASCULINO'),
('OSCAR', 'MUÑOZ ORTIZ', 'omunort@mlb.bounce.ed10.net', '684390051', 'MASCULINO'),
('LIDIA', 'IGLESIAS MOYA', 'liglmoy@mail2saudi.com', '717631732', 'FEMENINO'),
('MOHAMED', 'HERRERA MARIN', 'mhermar@interburp.com', '750292099', 'MASCULINO'),
('MARIA SOLEDAD', 'MORENO MORENO', 'mmormor@mail.ru', '720699755', 'NEUTRO'),
('RAMON', 'SANTOS SOTO', 'rsansot@outlook.it', '622708296', 'MASCULINO'),
('MARIA ROSA', 'GARRIDO LEON', 'mgarleo@i.ua', '701354268', 'NEUTRO'),
('PAU', 'PEÑA RODRIGUEZ', 'ppenrod@unforgettable.com', '621041509', 'OTRO'),
('FRANCISCO JOSE', 'CRESPO MARIN', 'fcremar@dfwatson.com', '682207168', 'NEUTRO');

INSERT INTO `probando` (probando, movidas, teleco, aaaaa, puesweso)
VALUES
('prueba1', 'movidas1', 'teleco1', 'aaaaa1', 'puesweso1'),
('prueba2', 'movidas2', 'teleco2', 'aaaaa2', 'puesweso2'),
('prueba3', 'movidas3', 'teleco3', 'aaaaa3', 'puesweso3'),
('prueba4', 'movidas4', 'teleco4', 'aaaaa4', 'puesweso4'),
('prueba5', 'movidas5', 'teleco5', 'aaaaa5', 'puesweso5'),
('prueba6', 'movidas6', 'teleco6', 'aaaaa6', 'puesweso6'),
('prueba7', 'movidas7', 'teleco7', 'aaaaa7', 'puesweso7'),
('prueba8', 'movidas8', 'teleco8', 'aaaaa8', 'puesweso8'),
('prueba9', 'movidas9', 'teleco9', 'aaaaa9', 'puesweso9');


SELECT * FROM `personas` LIMIT 50;

SELECT * FROM `personas` LIMIT 5 OFFSET 10;

Notas finales

# Este repositorio es un ejemplo educativo.

# No usar credenciales en texto plano en producción.

# Se recomienda añadir tests unitarios para validar la conversión Excel ↔ MySQL.

About

Programa en Java para pasar datos de Excell a una Base de datos SQL a través de Apache POI

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages