Műszaki cikk

Excel cellatartomány exportálása egy képként a HotXLS-szel

Néha a kézbesítendő nem dokumentum, hanem egy táblázat képe. Egy összefoglaló blokk egy státusz e-mailben, egy renderelt KPI panel egy irányítópulton, egy bélyegkép egy keresési találat mellett: mind cellákat akarnak, és egyik sem akar papírt. A HotXLS TXLSCellImageExporter osztálya klasszikus vagy XLSX cellatéglalapot vesz fel, és egyetlen kompakt PNG-t vagy JPEG-t állít elő oldalméret, margók, fejlécek és láblécek, nyomtatási címek és oldaltörések nélkül. A felbontás, a méretarány, a formátum és a JPEG minőség konfigurálható, az objektumok, a rácsvonalak és a cellaszegélyek külön kapcsolóval bírnak, a háttér lehet szín vagy átlátszó, és a fájlírás atomi, azonos mappás cserén át megy, amely meglévő célt érintetlenül hagy, ha bármi elbukik

Az ok, hogy ennek saját exportáló kell, nem pedig egy jelző a nyomtatási úton, az, hogy a lapozás nem olyan opcionális réteg, amelyet ki lehet kapcsolni. Az a dolog, amiért az oldalvezeték létezik

Miért ne renderelné a tartományt a nyomtatási vezetéken át?

Mert a nyomtatási vezeték oldalt helyez be Ön és a cellák közé. A papírméret dönti el, mennyi fér el, a margók befelé tolják a tartalmat, a fejlécek és láblécek sávokat foglalnak el, amelyeket nem kért, a nyomtatási címek olyan sorokat ismételnek, amelyekkel már rendelkezik, és az oldaltörések kettéhasítják a tartományt. Egy olyan összefoglaló blokk, amely éppen egy törésen ül át, két képként jön ki, a fontos sor félbevágva. Mindezt kompenzálhatja úgy, hogy a tartományhoz pontosan illeszkedő egyéni papírméretet állít be, és az emberek ezt teszik, de az azt jelenti, hogy minden tartományváltozáskor újra kell számolni a papírgeometriát, és még ekkor is marad az útban a fejlécsáv és a nyomtatási cím logika

A cellaexportáló megméri a téglalapot, pontosan akkora bittérképet foglal, belerajzolja a cellákat, és kódolja. Nincs oldal, tehát nincs mit konfigurálni el. Azokhoz az esetekhez, amikor mégis papírt akar, a PDF export út a helyes eszköz, és azt a munkalap PDF export cikk tárgyalja

A TXLSCellImageExporter megmér, rajzol és kódol egy képet cellatartományonként, miközben a nyomtatási vezeték oldaltöréseknél hasítja a tartományt
Az oldalvezeték papírgeometriát helyez be Ön és a cellák közé; a cellaexportáló útjában sehol sincs oldal

Mérjen, mielőtt renderel

A Measure visszaadja azokat a pixelméreteket, amelyeket az aktuális beállítások előállítanának, bármi kódolása nélkül. Ez két okból fontos. Egy HTML vagy e-mail sablonnak általában szüksége van a képméretekre, mielőtt a kép létezne, hogy lefoglalja a dobozt, és elkerülje az elrendezés elmozdulását. És egy felhasználó által kiválasztott tartományokat renderelő szolgáltatásnak módra van szüksége, hogy elutasítson egy képtelen kérést, mielőtt azért foglalna

uses
  lxHandleX, lxPagination;

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  Exporter: TXLSCellImageExporter;
  Summary: TXLSXRange;
  W, H, Bytes: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    Book.Open('quarter.xlsx');
    Sheet := Book.Sheets.ByPos[0];
    Summary := Sheet.Range['A1:F20'];

    Exporter := TXLSCellImageExporter.Create;
    try
      Exporter.ImageFormat := xpifPng;   // A PNG vékony vonásokat élesen tart
      Exporter.DPI := 96;
      Exporter.Scale := 2.0;             // retina-sűrűségű kimenet
      Exporter.IncludeGridlines := False;
      Exporter.IncludeCellBorders := True;
      Exporter.TransparentBackground := True;
      Exporter.MaxPixels := 40 * 1000 * 1000;
      Exporter.MaxBytes := 8 * 1024 * 1024;

      if not Exporter.Measure(Summary, W, H) then
        raise Exception.Create('range exceeds the configured budget');
      // A W és H most ismert; foglalja le az elrendezésdobozt kódolás előtt
      Bytes := Exporter.Save(Summary, 'summary.png');
      if Bytes <= 0 then
        raise Exception.Create('image export failed, previous file kept');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

Korlátok, mert a méretarány szorzódik

A MaxPixels és MaxBytes nem védekező díszítés. A pixelszám a méretarány tényezőjének négyzetével és a felbontásarány négyzetével nő, tehát egy 96 DPI mellett ésszerű 1200-szor-800-as tartomány 600 DPI mellett nagyjából 47 megapixeles lesz, és egy felhasználó, aki összefoglaló blokk helyett egy teljes használt tartományt választ ki, arra még egy nagyságrendet rátesz. Korlát nélkül a hibamód olyan foglalás, amelyet a folyamat nem tud kielégíteni, és amely ledönt mindent, amivel az a folyamat egyébként foglalkozott

Korláttal a kérés elbukik, és a hívó választhat: elutasít, csökkenti a méretarányt, vagy szűkíti a tartományt. Ez sokkal jobb helyzet egy jelentéskiszolgálónak, és ugyanez az érvelés áll a metafájl-dekódoló explicit korlátai mögött, amelyet a határolt EMF és WMF dekódolási cikk ír le

Korlátfolyamat a HotXLS TXLSCellImageExporter számára: a Measure előbb adja a pixelméretet, majd a MaxPixels és MaxBytes fogja korlát közé a foglalást és a kimenet méretét
Az elutasítás a foglalás előtt történik, és egy bájtkorlát megbukása az előző képet érintetlenül hagyja a hívónak

Atomi csere, és miért számít a mappa

A Save fájlnevre nem a célba ír. Ideiglenes fájlt ír ugyanabba a mappába, abba kódol, és csak azután cseréli a célt. Ha a kódolás elbukik, ha a korlát félúton túllépésre kerül, vagy ha a folyamatot lelövik, az előző kép még ott van, és még érvényes. Egy irányítópult, amely ütemterv szerint újratermeli a csempéit, ezért soha nem mutat csonkolt PNG-t, ami a naiv írás szokásos tünete, amely megnyitja a célt, és nekiáll streamelni

Az azonos mappa részlet nem véletlen. Egy atomi csere csak egyetlen köteten belül atomi, mert kötetek között az operációs rendszernek másolnia, majd törölnie kell, ami visszahozza azt az ablakot, amelyet be akart zárni. Ennek a mintának bármely implementációja, amely az ideiglenes fájlját a rendszer ideiglenes könyvtárába teszi, nem atomi azon a gépen, ahol a kimenet más meghajtón él

A TXLSCellImageExporter Save ugyanabba a mappába írt ideiglenes fájlba kódol, majd atomikusan cseréli a célt; a megbukások az előző képet érvényesen hagyják
Az ideiglenes fájlnak a cél mellett kell laknia, mert az atomi csere csak egyetlen köteten belül működik

A festési események a valódi vászonra rajzolnak

Mind a tartományexportáló, mind az oldal exportáló nyitó és záró festési eseményeket tesz ki, és azok teljes csak olvasható kontextust kapnak, nem csupán vászonhandlet. A TXLSPagePaintContext hordozza az élő vásznat, a pixelhatárokat, az oldalméretet pontokban, a ténylegesen használatban lévő felbontást és méretarányt, a dokumentum oldalszámát, a munkalapon belüli oldalszámot, a teljes oldalszámot, a munkalapnevet és az eredeti munkalapot klasszikus és XLSX ízlésben egyaránt. Az elég ahhoz, hogy helyesen skálázódó vízjelet rajzoljon, vagy olyan oldalbélyeget, amely tudja, hol tart a futásban

procedure TReportJob.StampDraft(Sender: TObject;
  const AContext: TXLSPagePaintContext);
begin
  // Méretarányt ismerő, tehát a bélyeg 1x-en és 3x-on ugyanúgy néz ki
  AContext.Canvas.Font.Height := Round(-48 * AContext.Scale);
  AContext.Canvas.Font.Color := clSilver;
  AContext.Canvas.Brush.Style := bsClear;
  AContext.Canvas.TextOut(AContext.Bounds.Left + Round(24 * AContext.Scale),
    AContext.Bounds.Top + Round(24 * AContext.Scale), 'DRAFT');
end;

Exporter.AfterPaint := Job.StampDraft;

Három viselkedésre érdemes támaszkodni. Az események pontosan egyszer sülnek el renderelt képkockánként, beleértve a többoldalas TIFF minden képkockáját, tehát a kezelőben növelt számláló megbízható. Csendben maradnak mérés közben, tehát mellékhatással bíró kezelő nem fut kétszer egyetlen kimenetért. És ha a nyitó esemény dob, a záró esemény nem sül el, és részleges képbájtok nem íródnak, tehát a saját rajzolási kódjában lévő kivétel nem produkálhat félig bélyegzett fájlt

A formátum kiválasztása

PNG minden szövegteljes tartalomhoz. A JPEG blokktranszformációt alkalmaz, amely látható gyűrűzést produkál vékony, nagy kontrasztú vonások körül, ami pontosan az, ami a cellaszegélyek és a kis szöveg, és az artefaktok túlélik azokat a minőségbeállításokat, amelyek mellett egy fénykép tökéletesnek néz ki. A JPEG akkor érdemli meg a helyét, amikor a tartományt beágyazott fényképek uralják, és a fájlméret fontosabb, mint az élek hűsége. Átlátszó háttér PNG-t igényel, mert a JPEG-nek nincs alfa csatornája, tehát egy színes felületre szánt csempénél a döntés megszületett Ön helyett

Ha a tartományában egyesített cellák vannak, nézze meg a kimenetet a munkalappal szemben: az egyesített régiók az oszlopszélességekkel olyan módokon lépnek kapcsolatba, amelyek meglepnek, és az elrendezési szabályokat a egyesített cellák és jelentéssablonok cikk tárgyalja. A HotXLS XLS, XLSX, ODS és CSV formátumokat olvas és ír Delphi és C++Builder alól Excel-függőség nélkül, és a teljes exportáló felület a HotXLS Delphi spreadsheet component terméklapon van dokumentálva