Spreadsheet

TsgcHTMLComponent_Spreadsheet: una griglia con formule per applicazioni web in Delphi, C++ Builder e .NET. Gli utenti digitano valori e formule come in Excel, il server le calcola e ogni modifica arriva al tuo codice prima di essere conservata.

TsgcHTMLComponent_Spreadsheet

Mettilo su un form, riempi il suo foglio nel codice e fai il rendering. Ogni modifica va al server, che la controlla, ricalcola le celle che ne dipendono e risponde con le celle modificate. Nel browser non c'è alcun motore di formule, quindi Delphi e .NET calcolano gli stessi valori.

Classe del componente

TsgcHTMLComponent_Spreadsheet, con il modello di foglio TsgcHTMLSpreadsheetSheet nella sua proprietà Sheet

Rendering

Una griglia virtualizzata con barra degli strumenti, barra della formula e barra di stato, in JavaScript e CSS puri e senza librerie esterne

Famiglia

Dati e Tabelle

Linguaggi

Delphi, C++ Builder, .NET

Riempi il foglio, conserva le modifiche, condividilo in tempo reale

Imposta le celle nel codice con SetCellByName. OnCellChange controlla e memorizza ogni cella che un utente modifica, e con LiveSync l'host trasmette GetLiveSyncFragmentHTML dopo una modifica, così ogni pagina aperta ricarica le celle modificate.

uses
  sgcHTML_Formula, sgcHTML_Component_Spreadsheet, sgcHTMX_Engine_Server;

// Sul form: un TsgcHTMLComponent_Spreadsheet (Spreadsheet1) con
// LiveSync = True, e il TsgcHTMX_Engine_Server (HTMXEngine1) della pagina

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;

// Ogni cella che un utente modifica: digitazione, incolla, riempimento o cancellazione
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 riga del titolo resta com'è
  else
    StoreCell(sgcHTMLCellName(aRow, aCol), aNewRaw);   // il tuo archivio: una tabella, un file
end;

// La modifica è applicata e ricalcolata: avvisa ogni pagina aperta
procedure TMainModule.Spreadsheet1Change(Sender: TObject;
  aSheet: TsgcHTMLSpreadsheetSheet);
begin
  HTMXEngine1.BroadcastFragment(Spreadsheet1.GetLiveSyncFragmentHTML);
end;

// GET /budget.xlsx: il foglio come cartella di lavoro, con formule e stili
procedure TMainModule.ExportBudget(aStream: TStream);
begin
  Spreadsheet1.SaveToXLSX(aStream);
end;
@* Views/Sheets/Budget.cshtml: il budget condiviso del team *@
@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: controlla e conserva una cella
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: applicata e ricalcolata, ogni pagina aperta ricarica le celle modificate
public void Changed(object Sender, TsgcHTMLSpreadsheetSheet aSheet)
{
    _ = hub.BroadcastAsync(((TsgcHTMLComponent_Spreadsheet)Sender).GetLiveSyncFragmentHTML());
}

// OnGetSheet: un foglio per utente
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);

Cosa ottengono i tuoi utenti

La tastiera, gli appunti e le formule che conoscono da Excel, su un unico foglio che il tuo server conserva.

Formule

Una cella che inizia con = è una formula: gli operatori + - * / ^ % &, i confronti, le parentesi, i riferimenti di cella e gli intervalli come A1:C5, con parti assolute scritte $A$1, A$1 o $A1. La precedenza e la conversione da testo a numero funzionano come in Excel. Gli errori appaiono come #DIV/0!, #VALUE!, #REF!, #NAME?, #NUM! e #N/A, e #CIRC! contrassegna una cella in un riferimento circolare.

Funzioni matematiche, logiche e di testo

Matematica e statistica: SUM, AVERAGE, MIN, MAX, COUNT, COUNTA, COUNTBLANK, PRODUCT, ROUND, ROUNDUP, ROUNDDOWN, INT, MOD, ABS, SQRT, POWER, PI. Logica e informazioni: IF, IFERROR, AND, OR, NOT, TRUE, FALSE, ISBLANK, ISNUMBER, ISTEXT, ISERROR. Testo: CONCAT, CONCATENATE, LEN, LEFT, RIGHT, MID, UPPER, LOWER, TRIM, VALUE.

Funzioni di ricerca, data e finanziarie

Condizionali: SUMIF, COUNTIF e AVERAGEIF con criteri come ">10", "<>x" e i caratteri jolly * e ?. Ricerca: VLOOKUP e HLOOKUP, esatta o approssimata, INDEX e MATCH. Data: DATE, YEAR, MONTH, DAY, TODAY, sui numeri di serie di Excel. Finanziarie: PMT, FV, PV, NPV. In tutto 54 funzioni, con la semantica di Excel, e la barra della formula ne completa i nomi.

Formati

Grassetto, corsivo, allineamento, colore del testo e colore di riempimento, e un formato numerico per cella: Generale, Numero, Valuta, Percentuale, Data o Testo, con da 0 a 10 decimali, un separatore delle migliaia, il simbolo di valuta e il formato data. La visualizzazione usa i separatori decimale e delle migliaia della locale sgcHTML in uso quando la locale li definisce.

Tastiera come Excel

Frecce, Tab e Shift+Tab, Invio e Shift+Invio, Home, Fine, Ctrl+Home, Ctrl+Fine, Ctrl+frecce, Pag su e Pag giù. F2 o la digitazione avvia la modifica, Esc annulla e Canc cancella. Shift+frecce, Shift+clic o il trascinamento del mouse selezionano un intervallo, un clic su unintestazione seleziona una riga o una colonna, Ctrl+D e Ctrl+R riempiono in basso e a destra, e Ctrl+Z e Ctrl+Y annullano e ripristinano le modifiche dell'utente.

Barra della formula

La barra della formula mostra il contenuto grezzo della cella, e la sua casella del nome salta a una cella: digita B12 e premi Invio. Mentre si modifica una formula, i suoi riferimenti sono evidenziati con colori, e l'utente può fare clic sulle celle o trascinarvi dentro degli intervalli.

Copia e incolla con Excel e Google Sheets

Copia, taglia e incolla usano testo separato da tabulazioni, il formato che Excel e Google Sheets mettono negli appunti, così un blocco di celle si sposta tra l'uno e l'altro in entrambe le direzioni. Una formula copiata nel foglio e incollata o riempita altrove ha i riferimenti relativi spostati e quelli assoluti mantenuti.

Inserisci ed elimina

Inserisci righe sopra o sotto e colonne a sinistra o a destra, elimina righe e colonne, dalla barra degli strumenti o dal menu contestuale di una cella o di un'intestazione. Ogni riferimento di ogni formula viene adattato come in Excel, e un riferimento a una cella eliminata diventa #REF!. Le colonne si ridimensionano trascinando il bordo dell'intestazione, e righe e colonne possono essere bloccate.

Importazione ed esportazione XLSX

Esporta in Excel scarica un .xlsx con le formule e i loro valori, gli stili di cella e i formati numerici, le larghezze delle colonne e i riquadri bloccati. Importa legge un .xlsx, con le sue formule e i suoi stili, o un .csv, una volta che l'utente conferma che sostituisce il foglio corrente.

Sincronizzazione in tempo reale tra utenti

Con LiveSync, le persone che hanno aperto lo stesso foglio vedono le modifiche degli altri: le celle modificate da un altro utente si ricaricano e lampeggiano. Ogni modifica accettata incrementa la revisione del foglio, e una pagina che ha perso una revisione ricarica l'intero foglio.

Barra di stato e fogli grandi

La barra di stato mostra Somma, Media e Conteggio della selezione, e un indicatore dice se le modifiche sono salvate. Nella pagina ci sono solo le righe e le colonne visibili, quindi un foglio di 10.000 righe per 104 colonne scorre in modo fluido. Senza JavaScript la pagina contiene comunque una semplice tabella delle celle, leggibile dai crawler.

Accessibilità

Il foglio è una griglia WAI-ARIA con conteggi e indici di righe e colonne, e una regione live cortese annuncia il riferimento della cella e il suo valore. Segue il tema della pagina, si specchia con dir="rtl", rispetta la riduzione del movimento e funziona alla larghezza di un telefono: scorrimento al tocco, tocco per selezionare e doppio tocco per modificare.

Proprietà, metodi ed eventi principali

I membri che usi più spesso.

Il foglio

Sheet è un TsgcHTMLSpreadsheetSheet. SetCell(aRow, aCol, aRaw) e SetCellByName('B2', '=A1*2') impostano una cella, e Raw, Value, Text e Style la leggono. Un raw che inizia con = è una formula e un apostrofo iniziale forza il testo. Righe e colonne partono da 0 nell'API, quindi A1 è la riga 0, colonna 0. Lock e Unlock proteggono le modifiche fatte dai tuoi thread.

OnCellChange e OnChange

OnCellChange(Sender, aRow, aCol, aOldRaw, aNewRaw, aAccept) viene eseguito per ogni cella che un utente modifica. Cambia aNewRaw per correggere il valore, imposta aAccept a False per rifiutarlo, oppure memorizzalo. OnChange(Sender, aSheet) segue quando la modifica è applicata e ricalcolata: il punto in cui trasmettere GetLiveSyncFragmentHTML.

Fogli per utente

OnGetSheet(Sender, aSheet) restituisce il foglio dell'utente che ha fatto la richiesta. Viene chiamato al rendering e a ogni richiesta, quindi un solo componente serve tutti gli utenti, ognuno con un foglio proprio.

Calcolo autorevole sul server

Il browser invia ciò che l'utente ha digitato e il server fa il resto: applica la modifica, ricalcola le celle che ne dipendono tramite un grafo delle dipendenze e risponde solo con le celle modificate. Recalculate esegue un calcolo completo e Evaluate calcola una formula fuori da qualsiasi cella. Delphi e .NET danno gli stessi risultati, lo stesso JSON e gli stessi byte XLSX.

Limiti di sicurezza

Il server non si fida mai del browser. Controlla ReadOnly, gli interruttori AllowFormulas, AllowFormatting, AllowInsertDelete, AllowImport e AllowExport, le coordinate rispetto a MaxRows (10000) e MaxCols (104), MaxCells (100000), MaxCellLength (8192) e MaxImportSize (5 MB), poi chiama OnCellChange per ogni cella. OnImport può rifiutare un file.

Layout

RowCount (100) e ColCount (26) dimensionano il foglio, FrozenRows e FrozenCols bloccano i titoli, DefaultColWidth, RowHeight e CSSHeight impostano le dimensioni, e ShowToolbar, ShowFormulaBar e ShowStatusBar attivano o disattivano le barre. ExportFileName dà il nome alla cartella di lavoro scaricata.

XLSX, JSON, CSV e dataset

SaveToXLSX e LoadFromXLSX scrivono e leggono una cartella di lavoro dal codice, formule e stili inclusi. Sul foglio, SaveToJSON e LoadFromJSON lo conservano in un unico formato JSON che Delphi e .NET scrivono byte per byte uguale, SaveToCSV e LoadFromCSV usano RFC 4180 con i valori grezzi, e LoadFromDataSet carica una riga di intestazione e i record.

Inserisci, elimina e sposta

InsertRows, DeleteRows, InsertCols e DeleteCols(aIndex, aCount) adattano ogni riferimento come in Excel. ShiftFormula(aFormula, aDeltaRow, aDeltaCol) sposta i riferimenti relativi di una formula e mantiene quelli assoluti, la stessa regola che il browser applica all'incolla e al riempimento.

Senza un evento del server

Il foglio invia le richieste all'endpoint degli eventi dei componenti del motore HTMX, oppure a ActionURL. Senza nessuno dei due è un visualizzatore di sola lettura del foglio.

ASP.NET Core

In una vista Razor, il Tag Helper <sgc-spreadsheet> esegue il rendering del foglio, e le sue richieste sono gestite dal middleware sgcHTML di UseSgcHtml. I suoi attributi sono name, read-only, rows, cols, frozen-rows, frozen-cols, css-height, gli interruttori allow-*, live-sync, action-url e i gestori on-get-sheet, on-cell-change e on-change.

La demo

Demos\60.HTML\01.RunTime\35.Spreadsheet è sgc Sheets, un server sulla porta 8137 con tre fogli: un budget di team che tutti modificano in tempo reale, con totali SUM, percentuale sul totale, formato valuta e un grafico che si aggiorna a ogni modifica; un calcolatore di prestiti con un foglio per visitatore, PMT, una tabella di ammortamento riempita in basso e un grafico del saldo; e le vendite per regione con SUMIF e VLOOKUP, esportazione e importazione XLSX. Le versioni in design time, Lazarus e .NET lo rispecchiano.

Continua a esplorare

Provalo onlineGuardalo nella demo Foglio di calcolo, in esecuzione dal vivo sul server demo di eSeGeCe.
Guida in lineaRiferimento API completo e guida all'uso di questo componente.
Componente GridLa griglia dati per i dataset: ordina, filtra, raggruppa, modifica in linea ed esporta.
Tutti i componenti sgcHTMLEsplora la matrice completa delle funzionalità di oltre 80 componenti.
Scarica la Prova GratuitaLa prova di 30 giorni include i progetti demo 60.HTML.
PrezziLicenze Single, Team e Site con codice sorgente completo.
La scelta più conveniente: All-AccessTutti i prodotti eSeGeCe, con Supporto Premium incluso, a partire da €1,059/anno.
Vedi i prezzi All-Access

Pronto a Iniziare?

Scarica la versione di prova gratuita e inizia a creare interfacce web in Delphi, C++ Builder e .NET.