paint-brush
Importación y exportación de Excel XLSX usando Vue: una guíapor@mesciusinc
Nueva Historia

Importación y exportación de Excel XLSX usando Vue: una guía

por MESCIUS inc.17m2024/06/26
Read on Terminal Reader

Demasiado Largo; Para Leer

Aprenda a importar y exportar archivos Excel XLSX en una aplicación Vue.
featured image - Importación y exportación de Excel XLSX usando Vue: una guía
MESCIUS inc. HackerNoon profile picture

"Se ve muy bien, pero ¿podrías simplemente agregar la importación de Excel?"


Si ha desarrollado software durante mucho tiempo, probablemente haya escuchado esa pregunta de algún gerente más de una vez. Para una multitud sin conocimientos técnicos, solicitar importación/exportación de Excel no parece gran cosa. Qué difícil podría ser, ¿verdad?


Pero con demasiada frecuencia, esta pregunta infunde miedo en los corazones de los desarrolladores. En la mayoría de las plataformas, trabajar con archivos de Excel requiere mucho trabajo. Históricamente, esto ha sido doblemente cierto en la web. Trabajar con datos de Excel en una aplicación web se parece un poco a este cómic de xkcd : "Puede ser difícil explicar la diferencia entre lo fácil y lo prácticamente imposible". Crear su propia hoja de cálculo en el navegador con importación y exportación de Excel parece un problema que requerirá cinco años y un equipo de investigación para resolverlo.


Eso está cambiando. Ahora contamos con bibliotecas listas para usar que le permiten colocar una hoja de cálculo completamente funcional en su aplicación web. SpreadJS es uno de ellos. Veremos cómo tomar una aplicación Vue existente (una aplicación del mundo real que usa una tienda Vuex) y mejorarla usando SpreadJS.


El resto del artículo supone que ya comprende HTML, CSS y JavaScript. También se supone que tiene conocimientos prácticos del marco de JavaScript progresivo de Vue.js para crear una interfaz de usuario web. Será útil si ha utilizado Vuex para la gestión estatal, pero no se preocupe si no lo ha hecho. Es intuitivo y fácil de entender, y podrás descubrir qué está pasando simplemente leyendo el código si has usado Vue.


En este blog, cubriremos cómo agregar Importación y Exportación de Excel a su aplicación Vue siguiendo estos pasos:


  1. Estructura de la aplicación Vue
  2. Agregue SpreadJS a su aplicación Vue
  3. Agregar exportación de Excel
  4. Agregar importación de Excel
  5. Pruebe su aplicación Vue

La aplicación Vue

La aplicación Vue en la que trabajaremos es un panel de ventas sencillo con algunos paneles de resumen y una tabla de datos. Es el tipo de aplicación que entra en la categoría "no está mal":


Panel de ventas de Vue


Aunque es sólo una demostración, es exactamente el tipo de aplicación que los desarrolladores web empresariales deben crear. También es exactamente el tipo de aplicación a la que normalmente se nos pide que agreguemos la funcionalidad de Excel, por lo que será un ejemplo perfecto para el resto de este artículo.


El código de esta aplicación se puede encontrar aquí .


Si desea ver cómo crear una aplicación Vue desde cero, consulte esta guía de inicio rápido .


Para preparar el escenario, el panel es una aplicación de una sola página creada con Vue. Utiliza las mejores y más recientes prácticas de Vue : componentes de un solo archivo y un almacén de datos de Vuex. También utiliza Bootstrap para sus componentes CSS y su sistema de cuadrícula.


Bootstrap no es tan popular como solía ser, pero en realidad, Bootstrap todavía está en todas partes, especialmente en aplicaciones web empresariales donde generalmente se necesita soporte de Excel. Apostaríamos a que muchas aplicaciones web empresariales nuevas seguirán usando Bootstrap en 2030.


Si prefieres usar Bulma o Tachyons en tus aplicaciones habilitadas para hojas de cálculo, ¡adelante! SpreadJS funcionará bien con cualquiera de ellos.

Estructura de la aplicación Vue

Echemos un vistazo a cómo está estructurado el código. Nuestra tienda Vuex y nuestra aplicación Vue están definidas en main.js. Tenemos varios componentes de Vue de un solo archivo, todos ubicados en la carpeta de componentes.


Si miras nuestra tienda Vuex, verás lo siguiente:


 const store = new Vuex.Store({ state: { recentSales } mutations: { UPDATE_RECENT_SALES(state) { state.recentSales.push([]); state.recentSales.pop(); } } });


El estado inicial de nuestra tienda se establece en el valor de RecentSales, un conjunto de datos ficticios que importamos. También tenemos una función que se encarga de actualizar las ventas recientes cuando se modifican.


Espera un minuto. Si solo tenemos un conjunto de datos, ¿cómo generamos tres gráficos y una tabla? Para ver qué está sucediendo, abra el componente Dashboard.vue . En él, verá que se generan varias propiedades calculadas en función de los datos de la tienda Vuex:


 <template> <div style="background-color: #ddd"> <NavBar title="Awesome Dashboard"/> <div class="container"> <div class="row"> <TotalSales :total="totalSales"/> <SalesByCountry :salesData="countrySales"/> <SalesByPerson :salesData="personSales"/> <SalesTable :tableData="salesTableData"/> </div> </div> </div> </template> <script> import NavBar from "./NavBar"; import TotalSales from "./TotalSales"; import SalesByCountry from "./SalesByCountry"; import SalesByPerson from "./SalesByPerson"; import SalesTable from "./SalesTable"; import { groupBySum } from "../util/util"; export default { components: { NavBar, SalesByCountry, SalesByPerson, SalesTable, TotalSales }, computed: { totalSales() { const items = this.$store.state.recentSales; const total = items.reduce((acc, sale) => (acc += sale.value), 0); return parseInt(total); }, chartData() { const items = this.$store.state.recentSales; const groups = groupBySum(items, "country", "value"); return groups; }, personSales() { const items = this.$store.state.recentSales; const groups = groupBySum(items, "soldBy", "value"); return groups; }, salesTableData() { return this.$store.state.recentSales; }, } }; </script>


¡Ahora tiene más sentido! El conjunto de datos único contiene todo lo que necesitamos para generar todos los números y tablas para nuestro panel. Dado que los datos están en una tienda Vuex reactiva, si los datos se actualizan, todos los paneles del panel se actualizarán automáticamente.


Esta reactividad será útil en la siguiente sección cuando reemplacemos nuestra vieja y aburrida tabla estática con una hoja de cálculo editable.

Agregar SpreadJS a su aplicación Vue

¡Aquí es donde comienza la diversión! Tenemos nuestro panel de control, pero queremos eliminar esa vieja y torpe tabla HTML. Así que tendremos que cambiar un poco las cosas. Tenemos un excelente punto de partida, pero debemos ejecutar nuestra aplicación localmente para usar SpreadJS en modo de desarrollo sin licencia.


Puede descargar el código terminado para ver el resultado final.


Comience abriendo el proyecto original sin SpreadJS. Abra una terminal, navegue hasta el directorio donde clonó el repositorio y ejecute 'npm install'. Esto instala las dependencias necesarias para ejecutar la aplicación. Cuando finalice la instalación de la dependencia, ejecute 'npmserve' para ver la aplicación actualizada en acción. Si desea importar específicamente las bibliotecas utilizadas, puede usar este comando:


 npm install @mescius/spread-sheets @mescius/spread-sheets-vue @mescius/spread-excelio file-saver bootstrap


Repasemos los cambios que tendremos que realizar para actualizar nuestra aplicación anterior a su versión nueva y mejorada. Como vamos a reemplazar nuestra tabla de ventas con una hoja de cálculo, colocaremos la hoja en nuestro componente SalesTable.vue existente, pero primero tendremos que deshacernos de nuestra tabla anterior. Una vez que desaparezca, nuestra plantilla SalesTable se verá así:


 <template> <TablePanel title="Recent Sales"> </TablePanel> </template>


Después de eliminar la tabla, tenemos nuestro panel de tabla listo y esperando una hoja de cálculo, ¡así que agreguemos una! Después de agregar una hoja de SpreadJS, nuestra plantilla se verá así:


 <template> <TablePanel title="Recent Sales"> <gc-spread-sheets :hostClass='hostClass' @workbookInitialized='workbookInit'> <gc-worksheet :dataSource='tableData' :autoGenerateColumns='autoGenerateColumns'> <gc-column :width='50' :dataField="'id'" :headerText="'ID'" :visible = 'visible' :resizable = 'resizable' > </gc-column> <gc-column :width='300' :dataField="'client'" :headerText="'Client'" :visible = 'visible' :resizable = 'resizable' > </gc-column> <gc-column :width="350" :headerText="'Description'" :dataField="'description'" :visible = 'visible' :resizable = 'resizable' > </gc-column> <gc-column :width="100" :dataField="'value'" :headerText="'Value'" :visible = 'visible' :formatter = 'priceFormatter' :resizable = 'resizable' > </gc-column> <gc-column :width="100" :dataField="'itemCount'" :headerText="'Quantity'" :visible = 'visible' :resizable = 'resizable' > </gc-column> <gc-column :width="100" :dataField="'soldBy'" :headerText="'Sold By'" :visible = 'visible' :resizable = 'resizable' ></gc-column> <gc-column :width="100" :dataField="'country'" :headerText="'Country'" :visible = 'visible' :resizable = 'resizable' ></gc-column> </gc-worksheet> </gc-spread-sheets> </TablePanel> </template>


Hay mucho que asimilar, así que repasémoslo para comprender qué está sucediendo.


Primero, creamos una hoja de cálculo usando el elemento gc-spread-sheets y vinculándolo a dos de las propiedades de nuestro componente: hostClass y workbookInit.


Dentro de la hoja de cálculo, creamos una nueva hoja de trabajo con el elemento gc-worksheet y la vinculamos a las propiedades tableData y autoGenerateColumns de nuestro componente. Tenga en cuenta que tableData es exactamente el mismo tableData que utilizamos para generar nuestra tabla HTML simple. ¡Podemos poner nuestros datos en SpreadJS tal cual sin necesidad de cambios!


Finalmente, dentro de la hoja de trabajo, definimos columnas que le indican a SpreadJS cómo mostrar nuestros datos. La propiedad dataField nos dice qué propiedad del conjunto de datos subyacente debe mostrar esta columna, y headerText le da a SpreadJS un nombre de columna con un formato agradable para usar. El resto de los enlaces para cada columna son sencillos. La documentación de SpreadJS tiene una lista completa de todo lo que puede pasar a una columna gc.


Entonces, con nuestra plantilla implementada, ¿cuánto código se necesitará para que todo esto funcione? ¡Afortunadamente, no mucho! Aquí está el nuevo código de script de nuestro componente SalesTable.vue :


 import "@mescius/spread-sheets/styles/gc.spread.sheets.excel2016colorful.css"; // SpreadJS imports import GC from "@mescius/spread-sheets"; import "@mescius/spread-sheets-vue"; import Excel from "@mescius/spread-excelio"; import TablePanel from "./TablePanel"; export default { components: { TablePanel }, props: ["tableData"], data(){ return { sheetName: 'Sales Data', hostClass:'spreadsheet', autoGenerateColumns:true, width:200, visible:true, resizable:true, priceFormatter:"$ #.00" } }, methods: { workbookInit: function(_spread_) { this._spread = spread; var self = this; spread.bind(GC.Spread.Sheets.Events.ValueChanged, function () { const store = self.$store; var sheet = self._spread.getSheetFromName("Sales Data"); var newSalesData = sheet.getDataSource(); store.commit('UPDATE_RECENT_SALES', newSalesData); }); } } };


Debido a la simplicidad de Vue, se necesita muy poco código para que esto funcione. Si hay algo aquí con lo que no está familiarizado, la sección 'Componentes en profundidad' de la documentación de Vue explica los componentes de Vue en detalle. Lo único que ha cambiado son algunas importaciones, algunas propiedades de datos y un par de métodos. Las propiedades de los datos deberían resultarle familiares; los vimos hace un momento en la plantilla. Son opciones de configuración que vinculamos a los componentes de nuestra hoja de cálculo SpreadJS.


El método workbookInit es una devolución de llamada que SpreadJS llama cuando se inicializa la hoja. En este método, guardamos nuestro objeto de hoja de cálculo SheetJS como una variable de instancia en nuestro componente para que podamos interactuar con él directamente si es necesario. También agregamos una función vinculante para el evento ValueChanged para actualizar automáticamente los datos cada vez que se cambian los valores en la instancia de SpreadJS.


Un último cambio: le damos a nuestro componente un estilo de alcance para ayudar al estilo de la hoja de cálculo. Vimos esto antes cuando pasamos hostClass al elemento gc-spread-sheets. Dado que hostClass está configurado en 'hoja de cálculo', crearemos una clase CSS llamada hoja de cálculo:


 <style scoped> .spreadsheet { width: 100%; height: 400px; border: 1px solid lightgray; } </style>


En este punto, si no realizamos otros cambios y cargamos nuestro Panel, se verá así:


Nuevo panel de Vue


¡Pero espera hay mas!


¿Recuerda cómo pasamos los datos de nuestra tabla a la hoja de cálculo sin realizar ningún cambio en el conjunto de datos? Ahora que nuestros datos están en una hoja de cálculo, podemos editarlos.


¿Qué pasará si cambiamos el valor de la venta n.° 6 de $35 000 a $3500? Si ingresamos a la hoja y editamos el valor, obtenemos un panel que se ve así:


Panel de control de Vue editado


¡Guau! ¿Qué pasó?


Actualizamos la hoja SpreadJS y actualizó automáticamente nuestra tienda Vuex.


También parece que Ángela pasó de tener un mes de ventas espectacular a uno mediocre. ¡Lo siento, Ángela!


Ahora tenemos un panel mejorado con el que un gerente estaría contento. Pueden modificar los datos y ver la actualización del panel ante sus ojos, pero podemos hacerlo aún mejor agregando la capacidad de importar y exportar archivos de Excel. A continuación, aprenderemos cómo hacerlo.

Agregar exportación de Excel

Agregar la exportación de Excel a nuestra hoja es fácil. Primero, agreguemos un botón de exportación a nuestro panel. Lo colocaremos en la parte inferior de nuestro panel de tabla en el archivo SalesTable.vue , justo después de la etiqueta de cierre gc-spread-sheets:


 … </gc-spread-sheets> <div class="dashboardRow"> <button class="btn btn-primary dashboardButton" @click="exportSheet"> Export to Excel </button> </div> </TablePanel> </template>


Como puede ver, nuestro botón espera un controlador de clic llamado exportSheet. Lo agregaremos en un momento, pero primero importaremos una función de un paquete NPM llamado file-saver:


 import { saveAs } from 'file-saver';


A continuación, agreguemos exportSheet al objeto de métodos de nuestro componente:


 exportSheet: function() { const spread = this._spread; const fileName = "SalesData.xlsx"; //const sheet = spread.getSheet(0); const excelIO = new IO(); const json = JSON.stringify(spread.toJSON({ includeBindingSource: true, columnHeadersAsFrozenRows: true, })); excelIO.save(json, (blob) => { saveAs(blob, fileName); }, function (e) { console.log(e) }); }


Esto es lo que hace el código: primero, obtenemos una referencia a nuestra Hoja de datos de ventas. Como es la única hoja de nuestra hoja de cálculo, se encuentra en el índice 0 y accedemos a ella llamando a getSheet. Esto se puede usar en otra parte de la función si necesitamos interactuar directamente con la hoja.


Luego creamos una instancia de la biblioteca ExcelIO de SpreadJS, convertimos nuestra hoja a JSON y le pedimos a SpreadJS que la guarde. ¡Voilá! ¡Hemos exportado un archivo Excel desde nuestra aplicación Vue habilitada para hojas de cálculo!


Tenga en cuenta que estamos pasando dos opciones de serialización a la llamada toJSON de la hoja: includeBindingSource y columnHeadersAsFrozenRows. Juntas, estas opciones garantizan que los datos que vinculamos a la hoja se exporten correctamente y que la hoja contenga nuestros encabezados de columna. Entonces, mirar el archivo de Excel exportado comprenderá cada columna.

Agregar importación de Excel

A continuación, es hora de agregar la capacidad de importar archivos de Excel.


Justo debajo de nuestro botón de exportación, agregaremos el siguiente código:


 <div> <b>Import Excel File:</b> <div> <input type="file" class="fileSelect" @change='fileChange($event)' /> </div> </div>


Como puede ver, usaremos un selector de archivos HTML estándar y activaremos un método de componente llamado fileChange cuando se seleccione un archivo.


Ahora que hemos agregado la plantilla, agreguemos el controlador de cambios al objeto de métodos de nuestro componente:


 fileChange: function (_e_) { if (this._spread) { const fileDom = e.target || e.srcElement; const excelIO = new Excel.IO(); const spread = this._spread; const store = this.$store; /*const deserializationOptions = { includeBindingSource: true, frozenRowsAsColumnHeaders: true };*/ excelIO.open(fileDom.files[0], (_data_) => { // Used for simply loading the JSON from a file //spread.fromJSON(data, deserializationOptions); var newSalesData = extractSheetData(data); store.commit('IMPORT_RECENT_SALES', newSalesData) }); } }


Importar un archivo de Excel es muy parecido a exportarlo, excepto que es al revés. Una vez elegido un archivo, le pedimos a ExcelIO que lo importe. Cuando termina, pasa la información de la hoja a una función de devolución de llamada como un objeto JavaScript. A continuación, pasamos los datos importados a través de una función personalizada para extraer los datos que necesitamos y luego volver a enviarlos a la tienda Vuex.


Normalmente, importar un archivo es tan simple como llamar al método abierto de ExcelIO pero usando el método del libro "fromJSON". En este caso, solo queremos analizar los datos del archivo importado y actualizar la tienda, que luego actualizará SpreadJS.


En nuestra función extractSheetData, que encontrará en el archivo src/util.util.js, verá que extraemos datos del objeto JavaScript devuelto por ExcelIO y los reestructuramos para que coincidan con la forma de los datos en nuestro Vuex. almacenar.


Nuestra función de importación supone que los datos de la hoja importada tendrán las mismas columnas que nuestro conjunto de datos original. Si alguien carga una hoja de cálculo que no cumple con este requisito, nuestra aplicación no podrá manejarla. Esta es una limitación aceptable en la mayoría de las aplicaciones de línea de negocio. Dado que nuestro panel está diseñado para mostrar un tipo de datos específico, es razonable pedir a los usuarios que proporcionen datos en el formato que espera la aplicación.


Cuando se completa la extracción de datos, llamamos al compromiso en la tienda Vuex y enviamos los datos actualizados de la transacción de ventas. La hoja de SpreadJS y los paneles del panel se actualizan para reflejar los nuevos datos. De hecho, podemos usar una función de mutación diferente para importar en lugar de cambiar un valor para poder agregarlo al archivo main.js como "IMPORT_RECENT_SALES":


 const store = new Vuex.Store({ state: { recentSales }, mutations: { UPDATE_RECENT_SALES(state) { state.recentSales.push([]); state.recentSales.pop(); }, IMPORT_RECENT_SALES(state, sales) { state.recentSales = sales; } } });

Probando su aplicación Vue

Ahora que ha visto el código, probemos la importación y exportación de Excel en nuestra aplicación Vue.


Comience haciendo clic en el botón 'Exportar a Excel'. Luego, su navegador web descargará una hoja de cálculo de Excel que contiene todos los datos que vimos en la hoja de cálculo de nuestro panel.


Abra la hoja en Excel y agregue un par de líneas de datos. Está bien si utiliza nuevos países o nuevos vendedores; Todos los componentes de nuestro tablero pueden soportarlo. Solo tenga cuidado de no cambiar el orden de las columnas o los nombres. Cuando haya terminado, haga clic en el botón "Elegir archivo" en la parte inferior del panel Ventas recientes. Seleccione el archivo de Excel que acaba de editar.


Cuando seleccione el archivo, verá los componentes del panel actualizados.

Conclusión

¡Hemos terminado! Tomamos una aplicación de panel de control Vue normal y le agregamos una hoja de cálculo en vivo. Ahora podemos editar los datos en la hoja y ver cómo se actualiza todo nuestro panel. Nuestro panel mejorado también puede importar y exportar archivos de Excel.


Vue, Vuex y SpreadJS se complementan bien. Con las sencillas plantillas y enlace de datos de Vue, el almacén de datos reactivo de Vuex y las hojas de cálculo interactivas de SpreadJS, se pueden crear aplicaciones empresariales JavaScript complejas en horas.


Por muy bueno que parezca, apenas hemos arañado la superficie de lo que SpreadJS puede hacer. Para comprender mejor lo que SpreadJS puede hacer por usted, consulte las demostraciones de SpreadJS , que incluyen demostraciones completas de las diferentes funciones de SpreadJS, explicaciones y código en vivo que muestra esas funciones. Si desea profundizar en el uso de SpreadJS en sus propias aplicaciones, la documentación de SpreadJS tiene la información que necesita.


Obtenga más información sobre este componente de hoja de cálculo de JavaScript: