Technický článek

Objekty kamery Excelu z Delphi: živé snímky

HotXLS vytváří objekty kamery Excelu na listech XLSX z Delphi přes AddCamera. Objekt kamery je obrázek trvale propojený s oblastí buněk: Excel ho znovu vykreslí ze zdrojové oblasti při každém otevření sešitu nebo změně zdroje, takže dashboard může zobrazovat živý pohled na tabulku, která žije na jiném listu, v libovolné velikosti, a pokud chcete, i otočený

Tato funkce existuje v Excelu jako nástroj Kamera, tlačítko, které většina uživatelů nikdy neviděla, protože není ve výchozím nastavení na pásu karet. Řeší reálný problém dashboardů lépe než alternativy: zkopírovaná oblast zastará, graf nedokáže zobrazit libovolný obsah buněk a ručně vložený propojený obrázek nelze vygenerovat kódem. Objekt kamery je jediná konstrukce, která je zároveň živá i libovolná

Objekt kamery HotXLS vytvořený z Delphi: živý obrázek oblasti Data!$B$2:$D$4 umístěný na listu dashboardu, který Excel znovu vykreslí při otevření a při každé úpravě zdroje
Objekt kamery zůstává trvale propojený se svou zdrojovou oblastí, takže Excel obrázek znovu vykreslí při otevření a při každé úpravě, v libovolné velikosti a z oblasti na jiném listu

Kde je to zdokumentované a proč na tom záleží?

Hlavní specifikace tabulkových procesorů objekty kamery nepopisuje; zachází se s nimi jako s implementačním detailem. Autoritativní popis žije v dokumentaci značkování kreseb, pod záhlavím Camera Tool, a znalost tohoto místa ušetří odpoledne strávené hledáním ve špatném dokumentu

Strukturálně je objekt kamery obyčejný obrazový element, jehož nevizuální vlastnosti obrázku nesou seznam rozšíření. Rozšíření je identifikováno pevným GUID a uvnitř něj element z kreslicího jmenného prostoru 2010 zaznamenává dvě věci: zdrojovou oblast jako absolutní odkaz ve stylu A1, volitelně kvalifikovaný listem, a identifikátor tvaru. Vše ostatní na obrázku je normální

Anatomie XLSX objektu kamery zapsaného HotXLS z Delphi: obyčejný obrazový element, jehož seznam rozšíření nese element z kreslicího jmenného prostoru 2010 zaznamenávající absolutní zdrojovou oblast a identifikátor tvaru
Strukturálně je kamera obyčejný obrázek plus jeden element rozšíření z kreslicího jmenného prostoru 2010, zaznamenávající absolutní zdrojovou oblast ve stylu A1 a identifikátor tvaru

Vytváření kamery

Existují dvě přetížení, protože se hodí dva způsoby pojmenování oblasti. Textová forma přebírá odkaz přesně tak, jak bude uložen, což chcete pro zdroj napříč listy. Souřadnicová forma přebírá čtyři souřadnice buněk na stejném listu a absolutní odkaz za vás sestaví:

uses
  lxHandleX;

var
  Book: TXLSXWorkbook;
  Dashboard: TXLSXWorksheet;
  Cam: TXLSXImage;
begin
  Book := TXLSXWorkbook.Create;
  try
    if Book.Open('reporting.xlsx') <> 1 then
      Exit;
    Dashboard := Book.Sheets[0];

    // Živý pohled na Data!$B$2:$D$4, umístěný přes B10:F20 na dashboardu
    Cam := Dashboard.AddCamera('Data!$B$2:$D$4', 10, 2, 20, 6);

    // Umísťovací rámeček se ve výchozím stavu řídí vlastními 64px sloupci
    // a 20px řádky Excelu; velikost kresby v EMU pak upravte podle potřeby
    Cam.WidthEMU := Round(12.5 * 914400 / 2.54);   // 12,5 cm
    Cam.HeightEMU := Round(6.0 * 914400 / 2.54);

    Book.SaveAs('reporting-dashboard.xlsx');
  finally
    Book.Free;
  end;
end;

Vrácený objekt je normální obrazový objekt s jednou navíc vlastností, CameraRange, která je neprázdná přesně tehdy, když je obrázek kamerou. Tak také detekujete kamery v sešitu, který jste nevytvořili: vyjmenujte obrázky a zkontrolujte tuto vlastnost

Proč zástupný obrázek nemusí být reálný?

Každý obrázek v balíčku XLSX potřebuje obrazovou část a objekt kamery není výjimkou. Excel ale tento obrázek ignoruje: při načtení znovu vykreslí propojenou oblast a namaluje výsledek. Vložené bajty existují čistě jako zobrazovací mezipaměť pro nástroje, které chování kamery neimplementují

Tato skutečnost odstraňuje z implementace celý subsystém. Není potřeba rastrovat zdrojovou oblast, není potřeba vykreslovací engine, který by snímek vyprodukoval, a nehrozí riziko, že by se mezipaměťový obrázek neshodoval s tím živým v Excelu. HotXLS zapisuje minimální zástupný metasoubor — hlavičkový záznam a záznam konce souboru, celkem 108 bajtů — což udržuje balíček strukturálně kompletní a nestojí nic

Jeden důsledek, se kterým je třeba počítat: prohlížeč, který vykresluje XLSX bez implementace objektů kamery, zobrazí zástupný obrázek, který je prázdný. Pokud vaše sešity spotřebovává takový nástroj, je objekt kamery špatnou konstrukcí a vykreslený obrázek oblasti je tou správnou

Zástupná obrazová část objektu kamery HotXLS: Excel při načtení znovu vykreslí propojenou oblast a ignoruje 108bajtový metasoubor, zatímco prohlížeče bez podpory kamery zobrazí prázdný obrázek
Excel ignoruje vložené bajty a při načtení znovu vykreslí propojenou oblast, takže HotXLS zapisuje jen 108bajtový zástupný metasoubor, zatímco prohlížeč bez podpory kamery zobrazí prázdný zástupný obrázek

Převod jednotek, ve kterém je snadné chybovat

Geometrie kreseb v Open XML se měří v English Metric Units, kde jeden palec je 914 400 EMU a jeden centimetr 360 000. Hlavičky metasouborů ale zaznamenávají svůj rámec v jednotkách 0,01 milimetru. Převod mezi nimi je dělení číslem 360

Stojí za to to zdůraznit, protože chyba je tichá. Převod přes pixely při 96 DPI místo toho — násobení 2540 a dělení 9525 — vyprodukuje hodnotu 96krát příliš velkou a nic ji neodmítne: balíček je platný, obrázek je kotvou umístěn správně a nesmyslný je jen deklarovaný rámec metasouboru. Model EMU a jeho chování při zaokrouhlování popisuje článek geometrie obrázků, jednotky EMU a škálování

Zachování kamer při zpětném uložení a otevření sešitu, který je již má

Otevření a uložení sešitu zachovává objekty kamery, včetně elementu rozšíření a jeho odkazu na oblast. To má větší význam než jejich vytváření: většina sešitů s objekty kamery vznikla v Excelu od analytika a knihovna, která je při uložení tiše převede na obyčejné obrázky, zničila živé chování, na které se analytik spoléhal

// Audit, které obrázky jsou kamery a kam ukazují
for I := 0 to Sheet.Images.Count - 1 do
  if Sheet.Images[I].CameraRange <> '' then
    Writeln(Format('camera %d -> %s',
      [I, Sheet.Images[I].CameraRange]));

Když generujete dashboardy programově, tento audit je zároveň regresním testem: po cyklu uložení a znovuotevření musí stejný počet kamer ukazovat na stejné oblasti. Obecné zacházení s obrázky a kresbami, včetně kotvícího modelu, který je umísťuje, popisuje článek grafy, obrázky a kresby

Kdy kamera předčí alternativy

Použijte objekt kamery, když se stejná živá tabulka musí objevit na několika listech v různých velikostech, když tiskové rozvržení potřebuje oblast jednoho listu složenou vedle oblastí jiných, nebo když má souhrnný blok sledovat úpravy provedené jinde, aniž by každou buňku propojoval samostatný vzorec

Dejte přednost obyčejným vzorcům, když je cílem hrstka buněk, protože vzorec napříč listy je jednodušší a rozumí mu každý nástroj. Dejte přednost grafu, když jsou data skutečně řadou, ne formátovaným blokem. A dejte přednost vykreslenému obrázku, když bude sešit spotřebovávat jiný nástroj než Excel, nebo když se snímek po dodání nesmí měnit — archivovaný report by neměl být živý

Jedna poznámka k rozvržení z praxe: kamera zobrazí zdrojovou oblast přesně tak, jak je naformátovaná, včetně sloučených buněk, podmíněného formátování a šířek sloupců. Získání čistě vyhlížejícího bloku dashboardu proto začíná naformátováním zdrojové oblasti, jako by šlo o hotový výstup, což je stejná disciplína popsaná v článku sloučené buňky a rozvržení šablon reportů

Objekty kamery, kresby a zapisovač balíčku XLSX za nimi jsou dodávány v jedné knihovně pro Delphi a C++Builder; úplný seznam funkcí najdete na stránce komponenty HotXLS Delphi spreadsheet component