Spreadsheet

TsgcHTMLComponent_Spreadsheet: una cuadrícula con fórmulas para aplicaciones web en Delphi, C++ Builder y .NET. Los usuarios escriben valores y fórmulas como en Excel, el servidor las calcula y cada cambio llega a tu código antes de conservarse.

TsgcHTMLComponent_Spreadsheet

Colócalo en un formulario, rellena su hoja en código y renderízalo. Cada edición va al servidor, que la comprueba, recalcula las celdas que dependen de ella y responde con las celdas que han cambiado. No hay motor de fórmulas en el navegador, así que Delphi y .NET calculan los mismos valores.

Clase del componente

TsgcHTMLComponent_Spreadsheet, con el modelo de hoja TsgcHTMLSpreadsheetSheet en su propiedad Sheet

Renderiza

Una cuadrícula virtualizada con barra de herramientas, barra de fórmulas y barra de estado, en JavaScript y CSS puros y sin ninguna biblioteca externa

Familia

Datos y Tablas

Lenguajes

Delphi, C++ Builder, .NET

Rellena la hoja, conserva los cambios, compártela en vivo

Establece celdas en código con SetCellByName. OnCellChange comprueba y guarda cada celda que cambia un usuario, y con LiveSync el host difunde GetLiveSyncFragmentHTML tras un cambio, de modo que cada página abierta recarga las celdas que han cambiado.

uses
  sgcHTML_Formula, sgcHTML_Component_Spreadsheet, sgcHTMX_Engine_Server;

// En el formulario: un TsgcHTMLComponent_Spreadsheet (Spreadsheet1) con
// LiveSync = True, y el TsgcHTMX_Engine_Server (HTMXEngine1) de la página

procedure TMainModule.DataModuleCreate(Sender: TObject);
begin
  Spreadsheet1.Sheet.SetCellByName('A1', 'Item');
  Spreadsheet1.Sheet.SetCellByName('B1', 'Amount');
  Spreadsheet1.Sheet.SetCellByName('A2', 'Rent');
  Spreadsheet1.Sheet.SetCellByName('B2', '1200');
  Spreadsheet1.Sheet.SetCellByName('A3', 'Travel');
  Spreadsheet1.Sheet.SetCellByName('B3', '340.50');
  Spreadsheet1.Sheet.SetCellByName('A4', 'Total');
  Spreadsheet1.Sheet.SetCellByName('B4', '=SUM(B2:B3)');
end;

// Cada celda que cambia un usuario: escribir, pegar, rellenar o borrar
procedure TMainModule.Spreadsheet1CellChange(Sender: TObject; aRow, aCol: Integer;
  const aOldRaw: string; var aNewRaw: string; var aAccept: Boolean);
begin
  if aRow = 0 then
    aAccept := False   // la fila de títulos se queda como está
  else
    StoreCell(sgcHTMLCellName(aRow, aCol), aNewRaw);   // tu propio almacén: una tabla, un archivo
end;

// El cambio está aplicado y recalculado: avisa a cada página abierta
procedure TMainModule.Spreadsheet1Change(Sender: TObject;
  aSheet: TsgcHTMLSpreadsheetSheet);
begin
  HTMXEngine1.BroadcastFragment(Spreadsheet1.GetLiveSyncFragmentHTML);
end;

// GET /budget.xlsx: la hoja como libro, con fórmulas y estilos
procedure TMainModule.ExportBudget(aStream: TStream);
begin
  Spreadsheet1.SaveToXLSX(aStream);
end;
@* Views/Sheets/Budget.cshtml: el presupuesto compartido del equipo *@
@model BudgetModel

<sgc-spreadsheet name="budget" rows="40" cols="14"
                 frozen-rows="1" frozen-cols="1" css-height="560px"
                 allow-insert-delete="false" live-sync="true"
                 on-get-sheet="Model.GetSheet"
                 on-cell-change="Model.CellChange"
                 on-change="Model.Changed" />
using esegece.sgcWebSockets;

var budget = new TsgcHTMLComponent_Spreadsheet();
budget.LiveSync = true;
budget.Sheet.SetCellByName("A1", "Item");
budget.Sheet.SetCellByName("B1", "Amount");
budget.Sheet.SetCellByName("A2", "Rent");
budget.Sheet.SetCellByName("B2", "1200");
budget.Sheet.SetCellByName("B3", "340.50");
budget.Sheet.SetCellByName("A4", "Total");
budget.Sheet.SetCellByName("B4", "=SUM(B2:B3)");
budget.OnCellChange += CellChange;
budget.OnChange += Changed;

// OnCellChange: comprobar y conservar una celda
public void CellChange(object Sender, int aRow, int aCol, string aOldRaw,
    ref string aNewRaw, ref bool aAccept)
{
    if (aRow == 0)
        aAccept = false;
    else
        store.Save(aRow, aCol, aNewRaw);
}

// OnChange: aplicado y recalculado, cada página abierta recarga las celdas que han cambiado
public void Changed(object Sender, TsgcHTMLSpreadsheetSheet aSheet)
{
    _ = hub.BroadcastAsync(((TsgcHTMLComponent_Spreadsheet)Sender).GetLiveSyncFragmentHTML());
}

// OnGetSheet: una hoja por usuario
public void GetSheet(object Sender, ref TsgcHTMLSpreadsheetSheet? aSheet)
{
    aSheet = sheets.ForUser(User.Identity.Name);
}

// GET /budget.xlsx
using var ms = new MemoryStream();
budget.SaveToXLSX(ms);

Lo que obtienen tus usuarios

El teclado, el portapapeles y las fórmulas que conocen de Excel, en una sola hoja que conserva tu servidor.

Fórmulas

Una celda que empieza por = es una fórmula: los operadores + - * / ^ % &, las comparaciones, los paréntesis, las referencias de celda y los rangos como A1:C5, con partes absolutas escritas $A$1, A$1 o $A1. La precedencia y la conversión de texto a número funcionan como en Excel. Los errores se muestran como #DIV/0!, #VALUE!, #REF!, #NAME?, #NUM! y #N/A, y #CIRC! marca una celda con una referencia circular.

Funciones matemáticas, lógicas y de texto

Matemáticas y estadística: SUM, AVERAGE, MIN, MAX, COUNT, COUNTA, COUNTBLANK, PRODUCT, ROUND, ROUNDUP, ROUNDDOWN, INT, MOD, ABS, SQRT, POWER, PI. Lógica e información: IF, IFERROR, AND, OR, NOT, TRUE, FALSE, ISBLANK, ISNUMBER, ISTEXT, ISERROR. Texto: CONCAT, CONCATENATE, LEN, LEFT, RIGHT, MID, UPPER, LOWER, TRIM, VALUE.

Funciones de búsqueda, fecha y financieras

Condicionales: SUMIF, COUNTIF y AVERAGEIF con criterios como ">10", "<>x" y los comodines * y ?. Búsqueda: VLOOKUP y HLOOKUP, exacta o aproximada, INDEX y MATCH. Fecha: DATE, YEAR, MONTH, DAY, TODAY, sobre números de serie de Excel. Financieras: PMT, FV, PV, NPV. En total 54 funciones, con la semántica de Excel, y la barra de fórmulas completa sus nombres.

Formatos

Negrita, cursiva, alineación, color de texto y color de relleno, y un formato de número por celda: General, Número, Moneda, Porcentaje, Fecha o Texto, con de 0 a 10 decimales, un separador de millares, el símbolo de moneda y el formato de fecha. La visualización toma los separadores decimal y de millares de la configuración regional de sgcHTML en uso cuando esta los define.

Teclado como Excel

Flechas, Tab y Shift+Tab, Enter y Shift+Enter, Inicio, Fin, Ctrl+Inicio, Ctrl+Fin, Ctrl+flechas, RePág y AvPág. F2 o escribir inicia la edición, Esc cancela y Supr borra. Shift+flechas, Shift+clic o un arrastre del ratón seleccionan un rango, un clic en un encabezado selecciona una fila o una columna, Ctrl+D y Ctrl+R rellenan hacia abajo y hacia la derecha, y Ctrl+Z y Ctrl+Y deshacen y rehacen las ediciones del propio usuario.

Barra de fórmulas

La barra de fórmulas muestra el contenido sin procesar de la celda, y su cuadro de nombres salta a una celda: escribe B12 y pulsa Enter. Mientras se edita una fórmula, sus referencias se resaltan en colores, y el usuario puede hacer clic en celdas o arrastrar rangos hacia ella.

Copiar y pegar con Excel y Google Sheets

Copiar, cortar y pegar usan texto separado por tabuladores, el formato que Excel y Google Sheets ponen en el portapapeles, de modo que un bloque de celdas se mueve entre ellos en ambas direcciones. Una fórmula copiada dentro de la hoja y pegada o rellenada en otro lugar tiene sus referencias relativas desplazadas y conserva las absolutas.

Insertar y eliminar

Inserta filas encima o debajo y columnas a la izquierda o a la derecha, elimina filas y columnas, desde la barra de herramientas o el menú contextual de una celda o de un encabezado. Cada referencia de cada fórmula se ajusta como en Excel, y una referencia a una celda eliminada pasa a ser #REF!. Las columnas se redimensionan arrastrando el borde del encabezado, y se pueden inmovilizar filas y columnas.

Importación y exportación XLSX

Exportar a Excel descarga un .xlsx con las fórmulas y sus valores, los estilos de celda y los formatos de número, los anchos de columna y los paneles inmovilizados. Importar lee un .xlsx, con sus fórmulas y estilos, o un .csv, cuando el usuario confirma que sustituye la hoja actual.

Sincronización en vivo entre usuarios

Con LiveSync, las personas que tienen abierta la misma hoja ven los cambios de las demás: las celdas que otro usuario cambió se recargan y parpadean. Cada cambio aceptado incrementa la revisión de la hoja, y una página que se perdió una revisión vuelve a cargar la hoja completa.

Barra de estado y hojas grandes

La barra de estado muestra Suma, Promedio y Contar de la selección, y un indicador dice si los cambios están guardados. Solo las filas y columnas visibles están en la página, así que una hoja de 10.000 filas por 104 columnas se desplaza con fluidez. Sin JavaScript la página sigue conteniendo una tabla simple con las celdas, legible por los rastreadores.

Accesibilidad

La hoja es una cuadrícula WAI-ARIA con recuentos e índices de filas y columnas, y una región en vivo educada anuncia la referencia de la celda y su valor. Sigue el tema de la página, se refleja con dir="rtl", respeta el movimiento reducido y funciona en pantallas de móvil: desplazamiento táctil, tocar para seleccionar y doble toque para editar.

Propiedades, métodos y eventos clave

Los miembros que más vas a usar.

La hoja

Sheet es un TsgcHTMLSpreadsheetSheet. SetCell(aRow, aCol, aRaw) y SetCellByName('B2', '=A1*2') establecen una celda, y Raw, Value, Text y Style la leen. Un raw que empieza por = es una fórmula y un apóstrofo inicial fuerza texto. Las filas y columnas empiezan en 0 en la API, así que A1 es la fila 0, columna 0. Lock y Unlock protegen los cambios hechos desde tus propios hilos.

OnCellChange y OnChange

OnCellChange(Sender, aRow, aCol, aOldRaw, aNewRaw, aAccept) se ejecuta por cada celda que cambia un usuario. Cambia aNewRaw para corregir el valor, pon aAccept a False para rechazarlo, o guárdalo. OnChange(Sender, aSheet) sigue una vez aplicado y recalculado el cambio: el lugar para difundir GetLiveSyncFragmentHTML.

Hojas por usuario

OnGetSheet(Sender, aSheet) devuelve la hoja del usuario que hace la petición. Se llama al renderizar y en cada petición, así que un solo componente sirve a todos los usuarios, cada uno con su propia hoja.

Cálculo con autoridad en el servidor

El navegador envía lo que el usuario escribió y el servidor hace el resto: aplica el cambio, recalcula las celdas que dependen de él mediante un grafo de dependencias y responde solo con las celdas que han cambiado. Recalculate ejecuta un cálculo completo y Evaluate calcula una fórmula fuera de cualquier celda. Delphi y .NET dan los mismos resultados, el mismo JSON y los mismos bytes XLSX.

Límites de seguridad

El servidor nunca confía en el navegador. Comprueba ReadOnly, los interruptores AllowFormulas, AllowFormatting, AllowInsertDelete, AllowImport y AllowExport, las coordenadas frente a MaxRows (10000) y MaxCols (104), MaxCells (100000), MaxCellLength (8192) y MaxImportSize (5 MB), y después llama a OnCellChange por cada celda. OnImport puede rechazar un archivo.

Diseño

RowCount (100) y ColCount (26) dimensionan la hoja, FrozenRows y FrozenCols fijan los títulos, DefaultColWidth, RowHeight y CSSHeight establecen los tamaños, y ShowToolbar, ShowFormulaBar y ShowStatusBar activan o desactivan las barras. ExportFileName da nombre al libro descargado.

XLSX, JSON, CSV y conjuntos de datos

SaveToXLSX y LoadFromXLSX escriben y leen un libro desde código, con fórmulas y estilos incluidos. En la hoja, SaveToJSON y LoadFromJSON la conservan en un único formato JSON que Delphi y .NET escriben byte a byte igual, SaveToCSV y LoadFromCSV usan RFC 4180 con los valores sin procesar, y LoadFromDataSet carga una fila de encabezado y los registros.

Insertar, eliminar y desplazar

InsertRows, DeleteRows, InsertCols y DeleteCols(aIndex, aCount) ajustan cada referencia como en Excel. ShiftFormula(aFormula, aDeltaRow, aDeltaCol) mueve las referencias relativas de una fórmula y conserva las absolutas, la misma regla que aplica el navegador al pegar y rellenar.

Sin un evento de servidor

La hoja envía al endpoint de eventos de componentes del motor HTMX, o a ActionURL. Sin ninguno de los dos es un visor de solo lectura de la hoja.

ASP.NET Core

En una vista Razor, el Tag Helper <sgc-spreadsheet> renderiza la hoja, y sus peticiones las responde el middleware sgcHTML de UseSgcHtml. Sus atributos son name, read-only, rows, cols, frozen-rows, frozen-cols, css-height, los interruptores allow-*, live-sync, action-url y los manejadores on-get-sheet, on-cell-change y on-change.

La demo

Demos\60.HTML\01.RunTime\35.Spreadsheet es sgc Sheets, un servidor en el puerto 8137 con tres hojas: un presupuesto de equipo que todos editan en vivo, con totales SUM, porcentaje del total, formato de moneda y un gráfico que se actualiza en cada cambio; una calculadora de préstamos con una hoja por visitante, PMT, una tabla de amortización rellenada hacia abajo y un gráfico de saldo; y ventas por región con SUMIF y VLOOKUP, exportación e importación XLSX. Las versiones en tiempo de diseño, Lazarus y .NET la reproducen.

Sigue explorando

Pruébalo en líneaMíralo en la demo Hoja de cálculo, funcionando en vivo en el servidor de demos de eSeGeCe.
Ayuda en líneaReferencia completa de la API y guía de uso para este componente.
Componente GridLa cuadrícula de datos para conjuntos de datos: ordenar, filtrar, agrupar, editar en línea y exportar.
Todos los componentes de sgcHTMLExplora la matriz de características completa de más de 80 componentes.
Descargar prueba gratuitaLa prueba de 30 días incluye los proyectos de demostración 60.HTML.
PreciosLicencias Single, Team y Site con todo el código fuente.
La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

¿Listo para empezar?

Descarga la prueba gratuita y empieza a crear interfaces web en Delphi, C++ Builder y .NET.