Spreadsheet

TsgcHTMLComponent_Spreadsheet: siatka z formułami dla aplikacji webowych w Delphi, C++ Builder i .NET. Użytkownicy wpisują wartości i formuły tak jak w Excelu, serwer je oblicza, a każda zmiana trafia do Twojego kodu, zanim zostanie zachowana.

TsgcHTMLComponent_Spreadsheet

Umieść go na formularzu, wypełnij jego arkusz w kodzie i wyrenderuj. Każda edycja trafia na serwer, który ją sprawdza, przelicza zależne od niej komórki i odpowiada zmienionymi komórkami. W przeglądarce nie ma silnika formuł, więc Delphi i .NET obliczają te same wartości.

Klasa komponentu

TsgcHTMLComponent_Spreadsheet, z modelem arkusza TsgcHTMLSpreadsheetSheet we właściwości Sheet

Renderuje

Wirtualizowana siatka z paskiem narzędzi, paskiem formuły i paskiem stanu, w czystym JavaScripcie i CSS, bez zewnętrznej biblioteki

Rodzina

Dane i tabele

Języki

Delphi, C++ Builder, .NET

Wypełnij arkusz, zachowaj zmiany, udostępnij go na żywo

Ustawiaj komórki w kodzie za pomocą SetCellByName. OnCellChange sprawdza i zapisuje każdą komórkę zmienioną przez użytkownika, a przy LiveSync host rozsyła GetLiveSyncFragmentHTML po zmianie, dzięki czemu każda otwarta strona przeładowuje zmienione komórki.

uses
  sgcHTML_Formula, sgcHTML_Component_Spreadsheet, sgcHTMX_Engine_Server;

// Na formularzu: TsgcHTMLComponent_Spreadsheet (Spreadsheet1) z
// LiveSync = True oraz TsgcHTMX_Engine_Server (HTMXEngine1) strony

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;

// Każda komórka zmieniona przez użytkownika: wpisanie, wklejenie, wypełnienie lub wyczyszczenie
procedure TMainModule.Spreadsheet1CellChange(Sender: TObject; aRow, aCol: Integer;
  const aOldRaw: string; var aNewRaw: string; var aAccept: Boolean);
begin
  if aRow = 0 then
    aAccept := False   // wiersz tytułowy zostaje bez zmian
  else
    StoreCell(sgcHTMLCellName(aRow, aCol), aNewRaw);   // Twój własny magazyn: tabela, plik
end;

// Zmiana jest zastosowana i przeliczona: powiadom każdą otwartą stronę
procedure TMainModule.Spreadsheet1Change(Sender: TObject;
  aSheet: TsgcHTMLSpreadsheetSheet);
begin
  HTMXEngine1.BroadcastFragment(Spreadsheet1.GetLiveSyncFragmentHTML);
end;

// GET /budget.xlsx: arkusz jako skoroszyt, z formułami i stylami
procedure TMainModule.ExportBudget(aStream: TStream);
begin
  Spreadsheet1.SaveToXLSX(aStream);
end;
@* Views/Sheets/Budget.cshtml: wspólny budżet zespołu *@
@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: sprawdź i zachowaj jedną komórkę
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: zastosowano i przeliczono, każda otwarta strona przeładowuje zmienione komórki
public void Changed(object Sender, TsgcHTMLSpreadsheetSheet aSheet)
{
    _ = hub.BroadcastAsync(((TsgcHTMLComponent_Spreadsheet)Sender).GetLiveSyncFragmentHTML());
}

// OnGetSheet: jeden arkusz na użytkownika
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);

Co dostają Twoi użytkownicy

Klawiatura, schowek i formuły znane z Excela, w jednym arkuszu przechowywanym przez Twój serwer.

Formuły

Komórka zaczynająca się od = jest formułą: operatory + - * / ^ % &, porównania, nawiasy, odwołania do komórek i zakresy, takie jak A1:C5, z częściami bezwzględnymi zapisanymi jako $A$1, A$1 lub $A1. Kolejność działań i konwersja tekstu na liczbę działają jak w Excelu. Błędy są wyświetlane jako #DIV/0!, #VALUE!, #REF!, #NAME?, #NUM! i #N/A, a #CIRC! oznacza komórkę w odwołaniu cyklicznym.

Funkcje matematyczne, logiczne i tekstowe

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

Funkcje wyszukiwania, daty i finansowe

Warunkowe: SUMIF, COUNTIF i AVERAGEIF z kryteriami takimi jak ">10", "<>x" oraz symbolami wieloznacznymi * i ?. Wyszukiwanie: VLOOKUP i HLOOKUP, dokładne lub przybliżone, INDEX i MATCH. Data: DATE, YEAR, MONTH, DAY, TODAY, na numerach seryjnych Excela. Finansowe: PMT, FV, PV, NPV. Łącznie 54 funkcje, z semantyką Excela, a pasek formuły uzupełnia ich nazwy.

Formaty

Pogrubienie, kursywa, wyrównanie, kolor tekstu i kolor wypełnienia oraz format liczby dla każdej komórki: Ogólne, Liczba, Waluta, Procent, Data lub Tekst, z 0 do 10 miejsc dziesiętnych, separatorem tysięcy, symbolem waluty i formatem daty. Wyświetlanie używa separatorów dziesiętnego i tysięcy z używanych ustawień regionalnych sgcHTML, jeśli je definiują.

Klawiatura jak w Excelu

Strzałki, Tab i Shift+Tab, Enter i Shift+Enter, Home, End, Ctrl+Home, Ctrl+End, Ctrl+strzałki, PageUp i PageDown. F2 lub pisanie rozpoczyna edycję, Esc anuluje, a Delete czyści. Shift+strzałki, Shift+kliknięcie lub przeciągnięcie myszą zaznaczają zakres, kliknięcie nagłówka zaznacza wiersz lub kolumnę, Ctrl+D i Ctrl+R wypełniają w dół i w prawo, a Ctrl+Z i Ctrl+Y cofają i ponawiają własne edycje użytkownika.

Pasek formuły

Pasek formuły pokazuje surową zawartość komórki, a jego pole nazwy przechodzi do komórki: wpisz B12 i naciśnij Enter. Podczas edycji formuły jej odwołania są wyróżniane kolorami, a użytkownik może klikać komórki lub przeciągać zakresy do formuły.

Kopiowanie i wklejanie z Excelem i Arkuszami Google

Kopiowanie, wycinanie i wklejanie używają tekstu rozdzielanego tabulatorami, czyli formatu, który Excel i Arkusze Google umieszczają w schowku, więc blok komórek przenosi się między nimi w obu kierunkach. Formuła skopiowana wewnątrz arkusza i wklejona lub wypełniona gdzie indziej ma przesunięte odwołania względne i zachowane bezwzględne.

Wstawianie i usuwanie

Wstawiaj wiersze powyżej lub poniżej oraz kolumny po lewej lub po prawej, usuwaj wiersze i kolumny, z paska narzędzi lub z menu kontekstowego komórki albo nagłówka. Każde odwołanie w każdej formule jest dostosowywane jak w Excelu, a odwołanie do usuniętej komórki zmienia się w #REF!. Rozmiar kolumn zmienia się przeciągając krawędź nagłówka, a wiersze i kolumny można zablokować.

Import i eksport XLSX

Eksport do Excela pobiera plik .xlsx z formułami i ich wartościami, stylami komórek i formatami liczb, szerokościami kolumn i zablokowanymi panelami. Import odczytuje plik .xlsx, wraz z formułami i stylami, lub plik .csv, gdy użytkownik potwierdzi, że zastępuje on bieżący arkusz.

Synchronizacja na żywo między użytkownikami

Przy LiveSync osoby, które mają otwarty ten sam arkusz, widzą nawzajem swoje zmiany: komórki zmienione przez innego użytkownika przeładowują się i migają. Każda zaakceptowana zmiana podnosi wersję arkusza, a strona, która ominęła wersję, ładuje cały arkusz ponownie.

Pasek stanu i duże arkusze

Pasek stanu pokazuje Suma, Średnia i Licznik dla zaznaczenia, a wskaźnik informuje, czy zmiany są zapisane. Na stronie znajdują się tylko widoczne wiersze i kolumny, więc arkusz o 10 000 wierszy i 104 kolumnach przewija się płynnie. Bez JavaScriptu strona nadal zawiera zwykłą tabelę z komórkami, czytelną dla robotów indeksujących.

Dostępność

Arkusz jest siatką WAI-ARIA z liczbą i indeksami wierszy i kolumn, a uprzejmy obszar na żywo ogłasza odwołanie do komórki i jej wartość. Podąża za motywem strony, odbija się lustrzanie przy dir="rtl", uwzględnia ograniczony ruch i działa na szerokości telefonu: przewijanie dotykiem, stuknięcie zaznacza, a podwójne stuknięcie edytuje.

Kluczowe właściwości, metody i zdarzenia

Składniki, po które sięgasz najczęściej.

Arkusz

Sheet to TsgcHTMLSpreadsheetSheet. SetCell(aRow, aCol, aRaw) i SetCellByName('B2', '=A1*2') ustawiają komórkę, a Raw, Value, Text i Style ją odczytują. Wartość raw zaczynająca się od = jest formułą, a początkowy apostrof wymusza tekst. Wiersze i kolumny są w API liczone od 0, więc A1 to wiersz 0, kolumna 0. Lock i Unlock chronią zmiany wykonywane z Twoich własnych wątków.

OnCellChange i OnChange

OnCellChange(Sender, aRow, aCol, aOldRaw, aNewRaw, aAccept) uruchamia się dla każdej komórki zmienionej przez użytkownika. Zmień aNewRaw, aby poprawić wartość, ustaw aAccept na False, aby ją odrzucić, albo ją zapisz. OnChange(Sender, aSheet) następuje po zastosowaniu i przeliczeniu zmiany: to miejsce na rozesłanie GetLiveSyncFragmentHTML.

Arkusze dla poszczególnych użytkowników

OnGetSheet(Sender, aSheet) zwraca arkusz użytkownika, który stoi za żądaniem. Jest wywoływane podczas renderowania i przy każdym żądaniu, więc jeden komponent obsługuje wszystkich użytkowników, każdego z jego własnym arkuszem.

Obliczenia autorytatywne po stronie serwera

Przeglądarka wysyła to, co wpisał użytkownik, a resztę robi serwer: stosuje zmianę, przelicza zależne od niej komórki za pomocą grafu zależności i odpowiada wyłącznie zmienionymi komórkami. Recalculate uruchamia pełne obliczenie, a Evaluate oblicza formułę poza jakąkolwiek komórką. Delphi i .NET dają te same wyniki, ten sam JSON i te same bajty XLSX.

Limity bezpieczeństwa

Serwer nigdy nie ufa przeglądarce. Sprawdza ReadOnly, przełączniki AllowFormulas, AllowFormatting, AllowInsertDelete, AllowImport i AllowExport, współrzędne względem MaxRows (10000) i MaxCols (104), MaxCells (100000), MaxCellLength (8192) i MaxImportSize (5 MB), a następnie wywołuje OnCellChange dla każdej komórki. OnImport może odrzucić plik.

Układ

RowCount (100) i ColCount (26) określają rozmiar arkusza, FrozenRows i FrozenCols blokują tytuły, DefaultColWidth, RowHeight i CSSHeight ustawiają rozmiary, a ShowToolbar, ShowFormulaBar i ShowStatusBar włączają lub wyłączają paski. ExportFileName nadaje nazwę pobieranemu skoroszytowi.

XLSX, JSON, CSV i zestawy danych

SaveToXLSX i LoadFromXLSX zapisują i odczytują skoroszyt z kodu, razem z formułami i stylami. W arkuszu SaveToJSON i LoadFromJSON przechowują go w jednym formacie JSON, który Delphi i .NET zapisują bajt w bajt tak samo, SaveToCSV i LoadFromCSV używają RFC 4180 z wartościami surowymi, a LoadFromDataSet ładuje wiersz nagłówka i rekordy.

Wstawianie, usuwanie i przesuwanie

InsertRows, DeleteRows, InsertCols i DeleteCols(aIndex, aCount) dostosowują każde odwołanie jak w Excelu. ShiftFormula(aFormula, aDeltaRow, aDeltaCol) przesuwa odwołania względne formuły i zachowuje bezwzględne, według tej samej reguły, którą przeglądarka stosuje przy wklejaniu i wypełnianiu.

Bez zdarzenia serwera

Arkusz wysyła dane do punktu końcowego zdarzeń komponentów silnika HTMX lub do ActionURL. Bez żadnego z nich jest przeglądarką arkusza tylko do odczytu.

ASP.NET Core

W widoku Razor Tag Helper <sgc-spreadsheet> renderuje arkusz, a jego żądania obsługuje middleware sgcHTML z UseSgcHtml. Jego atrybuty to name, read-only, rows, cols, frozen-rows, frozen-cols, css-height, przełączniki allow-*, live-sync, action-url oraz procedury obsługi on-get-sheet, on-cell-change i on-change.

Demo

Demos\60.HTML\01.RunTime\35.Spreadsheet to sgc Sheets, serwer na porcie 8137 z trzema arkuszami: budżet zespołu, który wszyscy edytują na żywo, z sumami SUM, procentem całości, formatem waluty i wykresem odświeżanym przy każdej zmianie; kalkulator kredytu z arkuszem dla każdego odwiedzającego, PMT, tabelą amortyzacji wypełnioną w dół i wykresem salda; oraz sprzedaż według regionów z SUMIF i VLOOKUP, eksportem i importem XLSX. Wersje projektowe, Lazarus i .NET odzwierciedlają ją.

Poznawaj dalej

Wypróbuj onlineZobacz to w demie Arkusz kalkulacyjny, działającym na żywo na serwerze demo eSeGeCe.
Pomoc onlinePełna dokumentacja API i przewodnik użytkowania tego komponentu.
Komponent GridSiatka danych dla zbiorów danych: sortowanie, filtrowanie, grupowanie, edycja w miejscu i eksport.
Wszystkie komponenty sgcHTMLPrzejrzyj pełną matrycę funkcji 80+ komponentów.
Pobierz bezpłatną wersję próbną30-dniowa wersja próbna zawiera projekty demonstracyjne 60.HTML.
CennikLicencje Single, Team i Site z pełnym kodem źródłowym.
Najkorzystniejsza oferta: All-AccessWszystkie produkty eSeGeCe, ze wsparciem Premium w cenie, już od €1,059 rocznie.
Zobacz cennik All-Access

Gotowy, aby zacząć?

Pobierz bezpłatną wersję próbną i zacznij budować interfejsy webowe w Delphi, C++ Builder i .NET.