Spreadsheet

TsgcHTMLComponent_Spreadsheet : une grille avec formules pour les applications web Delphi, C++ Builder et .NET. Les utilisateurs saisissent des valeurs et des formules comme dans Excel, le serveur les calcule, et chaque modification arrive dans votre code avant d'être conservée.

TsgcHTMLComponent_Spreadsheet

Posez-le sur un formulaire, remplissez sa feuille dans le code et affichez-le. Chaque modification part au serveur, qui la vérifie, recalcule les cellules qui en dépendent et répond avec les cellules modifiées. Il n'y a pas de moteur de formules dans le navigateur, donc Delphi et .NET calculent les mêmes valeurs.

Classe du composant

TsgcHTMLComponent_Spreadsheet, avec le modèle de feuille TsgcHTMLSpreadsheetSheet dans sa propriété Sheet

Rendu

Une grille virtualisée avec une barre d'outils, une barre de formule et une barre d'état, en JavaScript et CSS purs, sans bibliothèque externe

Langages

Delphi, C++ Builder, .NET

Remplissez la feuille, conservez les modifications, partagez-la en direct

Définissez des cellules dans le code avec SetCellByName. OnCellChange vérifie et enregistre chaque cellule qu'un utilisateur modifie, et avec LiveSync l'hôte diffuse GetLiveSyncFragmentHTML après une modification, de sorte que chaque page ouverte recharge les cellules modifiées.

uses
  sgcHTML_Formula, sgcHTML_Component_Spreadsheet, sgcHTMX_Engine_Server;

// Sur le formulaire : un TsgcHTMLComponent_Spreadsheet (Spreadsheet1) avec
// LiveSync = True, et le TsgcHTMX_Engine_Server (HTMXEngine1) de la page

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;

// Chaque cellule qu'un utilisateur modifie : saisie, collage, recopie ou effacement
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 ligne de titre reste telle quelle
  else
    StoreCell(sgcHTMLCellName(aRow, aCol), aNewRaw);   // votre propre stockage : une table, un fichier
end;

// Le changement est appliqué et recalculé : prévenez chaque page ouverte
procedure TMainModule.Spreadsheet1Change(Sender: TObject;
  aSheet: TsgcHTMLSpreadsheetSheet);
begin
  HTMXEngine1.BroadcastFragment(Spreadsheet1.GetLiveSyncFragmentHTML);
end;

// GET /budget.xlsx : la feuille sous forme de classeur, avec formules et styles
procedure TMainModule.ExportBudget(aStream: TStream);
begin
  Spreadsheet1.SaveToXLSX(aStream);
end;
@* Views/Sheets/Budget.cshtml : le budget partagé de l'équipe *@
@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 : vérifier et conserver une cellule
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 : appliqué et recalculé, chaque page ouverte recharge les cellules modifiées
public void Changed(object Sender, TsgcHTMLSpreadsheetSheet aSheet)
{
    _ = hub.BroadcastAsync(((TsgcHTMLComponent_Spreadsheet)Sender).GetLiveSyncFragmentHTML());
}

// OnGetSheet : une feuille par utilisateur
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);

Ce que vos utilisateurs obtiennent

Le clavier, le presse-papiers et les formules qu'ils connaissent d'Excel, sur une feuille unique que votre serveur conserve.

Formules

Une cellule qui commence par = est une formule : les opérateurs + - * / ^ % &, les comparaisons, les parenthèses, les références de cellule et les plages comme A1:C5, avec des parties absolues écrites $A$1, A$1 ou $A1. La priorité des opérateurs et la conversion du texte en nombre fonctionnent comme dans Excel. Les erreurs s'affichent #DIV/0!, #VALUE!, #REF!, #NAME?, #NUM! et #N/A, et #CIRC! marque une cellule dans une référence circulaire.

Fonctions mathématiques, logiques et de texte

Mathématiques et statistiques : SUM, AVERAGE, MIN, MAX, COUNT, COUNTA, COUNTBLANK, PRODUCT, ROUND, ROUNDUP, ROUNDDOWN, INT, MOD, ABS, SQRT, POWER, PI. Logique et information : IF, IFERROR, AND, OR, NOT, TRUE, FALSE, ISBLANK, ISNUMBER, ISTEXT, ISERROR. Texte : CONCAT, CONCATENATE, LEN, LEFT, RIGHT, MID, UPPER, LOWER, TRIM, VALUE.

Fonctions de recherche, de date et financières

Conditionnelles : SUMIF, COUNTIF et AVERAGEIF avec des critères comme ">10", "<>x" et les jokers * et ?. Recherche : VLOOKUP et HLOOKUP, exacte ou approchée, INDEX et MATCH. Date : DATE, YEAR, MONTH, DAY, TODAY, sur les numéros de série d'Excel. Financières : PMT, FV, PV, NPV. 54 fonctions au total, avec la sémantique d'Excel, et la barre de formule complète leurs noms.

Formats

Gras, italique, alignement, couleur du texte et couleur de remplissage, et un format de nombre par cellule : Standard, Nombre, Monétaire, Pourcentage, Date ou Texte, avec 0 à 10 décimales, un séparateur de milliers, le symbole monétaire et le format de date. L'affichage reprend les séparateurs décimal et de milliers de la locale sgcHTML utilisée lorsque celle-ci les définit.

Clavier comme Excel

Flèches, Tab et Shift+Tab, Entrée et Shift+Entrée, Début, Fin, Ctrl+Début, Ctrl+Fin, Ctrl+flèches, Page précédente et Page suivante. F2 ou la saisie démarre l'édition, Échap annule et Suppr efface. Shift+flèches, Shift+clic ou un glissement de souris sélectionnent une plage, un clic sur un en-tête sélectionne une ligne ou une colonne, Ctrl+D et Ctrl+R recopient vers le bas et vers la droite, et Ctrl+Z et Ctrl+Y annulent et rétablissent les modifications de l'utilisateur.

Barre de formule

La barre de formule affiche le contenu brut de la cellule, et sa zone de nom permet d'aller à une cellule : saisissez B12 et appuyez sur Entrée. Pendant l'édition d'une formule, ses références sont mises en évidence par des couleurs, et l'utilisateur peut cliquer sur des cellules ou faire glisser des plages dedans.

Copier-coller avec Excel et Google Sheets

Copier, couper et coller utilisent du texte séparé par des tabulations, le format que Excel et Google Sheets placent dans le presse-papiers, si bien qu'un bloc de cellules passe de l'un à l'autre dans les deux sens. Une formule copiée dans la feuille puis collée ou recopiée ailleurs voit ses références relatives décalées et ses références absolues conservées.

Insérer et supprimer

Insérez des lignes au-dessus ou en dessous et des colonnes à gauche ou à droite, supprimez des lignes et des colonnes, depuis la barre d'outils ou le menu contextuel d'une cellule ou d'un en-tête. Chaque référence de chaque formule est ajustée comme dans Excel, et une référence à une cellule supprimée devient #REF!. Les colonnes se redimensionnent en faisant glisser le bord de l'en-tête, et des lignes et des colonnes peuvent être figées.

Import et export XLSX

Exporter vers Excel télécharge un .xlsx avec les formules et leurs valeurs, les styles de cellule et les formats de nombre, les largeurs de colonne et les volets figés. Importer lit un .xlsx, avec ses formules et ses styles, ou un .csv, une fois que l'utilisateur a confirmé qu'il remplace la feuille actuelle.

Synchronisation en direct entre utilisateurs

Avec LiveSync, les personnes qui ont la même feuille ouverte voient les modifications des autres : les cellules modifiées par un autre utilisateur se rechargent et clignotent. Chaque modification acceptée incrémente la révision de la feuille, et une page qui a manqué une révision recharge toute la feuille.

Barre d'état et grandes feuilles

La barre d'état affiche la Somme, la Moyenne et le Nombre de la sélection, et un indicateur dit si les modifications sont enregistrées. Seules les lignes et colonnes visibles se trouvent dans la page, donc une feuille de 10 000 lignes sur 104 colonnes défile avec fluidité. Sans JavaScript, la page contient toujours un tableau simple des cellules, lisible par les robots d'indexation.

Accessibilité

La feuille est une grille WAI-ARIA avec le nombre et l'index des lignes et des colonnes, et une région live polie annonce la référence de la cellule et sa valeur. Elle suit le thème de la page, se met en miroir avec dir="rtl", respecte la réduction des animations et fonctionne à la largeur d'un téléphone : défilement tactile, toucher pour sélectionner et double toucher pour modifier.

Propriétés, méthodes & événements clés

Les membres que vous utiliserez le plus souvent.

La feuille

Sheet est un TsgcHTMLSpreadsheetSheet. SetCell(aRow, aCol, aRaw) et SetCellByName('B2', '=A1*2') définissent une cellule, et Raw, Value, Text et Style la lisent. Un raw qui commence par = est une formule et une apostrophe initiale force le texte. Les lignes et colonnes sont numérotées à partir de 0 dans l'API, donc A1 est la ligne 0, colonne 0. Lock et Unlock protègent les modifications faites depuis vos propres threads.

OnCellChange et OnChange

OnCellChange(Sender, aRow, aCol, aOldRaw, aNewRaw, aAccept) s'exécute pour chaque cellule qu'un utilisateur modifie. Modifiez aNewRaw pour corriger la valeur, mettez aAccept à False pour la refuser, ou enregistrez-la. OnChange(Sender, aSheet) suit une fois la modification appliquée et recalculée : l'endroit où diffuser GetLiveSyncFragmentHTML.

Feuilles par utilisateur

OnGetSheet(Sender, aSheet) renvoie la feuille de l'utilisateur à l'origine de la requête. Il est appelé au rendu et à chaque requête, donc un seul composant sert tous les utilisateurs, chacun avec sa propre feuille.

Calcul faisant autorité côté serveur

Le navigateur envoie ce que l'utilisateur a saisi et le serveur fait le reste : il applique la modification, recalcule les cellules qui en dépendent grâce à un graphe de dépendances et ne répond qu'avec les cellules modifiées. Recalculate lance un calcul complet et Evaluate calcule une formule en dehors de toute cellule. Delphi et .NET donnent les mêmes résultats, le même JSON et les mêmes octets XLSX.

Limites de sécurité

Le serveur ne fait jamais confiance au navigateur. Il vérifie ReadOnly, les commutateurs AllowFormulas, AllowFormatting, AllowInsertDelete, AllowImport et AllowExport, les coordonnées par rapport à MaxRows (10000) et MaxCols (104), MaxCells (100000), MaxCellLength (8192) et MaxImportSize (5 Mo), puis appelle OnCellChange pour chaque cellule. OnImport peut refuser un fichier.

Mise en page

RowCount (100) et ColCount (26) dimensionnent la feuille, FrozenRows et FrozenCols figent les titres, DefaultColWidth, RowHeight et CSSHeight définissent les tailles, et ShowToolbar, ShowFormulaBar et ShowStatusBar activent ou désactivent les barres. ExportFileName nomme le classeur téléchargé.

XLSX, JSON, CSV et jeux de données

SaveToXLSX et LoadFromXLSX écrivent et lisent un classeur depuis le code, formules et styles compris. Sur la feuille, SaveToJSON et LoadFromJSON la conservent dans un format JSON unique que Delphi et .NET écrivent octet pour octet à l'identique, SaveToCSV et LoadFromCSV suivent la RFC 4180 avec les valeurs brutes, et LoadFromDataSet charge une ligne d'en-tête et les enregistrements.

Insérer, supprimer et décaler

InsertRows, DeleteRows, InsertCols et DeleteCols(aIndex, aCount) ajustent chaque référence comme dans Excel. ShiftFormula(aFormula, aDeltaRow, aDeltaCol) déplace les références relatives d'une formule et conserve les références absolues, la même règle que celle appliquée par le navigateur au collage et à la recopie.

Sans événement serveur

La feuille envoie ses requêtes au point de terminaison des événements de composants du moteur HTMX, ou à ActionURL. Sans l'un ni l'autre, c'est une simple visionneuse en lecture seule de la feuille.

ASP.NET Core

Dans une vue Razor, le Tag Helper <sgc-spreadsheet> affiche la feuille, et ses requêtes sont traitées par le middleware sgcHTML de UseSgcHtml. Ses attributs sont name, read-only, rows, cols, frozen-rows, frozen-cols, css-height, les commutateurs allow-*, live-sync, action-url et les gestionnaires on-get-sheet, on-cell-change et on-change.

La démo

Demos\60.HTML\01.RunTime\35.Spreadsheet est sgc Sheets, un serveur sur le port 8137 avec trois feuilles : un budget d'équipe que tout le monde modifie en direct, avec des totaux SUM, le pourcentage du total, le format monétaire et un graphique qui se rafraîchit à chaque modification ; une calculatrice de prêt avec une feuille par visiteur, PMT, un tableau d'amortissement recopié vers le bas et un graphique du solde ; et les ventes par région avec SUMIF et VLOOKUP, export et import XLSX. Les versions en mode conception, Lazarus et .NET la reprennent.

Continuez l'exploration

Essayer en ligneVoyez-le dans la démo Tableur, en fonctionnement direct sur le serveur de démos d'eSeGeCe.
Aide en ligneRéférence API complète et guide d'utilisation pour ce composant.
Composant GridLa grille de données pour les jeux de données : tri, filtre, regroupement, édition en ligne et export.
Tous les composants sgcHTMLParcourez la matrice complète des fonctionnalités de plus de 80 composants.
Télécharger la version d'essai gratuiteLa version d'essai de 30 jours fournit les projets de démonstration 60.HTML.
TarifsLicences Single, Team et Site avec code source complet.
Meilleur rapport qualité-prix : All-AccessTous les produits eSeGeCe, Support Premium inclus, à partir de €1,059/an.
Voir les tarifs All-Access

Prêt à démarrer ?

Téléchargez la version d'essai gratuite et commencez à créer des interfaces web en Delphi, C++ Builder et .NET.