Spreadsheet

TsgcHTMLComponent_Spreadsheet: een raster met formules voor webtoepassingen in Delphi, C++ Builder en .NET. Gebruikers typen waarden en formules zoals in Excel, de server berekent ze en elke wijziging bereikt je code voordat ze wordt bewaard.

TsgcHTMLComponent_Spreadsheet

Zet hem op een formulier, vul zijn blad in code en render hem. Elke bewerking gaat naar de server, die haar controleert, de cellen herberekent die ervan afhangen en antwoordt met de cellen die zijn gewijzigd. Er is geen formule-engine in de browser, dus Delphi en .NET berekenen dezelfde waarden.

Componentklasse

TsgcHTMLComponent_Spreadsheet, met het bladmodel TsgcHTMLSpreadsheetSheet in de eigenschap Sheet

Rendert

Een gevirtualiseerd raster met een werkbalk, een formulebalk en een statusbalk, in gewoon JavaScript en CSS zonder externe bibliotheek

Talen

Delphi, C++ Builder, .NET

Vul het blad, bewaar de wijzigingen, deel het live

Stel cellen in code in met SetCellByName. OnCellChange controleert en bewaart elke cel die een gebruiker wijzigt, en met LiveSync zendt de host na een wijziging GetLiveSyncFragmentHTML uit, zodat elke geopende pagina de gewijzigde cellen opnieuw laadt.

uses
  sgcHTML_Formula, sgcHTML_Component_Spreadsheet, sgcHTMX_Engine_Server;

// Op het formulier: een TsgcHTMLComponent_Spreadsheet (Spreadsheet1) met
// LiveSync = True, en de TsgcHTMX_Engine_Server (HTMXEngine1) van de 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;

// Elke cel die een gebruiker wijzigt: typen, plakken, doorvoeren of wissen
procedure TMainModule.Spreadsheet1CellChange(Sender: TObject; aRow, aCol: Integer;
  const aOldRaw: string; var aNewRaw: string; var aAccept: Boolean);
begin
  if aRow = 0 then
    aAccept := False   // de titelrij blijft zoals hij is
  else
    StoreCell(sgcHTMLCellName(aRow, aCol), aNewRaw);   // je eigen opslag: een tabel, een bestand
end;

// De wijziging is toegepast en herberekend: waarschuw elke geopende pagina
procedure TMainModule.Spreadsheet1Change(Sender: TObject;
  aSheet: TsgcHTMLSpreadsheetSheet);
begin
  HTMXEngine1.BroadcastFragment(Spreadsheet1.GetLiveSyncFragmentHTML);
end;

// GET /budget.xlsx: het blad als werkmap, met formules en stijlen
procedure TMainModule.ExportBudget(aStream: TStream);
begin
  Spreadsheet1.SaveToXLSX(aStream);
end;
@* Views/Sheets/Budget.cshtml: het gedeelde teambudget *@
@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: één cel controleren en bewaren
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: toegepast en herberekend, elke geopende pagina laadt de gewijzigde cellen opnieuw
public void Changed(object Sender, TsgcHTMLSpreadsheetSheet aSheet)
{
    _ = hub.BroadcastAsync(((TsgcHTMLComponent_Spreadsheet)Sender).GetLiveSyncFragmentHTML());
}

// OnGetSheet: één blad per gebruiker
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);

Wat je gebruikers krijgen

Het toetsenbord, het klembord en de formules die ze kennen uit Excel, op één blad dat je server beheert.

Formules

Een cel die met = begint is een formule: de operatoren + - * / ^ % &, vergelijkingen, haakjes, celverwijzingen en bereiken zoals A1:C5, met absolute delen geschreven als $A$1, A$1 of $A1. Voorrangsregels en de omzetting van tekst naar getal werken zoals in Excel. Fouten verschijnen als #DIV/0!, #VALUE!, #REF!, #NAME?, #NUM! en #N/A, en #CIRC! markeert een cel in een circulaire verwijzing.

Wiskunde-, logica- en tekstfuncties

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

Opzoek-, datum- en financiële functies

Voorwaardelijk: SUMIF, COUNTIF en AVERAGEIF met criteria zoals ">10", "<>x" en de jokertekens * en ?. Opzoeken: VLOOKUP en HLOOKUP, exact of bij benadering, INDEX en MATCH. Datum: DATE, YEAR, MONTH, DAY, TODAY, op Excel-serienummers. Financieel: PMT, FV, PV, NPV. In totaal 54 functies, met de semantiek van Excel, en de formulebalk vult hun namen aan.

Notaties

Vet, cursief, uitlijning, tekstkleur en opvulkleur, en een getalnotatie per cel: Standaard, Getal, Valuta, Percentage, Datum of Tekst, met 0 tot 10 decimalen, een duizendtalscheidingsteken, het valutasymbool en de datumnotatie. De weergave neemt de decimaal- en duizendtalscheidingstekens over van de gebruikte sgcHTML-locale wanneer die ze definieert.

Toetsenbord zoals Excel

Pijltjes, Tab en Shift+Tab, Enter en Shift+Enter, Home, End, Ctrl+Home, Ctrl+End, Ctrl+pijltjes, PageUp en PageDown. F2 of typen start het bewerken, Esc annuleert en Delete wist. Shift+pijltjes, Shift+klik of slepen met de muis selecteren een bereik, een klik op een kop selecteert een rij of een kolom, Ctrl+D en Ctrl+R voeren omlaag en naar rechts door, en Ctrl+Z en Ctrl+Y maken de eigen bewerkingen van de gebruiker ongedaan en opnieuw.

Formulebalk

De formulebalk toont de ruwe inhoud van de cel, en het naamvak springt naar een cel: typ B12 en druk op Enter. Terwijl een formule wordt bewerkt, zijn de verwijzingen in kleur gemarkeerd, en de gebruiker kan op cellen klikken of bereiken erin slepen.

Kopiëren en plakken met Excel en Google Sheets

Kopiëren, knippen en plakken gebruiken door tabs gescheiden tekst, de notatie die Excel en Google Sheets op het klembord zetten, zodat een blok cellen in beide richtingen tussen hen verhuist. Bij een formule die in het blad wordt gekopieerd en elders geplakt of doorgevoerd, worden de relatieve verwijzingen verschoven en de absolute behouden.

Invoegen en verwijderen

Voeg rijen boven of onder en kolommen links of rechts in, verwijder rijen en kolommen, via de werkbalk of het contextmenu van een cel of een kop. Elke verwijzing in elke formule wordt aangepast zoals in Excel, en een verwijzing naar een verwijderde cel wordt #REF!. Kolommen veranderen van breedte door de rand van de kop te slepen, en rijen en kolommen kunnen worden vastgezet.

XLSX-import en -export

Exporteren naar Excel downloadt een .xlsx met de formules en hun waarden, de celstijlen en getalnotaties, de kolombreedtes en de vastgezette deelvensters. Importeren leest een .xlsx, met zijn formules en stijlen, of een .csv, zodra de gebruiker bevestigt dat het het huidige blad vervangt.

Live synchronisatie tussen gebruikers

Met LiveSync zien de mensen die hetzelfde blad open hebben elkaars wijzigingen: de cellen die een andere gebruiker heeft gewijzigd worden opnieuw geladen en knipperen. Elke geaccepteerde wijziging verhoogt de revisie van het blad, en een pagina die een revisie heeft gemist laadt het hele blad opnieuw.

Statusbalk en grote bladen

De statusbalk toont Som, Gemiddelde en Aantal van de selectie, en een indicator geeft aan of de wijzigingen zijn opgeslagen. Alleen de zichtbare rijen en kolommen staan in de pagina, zodat een blad van 10.000 rijen bij 104 kolommen soepel scrolt. Zonder JavaScript bevat de pagina nog steeds een gewone tabel met de cellen, leesbaar voor crawlers.

Toegankelijkheid

Het blad is een WAI-ARIA-raster met aantallen en indexen van rijen en kolommen, en een beleefd live-gebied kondigt de celverwijzing en de waarde aan. Het volgt het paginathema, spiegelt zichzelf onder dir="rtl", respecteert verminderde beweging en werkt op telefoonbreedte: scrollen met aanraking, tikken om te selecteren en dubbeltikken om te bewerken.

Belangrijkste eigenschappen, methoden en gebeurtenissen

De leden die je het vaakst gebruikt.

Het blad

Sheet is een TsgcHTMLSpreadsheetSheet. SetCell(aRow, aCol, aRaw) en SetCellByName('B2', '=A1*2') stellen een cel in, en Raw, Value, Text en Style lezen haar. Een raw die met = begint is een formule en een voorafgaande apostrof dwingt tekst af. Rijen en kolommen beginnen in de API bij 0, dus A1 is rij 0, kolom 0. Lock en Unlock beschermen wijzigingen vanuit je eigen threads.

OnCellChange en OnChange

OnCellChange(Sender, aRow, aCol, aOldRaw, aNewRaw, aAccept) wordt uitgevoerd voor elke cel die een gebruiker wijzigt. Wijzig aNewRaw om de waarde te corrigeren, zet aAccept op False om haar te weigeren, of bewaar haar. OnChange(Sender, aSheet) volgt zodra de wijziging is toegepast en herberekend: de plek om GetLiveSyncFragmentHTML uit te zenden.

Bladen per gebruiker

OnGetSheet(Sender, aSheet) geeft het blad van de gebruiker achter het verzoek terug. Het wordt aangeroepen bij het renderen en bij elk verzoek, zodat één component alle gebruikers bedient, elk met een eigen blad.

Gezaghebbende berekening op de server

De browser stuurt wat de gebruiker typte en de server doet de rest: hij past de wijziging toe, herberekent de cellen die ervan afhangen via een afhankelijkheidsgraaf en antwoordt alleen met de cellen die zijn gewijzigd. Recalculate voert een volledige berekening uit en Evaluate berekent een formule buiten elke cel. Delphi en .NET geven dezelfde resultaten, dezelfde JSON en dezelfde XLSX-bytes.

Beveiligingslimieten

De server vertrouwt de browser nooit. Hij controleert ReadOnly, de schakelaars AllowFormulas, AllowFormatting, AllowInsertDelete, AllowImport en AllowExport, de coördinaten ten opzichte van MaxRows (10000) en MaxCols (104), MaxCells (100000), MaxCellLength (8192) en MaxImportSize (5 MB), en roept dan OnCellChange aan voor elke cel. OnImport kan een bestand weigeren.

Layout

RowCount (100) en ColCount (26) bepalen de afmetingen van het blad, FrozenRows en FrozenCols zetten de titels vast, DefaultColWidth, RowHeight en CSSHeight stellen de formaten in, en ShowToolbar, ShowFormulaBar en ShowStatusBar zetten de balken aan of uit. ExportFileName geeft de gedownloade werkmap een naam.

XLSX, JSON, CSV en datasets

SaveToXLSX en LoadFromXLSX schrijven en lezen een werkmap vanuit code, inclusief formules en stijlen. Op het blad bewaren SaveToJSON en LoadFromJSON het in één JSON-formaat dat Delphi en .NET byte voor byte gelijk schrijven, SaveToCSV en LoadFromCSV gebruiken RFC 4180 met de ruwe waarden, en LoadFromDataSet laadt een koprij en de records.

Invoegen, verwijderen en verschuiven

InsertRows, DeleteRows, InsertCols en DeleteCols(aIndex, aCount) passen elke verwijzing aan zoals in Excel. ShiftFormula(aFormula, aDeltaRow, aDeltaCol) verschuift de relatieve verwijzingen van een formule en behoudt de absolute, dezelfde regel die de browser toepast bij plakken en doorvoeren.

Zonder serverevent

Het blad post naar het events-endpoint van componenten van de HTMX-engine, of naar ActionURL. Zonder een van beide is het een alleen-lezen viewer van het blad.

ASP.NET Core

In een Razor-view rendert de Tag Helper <sgc-spreadsheet> het blad, en zijn verzoeken worden beantwoord door de sgcHTML-middleware van UseSgcHtml. De attributen zijn name, read-only, rows, cols, frozen-rows, frozen-cols, css-height, de allow-*-schakelaars, live-sync, action-url en de handlers on-get-sheet, on-cell-change en on-change.

De demo

Demos\60.HTML\01.RunTime\35.Spreadsheet is sgc Sheets, een server op poort 8137 met drie bladen: een teambudget dat iedereen live bewerkt, met SUM-totalen, percentage van het totaal, valutanotatie en een grafiek die bij elke wijziging wordt ververst; een leningcalculator met een blad per bezoeker, PMT, een omlaag doorgevoerde aflossingstabel en een saldografiek; en verkoop per regio met SUMIF en VLOOKUP, XLSX-export en -import. De versies voor ontwerptijd, Lazarus en .NET spiegelen het.

Blijf verkennen

Online proberenBekijk het in de demo Spreadsheet, live draaiend op de eSeGeCe-demoserver.
Online helpVolledige API-referentie en gebruikshandleiding voor dit component.
Grid-componentHet datagrid voor datasets: sorteren, filteren, groeperen, inline bewerken en exporteren.
Alle sgcHTML-componentenBlader door de volledige functiematrix van 80+ componenten.
Download gratis proefversieDe proefversie van 30 dagen bevat de 60.HTML-demoprojecten.
PrijzenSingle-, Team- en Site-licenties met volledige broncode.
De beste deal: All-AccessElk eSeGeCe-product, inclusief Premium-ondersteuning, vanaf €1,059 per jaar.
Bekijk de All-Access-prijzen

Klaar om te beginnen?

Download de gratis proefversie en begin met het bouwen van web-UI's in Delphi, C++ Builder en .NET.