S-017 – Integración de PivotGrid de DevExtreme en Svelte

Este componente lo he utilizado con PHPRunner (aplicación Web) y para las aplicaciones de Gestión en una oficina es una solución muy potente, pues se asemeja a una tabla Pivot de Excel, pero con muchas ventajas:

  • Recupera los datos de la base de datos de forma inmediata y su visualización es muy potente.
  • Desde la propia visualización se puede realizar actualizaciones en los registros, de tal forma que la gestión es mucho más rápida y dinámica.

Como en otras librerías, se ha hecho 2 integraciones:

  • CDN – Utilizando la versión de librería de JavaScript.
  • NPM – Utilizando la versión de módulo de JavaScript.

Objetivo

Disponer de una solución potente de Pivot Grid para el entorno de Svelte y aprovechando el conocimiento previo, verificar que la solución de DevExpress, aunque en la web no lo indiquen, se puede utilizar perfectamente con Svelte 5.

DEMO

Solución Técnica

La integración del tipo CDN ya la hemos tratado en artículos anteriores y su característica es carga de la librería en el fichero «index.html», en este caso:

<!doctype html>
<html lang="es">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>DevExtreme 25.2 + Svelte 5</title>

    <!-- DevExtreme 25.2 CSS -->
    <link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/25.2.3/css/dx.light.css" />
    <!-- <link rel="stylesheet" href="./DevExtreme/dx.light.css" /> -->

    <!-- DevExtreme 25.2 JS -->
    <script src="https://cdn3.devexpress.com/jslib/25.2.3/js/dx.all.js"></script>
    <!-- <script src="./DevExtreme/dx.all.js"></script> -->

    <script src="https://cdn3.devexpress.com/jslib/25.2.3/js/localization/dx.messages.es.js"></script>
    <!-- <script src="./DevExtreme/dx.messages.es.js"></script> -->

    <!-- ExcelJS + FileSaver (exportación) -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.3.0/exceljs.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> 

    <!-- Svelte -->
    <script type="module" src="/src/main.js"></script>
  </head>
  <body class="dx-viewport">
    <div id="app"></div>
  </body>
</html>

Es reseñable que en estas últimas versiones han cambiado las librerías para exportar a Excel, siendo ahora las de ExcelJS + FileSaver. Importante para que os funcione el botón de exportación del Grid a Excel.

Para la opción de NPM estos son los módulos instalados.

En ambas instalaciones hemos configurado la aplicación para que funcione en español, lo que hará más sencillo utilizar este ejemplo para aquellos que su idioma no sea el inglés.

El código de tratamiento es muy similar en versión CDN y NPM, por ello, sólo os dejaré el código de NPM.

main.jsdevextreme-license.jsApp.svelte
import { mount } from 'svelte'
import './app.css'
import App from './App.svelte'


// Método de carga de la licencia de DevExtreme, necesario para evitar el mensaje de advertencia en la consola del navegador.
import config from "devextreme/core/config"; 
import { licenseKey } from "./devextreme-license.js"; 
config({ licenseKey });

const app = mount(App, {
  target: document.getElementById('app'),
})

export default app
export const licenseKey = "TU_CLAVE_DE_LICENCIA";
<script>
  import { onMount } from "svelte";

  // PivotGrid
  import PivotGrid from "devextreme/ui/pivot_grid";

  // Chart
  import Chart from "devextreme/viz/chart";

  // Exportación
  import ExcelJS from "exceljs";
  import { saveAs } from "file-saver";

  // Localización
  import esMessages from "devextreme/localization/messages/es.json";
  import { loadMessages, locale } from "devextreme/localization";

  loadMessages(esMessages);
  locale("es");

  import { sales } from "./data.js";

  let pivotEl;
  let chartEl;

  let pivotGrid;
  let chart;
  let data = $state(sales);

  onMount(() => {
    chart = new Chart(chartEl, {
      commonSeriesSettings: { type: "line" },
      tooltip: {
        enabled: true,
        format: { type: "currency", currency: "EUR", precision: 0 }
      },
      size: { height: 200 }
    });

    pivotGrid = new PivotGrid(pivotEl, {
      allowSortingBySummary: true,
      allowFiltering: true,
      showBorders: true,

      fieldChooser: {
        enabled: true,
        height: 400,
        title: "Selector de campos"
      },

      export: { enabled: true },

      onExporting(e) {
        const workbook = new ExcelJS.Workbook();
        const worksheet = workbook.addWorksheet("Pivot");

        import("devextreme/excel_exporter").then(({ exportPivotGrid }) => {
          exportPivotGrid({
            component: e.component,
            worksheet
          }).then(() => {
            workbook.xlsx.writeBuffer().then((buffer) => {
              saveAs(new Blob([buffer]), "pivot.xlsx");
            });
          });
        });

        e.cancel = true;
      },

      dataSource: {
        fields: [
          { caption: "Región", dataField: "region", area: "row" },
          { caption: "Ciudad", dataField: "city", area: "row" },

          // Año → Trimestre → Mes (filtros OK)
          { dataField: "date", dataType: "date", area: "column", groupInterval: "year", caption: "Año" },
          { dataField: "date", dataType: "date", area: "column", groupInterval: "quarter", caption: "Trimestre" },
          { dataField: "date", dataType: "date", area: "column", groupInterval: "month", caption: "Mes" },

          {
            caption: "Total",
            dataField: "amount",
            dataType: "number",
            summaryType: "sum",
            area: "data",
            format: {
              formatter(value) {
                if (value == null) return "";
                return new Intl.NumberFormat("es-ES", {
                  useGrouping: true, // separador de miles
                  // style: "currency",
                  // currency: "EUR",
                  minimumFractionDigits: 0,
                  maximumFractionDigits: 0
                }).format(value);
              }
            }
          }
        ],
        store: data
      }
    });

    pivotGrid.bindChart(chart, {
      dataFieldsDisplayMode: "splitPanes",
      alternateDataFields: false
    });

    none_demo();
  });

  $effect(() => {
    if (pivotGrid) {
      pivotGrid.option("dataSource.store", data);
    }
  });

  function none_demo() {
    const botones = document.querySelectorAll('div[style*="cursor: pointer"]');
    botones.forEach((boton) => {
      boton.click();
    });
  }

</script>

<div bind:this={chartEl}></div>
<div bind:this={pivotEl} style="height:600px;"></div>

En los ficheros «main.js» y «dexextreme-license.js», se configura cómo debe registrarse la licencia de la librería.

En el fichero «App.svelte» está el ejemplo básico. Para hacerlo un poco más complejo y vistoso, he puesto un gráfico básico asociado a los datos del PivotGrid. Son funciones básicas, en el fabricantes puedes analizar mejor las posibilidades del producto y también en la guía 82, donde incluso está la edición de los registros del grid.

Os dejo los fuentes para que los podáis descargar y modificar/adaptar a vuestras necesidades

Adjuntos

Archivo Tamaño de archivo Descargas
zip pivotgrid2-svelte 24 KB 1
zip pivotgrid-svelte 36 KB 1

Blog personal para facilitar soporte gratuito a usuarios de React y PHPRunner