Excel como Base de Datos de lectura.
Tags: database, excel, api, spreadsheets
Published: 2021-07-27 00:06:17

Hola a todos, soy Chappie. Y el día de hoy utilizaremos una hoja de cálculo creada en Google Drive como una Base de datos de lectura.
## ¿Por qué?
Hay proyectos pequeños en los que tal vez no necesites hacer consultas o relaciones complicadas, por lo cual es posible que esta solución te pueda servir. De hecho, es muy simple de implementar y lo puedes usar en cualquier entorno de desarrollo, en esta ocasión crearemos un ejemplo sencillo tan solo con HTML y JavaScript. Utilizaremos CSS pero solo para que el ejemplo final se vea estilizado. Así que, empecemos…

### 1. Crear y configurar una hoja de cálculo.
Primero nos dirigimos a Drive y creamos una hoja de cálculo y le colocamos cualquier nombre para tener una idea de que contenido guardará. Luego vamos a configurar nuestra hoja de cálculo. Para ello le damos click a “Archivo” y después click en la opción “Publicar en la web”.

Dejamos las opciones que vienen por defecto y le damos click al botón que dice “Publicar”. Debes revisar que esté publicado todo el documento como página web.
![Publicar en la web](https://imgur.com/EZ4LacY.png)

Ahora vamos a colocar la información que queremos almacenar. Recuerda que la primera fila serán los nombres de las columnas y de la segunda fila para abajo el contenido que deseamos guardar.
![Publicar en la web](https://imgur.com/cXNtHYh.png)

Luego en la parte final veremos que tenemos una pestaña, a esa pestaña le colocaremos un nombre. En mi caso le pondré productos (Este nombre de la pestaña lo usaremos luego).
![Publicar en la web](https://imgur.com/R67jYDM.png)

Si deseas puedes agregar más pestañas dando click al botón +. Para este ejemplo vamos a agregar una pestaña más que contendrá la información de una “empresa”.

Ahora que toda la información de prueba está lista vamos a juntar los datos de este documento que nos servirán para extraer la información  del documento de Excel.

Lo primero es obtener el ID del documento, ese id se encuentra en el enlace (URL) del documento. Exactamente se encuentra entre ‘d/’  y ‘/edit’ en mi caso la que pueden visualizar a continuación: https://docs.google.com/spreadsheets/d/1xjqX3ybnY27E-SNo1qydYNmVYZmuYqK80ohuTsPHbDI/edit

1. ID=1xjqX3ybnY27E-SNo1qydYNmVYZmuYqK80ohuTsPHbDI
2. Pestañas: 
 * productos
 * empresa

Ya que tenemos todo listo vamos a empezar con el código:

### 2. Traer los datos de Excel
Empezamos con la estructura básica HTML:
y antes de la etiqueta `</head>` colocamos la CDN de [TableTop](https://www.npmjs.com/package/tabletop).

```html
<!-- CDN de TableTop -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js'></script>
```

Ahora antes de la etiqueta `</body>` colocaremos el siguiente script. En este script vamos a reemplazar el ID que aparece entre d/ y /pubhtml por nuestro ID. Luego crearemos una función init donde inicializamos [Tabletop](https://www.npmjs.com/package/tabletop) y le pasaremos un key, este será nuestro `publicSpreadsheetUrl` y en callback le pasaremos una función `showInfo` que recibirá data y tabletop. Lo que realmente nos importa ahora es data. Así que haremos un `console.log()` de data, luego a simpleSheet le pasamos como valor `false`. Por último, con la última línea de código le indicamos que ejecute la función `init` cuando la página cargue.

```javascript
<script type='text/javascript'>
        const publicSpreadsheetUrl = 'https://docs.google.com/spreadsheets/d/1xjqX3ybnY27E-SNo1qydYNmVYZmuYqK80ohuTsPHbDI/pubhtml';
 
        function init() {
            Tabletop.init({
                key: publicSpreadsheetUrl,
                callback: showInfo,
                simpleSheet: false
            })
        }
 
        function showInfo(data, tabletop) {
            console.log(data)
        }
 
        window.addEventListener('DOMContentLoaded', init)
</script>
```
Si revisamos la consola podremos visualizar lo siguiente:
![Publicar en la web](https://imgur.com/W7f43WP.png)

Si pueden apreciar aparece un objeto empresa y productos. Tal y como nombramos nuestras pestañas en el documento de excel. Contiene mucha información pero la que nos va a servir por ahora es elements. Por lo que si hacemos un console.log de data.productos.elements vamos a visualizar un arreglo de objetos, que es lo que utilizaremos.

### 3. Mostrar los datos en la página web

Debajo de la etiqueta `<body>` crearemos una estructura básica de una lista de productos

 ```html
<div class="container page-wrapper">
        <div class="page-inner">
            <h1 class="text-center mt-5" id="companyName">Productos de la tienda</h1>
            <div class="row" id="myProducts">
                <div class="el-wrapper">
                    <div class="box-up">
                        <img class="img" src="https://realplaza.vtexassets.com/arquivos/ids/15567689-1600-auto?width=1600&height=auto&aspect=true" alt="">
                        <div class="img-info">
                            <div class="info-inner">
                                <span class="p-name">nombre</span>
                                <span class="p-company">categoria</span>
                            </div>
                            <div class="a-size">Descripción: <span class="size">descripcion</span></div>
                        </div>
                    </div>
 
                    <div class="box-down">
                        <div class="h-bg">
                            <div class="h-bg-inner"></div>
                        </div>
 
                        <a class="cart" href="#">
                            <span class="price">$ 100</span>
                            <span class="add-to-cart">
                                <span class="txt">Agregar</span>
                            </span>
                        </a>
                    </div>
                </div>
            </div>
        </div>
    </div>
```

Arriba de la etiqueta `</head>` pegaremos los [estilos](https://codepen.io/slicecrowd/pen/GWJEZB) y las CDN de [Bootstrap](https://getbootstrap.com/) y [Google Fonts](https://fonts.google.com/):

```html
<!-- CDN de TableTop -->
    <script src='https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js'></script>
    <!-- CDN de Google Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,600" rel="stylesheet">
    <!-- CDN de Bootstrap -->
    <link rel="stylesheet"
        href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
    <!-- Minimalistic & Elegant eCommerce card creada por SilceCrowd
    https://codepen.io/slicecrowd/pen/GWJEZB -->
    <style>
        body,
        html {
            height: 100%;
        }
 
        .d-flex {
            display: -webkit-box;
            display: -ms-flexbox;
            display: flex;
        }
 
        .align-center {
            -webkit-box-align: center;
            -ms-flex-align: center;
            align-items: center;
        }
 
        .flex-centerY-centerX {
            justify-content: center;
            -webkit-box-pack: center;
            -ms-flex-pack: center;
            justify-content: center;
            -webkit-box-align: center;
            -ms-flex-align: center;
            align-items: center;
        }
 
        body {
            background-color: #f7f7f7;
        }
 
        .page-wrapper {
            height: 100%;
            display: table;
        }
 
        .page-wrapper .page-inner {
            display: table-cell;
            vertical-align: middle;
        }
 
        .el-wrapper {
            width: 360px;
            padding: 15px;
            margin: 15px auto;
            background-color: #fff;
        }
 
        .el-wrapper .img {
            object-fit: contain;
            width: 80%;
            height: 80%;
        }
 
        @media (max-width: 991px) {
            .el-wrapper {
                width: 345px;
            }
        }
 
        @media (max-width: 767px) {
            .el-wrapper {
                width: 290px;
                margin: 30px auto;
            }
        }
 
        .el-wrapper:hover .h-bg {
            left: 0px;
        }
 
        .el-wrapper:hover .price {
            left: 20px;
            -webkit-transform: translateY(-50%);
            -ms-transform: translateY(-50%);
            -o-transform: translateY(-50%);
            transform: translateY(-50%);
            color: #818181;
        }
 
        .el-wrapper:hover .add-to-cart {
            left: 50%;
        }
 
        .el-wrapper:hover .img {
            webkit-filter: blur(7px);
            -o-filter: blur(7px);
            -ms-filter: blur(7px);
            filter: blur(7px);
            filter: progid:DXImageTransform.Microsoft.Blur(pixelradius='7', shadowopacity='0.0');
            opacity: 0.4;
        }
 
        .el-wrapper:hover .info-inner {
            bottom: 155px;
        }
 
        .el-wrapper:hover .a-size {
            -webkit-transition-delay: 300ms;
            -o-transition-delay: 300ms;
            transition-delay: 300ms;
            bottom: 50px;
            opacity: 1;
        }
 
        .el-wrapper .box-down {
            width: 100%;
            height: 60px;
            position: relative;
            overflow: hidden;
        }
 
        .el-wrapper .box-up {
            width: 100%;
            height: 300px;
            position: relative;
            overflow: hidden;
            text-align: center;
        }
 
        .el-wrapper .img {
            padding: 20px 0;
            -webkit-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
        }
 
        .h-bg {
            -webkit-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            width: 660px;
            height: 100%;
            background-color: #3f96cd;
            position: absolute;
            left: -659px;
        }
 
        .h-bg .h-bg-inner {
            width: 50%;
            height: 100%;
            background-color: #464646;
        }
 
        .info-inner {
            -webkit-transition: all 400ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 400ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 400ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 400ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            position: absolute;
            width: 100%;
            bottom: 25px;
        }
 
        .info-inner .p-name,
        .info-inner .p-company {
            display: block;
        }
 
        .info-inner .p-name {
            font-family: 'PT Sans', sans-serif;
            font-size: 18px;
            color: #252525;
        }
 
        .info-inner .p-company {
            font-family: 'Lato', sans-serif;
            font-size: 12px;
            text-transform: uppercase;
            color: #8c8c8c;
        }
 
        .a-size {
            -webkit-transition: all 300ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 300ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 300ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 300ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            position: absolute;
            width: 100%;
            bottom: -20px;
            font-family: 'PT Sans', sans-serif;
            color: #828282;
            opacity: 0;
        }
 
        .a-size .size {
            color: #252525;
        }
 
        .cart {
            display: block;
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            font-family: 'Lato', sans-serif;
            font-weight: 700;
        }
 
        .cart .price {
            -webkit-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-delay: 100ms;
            -o-transition-delay: 100ms;
            transition-delay: 100ms;
            display: block;
            position: absolute;
            top: 50%;
            left: 50%;
            -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
            -o-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
            font-size: 16px;
            color: #252525;
        }
 
        .cart .add-to-cart {
            -webkit-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-delay: 100ms;
            -o-transition-delay: 100ms;
            transition-delay: 100ms;
            display: block;
            position: absolute;
            top: 50%;
            left: 110%;
            -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
            -o-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
        }
 
        .cart .add-to-cart .txt {
            font-size: 12px;
            color: #fff;
            letter-spacing: 0.045em;
            text-transform: uppercase;
            white-space: nowrap;
        }
    </style>

```

Ya que tenemos la estructura básica vamos a colocar la información de una manera dinámica. Como sabemos, en nuestra función `showInfo` data contiene empresa y productos, por lo que podemos hacer una desestructuración:

```javascript
const { productos, empresa } = data;
```

Debajo vamos a hacer referencia al elemento que contendrá todos los productos en este caso esa etiqueta `div` tiene el id myProducts y a la etiqueta `<h1>` con id companyName que tendrá el nombre de la tienda. Luego crearemos una variable que contendrá todo nuestro html de productos y lo declararemos como un template string vacío.

```javascript
myProducts = document.getElementById("myProducts");
 companyName = document.getElementById("companyName");
 
let ProductHTML  = ``;
```

Luego mapearemos todos los productos y le colocaremos la información que deseamos mostrar de los productos así que podemos eliminar la parte del producto del html anterior y lo podemos reemplazar por  una etiqueta de `<p>cargando...</p>`. (Puedes ver a detalle en el código final)

```javascript
productos.elements.map(productos => {
                ProductHTML += `
            <div class="el-wrapper">
                    <div class="box-up">
                        <img class="img" src="${productos.imagen}" alt="">
                        <div class="img-info">
                            <div class="info-inner">
                                <span class="p-name">${productos.nombre}</span>
                                <span class="p-company">${productos.categoria}</span>
                            </div>
                            <div class="a-size">Descripción: <span class="size">${productos.descripcion}</span></div>
                        </div>
                    </div>
 
                    <div class="box-down">
                        <div class="h-bg">
                            <div class="h-bg-inner"></div>
                        </div>
 
                        <a class="cart" href="#">
                            <span class="price">$ ${productos.precio}</span>
                            <span class="add-to-cart">
                                <span class="txt">Agregar</span>
                            </span>
                        </a>
                    </div>
                </div>`
            })

```

Todos esos productos van a ir juntándose en la variable `productsHTML` que declaramos. Cuando el array se termine de recorrer vamos a insertar todo el html de productos y el nombre de la tienda de la siguiente forma:

```javascript
myProducts.innerHTML = productsHTML;
companyName.innerHTML = empresa.elements[0].empresa;
```


## Código final
```html
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Excel como BD</title>
    <!-- CDN de TableTop -->
    <script src='https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.5.1/tabletop.min.js'></script>
    <!-- CDN de Google Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,600" rel="stylesheet">
    <!-- CDN de Bootstrap -->
    <link rel="stylesheet"
        href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
 
    <!-- Minimalistic & Elegant eCommerce card creada por SilceCrowd
    https://codepen.io/slicecrowd/pen/GWJEZB -->
    <style>
        body,
        html {
            height: 100%;
        }
 
        .d-flex {
            display: -webkit-box;
            display: -ms-flexbox;
            display: flex;
        }
 
        .align-center {
            -webkit-box-align: center;
            -ms-flex-align: center;
            align-items: center;
        }
 
        .flex-centerY-centerX {
            justify-content: center;
            -webkit-box-pack: center;
            -ms-flex-pack: center;
            justify-content: center;
            -webkit-box-align: center;
            -ms-flex-align: center;
            align-items: center;
        }
 
        body {
            background-color: #f7f7f7;
        }
 
        .page-wrapper {
            height: 100%;
            display: table;
        }
 
        .page-wrapper .page-inner {
            display: table-cell;
            vertical-align: middle;
        }
 
        .el-wrapper {
            width: 360px;
            padding: 15px;
            margin: 15px auto;
            background-color: #fff;
        }
 
        .el-wrapper .img {
            object-fit: contain;
            width: 80%;
            height: 80%;
        }
 
        @media (max-width: 991px) {
            .el-wrapper {
                width: 345px;
            }
        }
 
        @media (max-width: 767px) {
            .el-wrapper {
                width: 290px;
                margin: 30px auto;
            }
        }
 
        .el-wrapper:hover .h-bg {
            left: 0px;
        }
 
        .el-wrapper:hover .price {
            left: 20px;
            -webkit-transform: translateY(-50%);
            -ms-transform: translateY(-50%);
            -o-transform: translateY(-50%);
            transform: translateY(-50%);
            color: #818181;
        }
 
        .el-wrapper:hover .add-to-cart {
            left: 50%;
        }
 
        .el-wrapper:hover .img {
            webkit-filter: blur(7px);
            -o-filter: blur(7px);
            -ms-filter: blur(7px);
            filter: blur(7px);
            filter: progid:DXImageTransform.Microsoft.Blur(pixelradius='7', shadowopacity='0.0');
            opacity: 0.4;
        }
 
        .el-wrapper:hover .info-inner {
            bottom: 155px;
        }
 
        .el-wrapper:hover .a-size {
            -webkit-transition-delay: 300ms;
            -o-transition-delay: 300ms;
            transition-delay: 300ms;
            bottom: 50px;
            opacity: 1;
        }
 
        .el-wrapper .box-down {
            width: 100%;
            height: 60px;
            position: relative;
            overflow: hidden;
        }
 
        .el-wrapper .box-up {
            width: 100%;
            height: 300px;
            position: relative;
            overflow: hidden;
            text-align: center;
        }
 
        .el-wrapper .img {
            padding: 20px 0;
            -webkit-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
        }
 
        .h-bg {
            -webkit-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 800ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            width: 660px;
            height: 100%;
            background-color: #3f96cd;
            position: absolute;
            left: -659px;
        }
 
        .h-bg .h-bg-inner {
            width: 50%;
            height: 100%;
            background-color: #464646;
        }
 
        .info-inner {
            -webkit-transition: all 400ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 400ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 400ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 400ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            position: absolute;
            width: 100%;
            bottom: 25px;
        }
 
        .info-inner .p-name,
        .info-inner .p-company {
            display: block;
        }
 
        .info-inner .p-name {
            font-family: 'PT Sans', sans-serif;
            font-size: 18px;
            color: #252525;
        }
 
        .info-inner .p-company {
            font-family: 'Lato', sans-serif;
            font-size: 12px;
            text-transform: uppercase;
            color: #8c8c8c;
        }
 
        .a-size {
            -webkit-transition: all 300ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 300ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 300ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 300ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            position: absolute;
            width: 100%;
            bottom: -20px;
            font-family: 'PT Sans', sans-serif;
            color: #828282;
            opacity: 0;
        }
 
        .a-size .size {
            color: #252525;
        }
 
        .cart {
            display: block;
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            font-family: 'Lato', sans-serif;
            font-weight: 700;
        }
 
        .cart .price {
            -webkit-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-delay: 100ms;
            -o-transition-delay: 100ms;
            transition-delay: 100ms;
            display: block;
            position: absolute;
            top: 50%;
            left: 50%;
            -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
            -o-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
            font-size: 16px;
            color: #252525;
        }
 
        .cart .add-to-cart {
            -webkit-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            -moz-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            -o-transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            transition: all 600ms cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -moz-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            -o-transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            transition-timing-function: cubic-bezier(0, 0, 0.18, 1);
            /* ease-out */
            -webkit-transition-delay: 100ms;
            -o-transition-delay: 100ms;
            transition-delay: 100ms;
            display: block;
            position: absolute;
            top: 50%;
            left: 110%;
            -webkit-transform: translate(-50%, -50%);
            -ms-transform: translate(-50%, -50%);
            -o-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
        }
 
        .cart .add-to-cart .txt {
            font-size: 12px;
            color: #fff;
            letter-spacing: 0.045em;
            text-transform: uppercase;
            white-space: nowrap;
        }
    </style>
</head>
 
<body>
 
 
 
    <div class="container page-wrapper">
        <div class="page-inner">
            <h1 class="text-center mt-5" id="companyName">Productos de la tienda</h1>
            <div class="row" id="myProducts">
                <p>Cargando...</p>
            </div>
        </div>
    </div>
 
 
    <script type='text/javascript'>
        var publicSpreadsheetUrl = 'https://docs.google.com/spreadsheets/d/1xjqX3ybnY27E-SNo1qydYNmVYZmuYqK80ohuTsPHbDI/pubhtml';
 
        function init() {
            Tabletop.init({
                key: publicSpreadsheetUrl,
                callback: showInfo,
                simpleSheet: false
            })
        }
 
        function showInfo(data, tabletop) {
            const { productos, empresa } = data;
            // console.log(productos.elements)
            myProducts = document.getElementById("myProducts");
            companyName = document.getElementById("companyName");
 
            let productsHTML = ``;
 
            productos.elements.map(productos => {
                productsHTML += `
            <div class="el-wrapper">
                    <div class="box-up">
                        <img class="img" src="${productos.imagen}" alt="">
                        <div class="img-info">
                            <div class="info-inner">
                                <span class="p-name">${productos.nombre}</span>
                                <span class="p-company">${productos.categoria}</span>
                            </div>
                            <div class="a-size">Descripción: <span class="size">${productos.descripcion}</span></div>
                        </div>
                    </div>
 
                    <div class="box-down">
                        <div class="h-bg">
                            <div class="h-bg-inner"></div>
                        </div>
 
                        <a class="cart" href="#">
                            <span class="price">$ ${productos.precio}</span>
                            <span class="add-to-cart">
                                <span class="txt">Agregar</span>
                            </span>
                        </a>
                    </div>
                </div>`
            })
 
            myProducts.innerHTML = productsHTML;
            companyName.innerHTML = empresa.elements[0].empresa;
        }
 
        window.addEventListener('DOMContentLoaded', init)
    </script>
</body>
 
</html>

```