Tekninen artikkeli

Vie Excel-solualue yhdeksi kuvaksi HotXLS:llä

Joskus toimitettava ei ole dokumentti, se on taulukon kuva. Yhteenvetolohko tilasähköpostissa, renderöity KPI-paneeli kojelaudassa, pikkukuva hakutuloksen vieressä: kaikki haluavat solut eikä mikään niistä halua paperia. TXLSCellImageExporter HotXLS:ssä ottaa klassisen tai XLSX-solusuorakulmion ja tuottaa yhden tiiviin PNG- tai JPEG-kuvan ilman sivukokoa, ilman marginaaleja, ilman ylä- tai alatunnisteita, ilman tulostusotsikoita eikä sivunvaihtoja. Resoluutio, skaala, muoto ja JPEG-laatu ovat muokattavia, objekteilla, ruudukkolinjoilla ja solujen reunoilla on itsenäiset kytkimet, tausta voi olla väri tai läpinäkyvä, ja tiedoston kirjoitus kulkee atomisen saman kansion korvauksen kautta, joka jättää olemassa olevan kohteen koskemattomaksi, jos mikään epäonnistuu

Syy sille, että tämä tarvitsee oman vientitoimintonsa pikemminkin kuin lipun tulostuspolussa, on se, ettei sivutus ole valinnainen kerros, jonka voi kytkeä pois. Se on se asia, jonka tekemistä varten sivuputki on olemassa

Miksi ei renderöidä aluetta tulostusputken kautta?

Koska tulostusputki työntää sivun sinun ja solujen väliin. Paperikoko päättää, kuinka paljon mahtuu, marginaalit työntävät sisällön sisäänpäin, ylä- ja alatunnisteet miehittävät nauhoja, joita et pyytänyt, tulostusotsikot toistavat rivejä, jotka sinulla jo on, ja sivunvaihdot halkovat alueen. Yhteenvetolohko, joka sattuu olemaan vaihdoksen yli, ilmestyy kahtena kuvana, jossa kiinnostava rivi on leikattu puoliksi. Voit kompensoida kaiken tämän asettamalla mukautetun sivukoon, joka täsmää alueeseen täsmälleen, ja niin tehdään, mutta se tarkoittaa paperigeometrian uudelleenlaskemista joka kerta, kun alue muuttuu, ja se jättää yhä otsikkonauhan ja tulostusotsikkologiikan polulle

Soluvientitoiminto mittaa suorakulmion, varaa bittikartan täsmälleen tuon kokoiseksi, piirtää solut siihen ja koodaa. Sivua ei ole, joten mitään ei ole konfiguroitava pois. Tapauksissa, joissa haluatkin paperin, PDF-vientipolku on oikea työkalu ja se käsitellään artikkelissa laskentataulukon PDF-vienti

TXLSCellImageExporter mittaa, piirtää ja koodaa yhden kuvan per solualue, kun taas tulostusputki halkaisee alueen sivunvaihdossa
Sivuputki työntää paperigeometrian sinun ja solujen väliin; soluvientitoiminnolla ei ole sivua missään polussa

Mittaa ennen renderöintiä

Measure palauttaa pikseliulottuvuudet, jotka nykyiset asetukset tuottaisivat ilman mitään koodausta. Se merkitsee kahdesta syystä. HTML- tai sähköpostipohja tarvitsee yleensä kuvan ulottuvuudet ennen kuin kuva on olemassa, jotta se voi varata laatikon ja välttää asettelun siirtymän. Ja palvelu, joka renderöi käyttäjän valitsemia alueita, tarvitsee tavan hylätä mieletön pyyntö ennen sen puolesta varaamista

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;   // PNG pitää ohuet vedot terävinä
      Exporter.DPI := 96;
      Exporter.Scale := 2.0;             // retina-tiheyden tuloste
      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');
      // W ja H ovat nyt tiedossa; varaa asettelulaatikko ennen koodausta
      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;

Budjetit, koska skaala kertoutuu

MaxPixels ja MaxBytes eivät ole puolustavan koristelua. Pikselimäärä kasvaa skaalauskertoimen neliön ja resoluutiosuhteen neliön mukana, joten alue, joka on kohtuulliset 1200 kertaa 800 arvolla 96 DPI, tulee noin 47 megapikseliä arvolla 600 DPI, ja käyttäjä, joka valitsee koko käytetyn alueen yhteenvetolohkon sijaan, lisää toisen suuruusluokan tuon päälle. Ilman kattoa vikamuoto on varaus, jota prosessi ei voi tyydyttää, mikä kaataa kaiken muun, mitä kyseinen prosessi teki

Katolla pyyntö epäonnistuu ja kutsuja saa valita: hylkää, pienennä skaalaa tai kavenna aluetta. Se on paljon parempi asema raporttipalvelimelle, ja se on sama päättely, joka on eksplisiittisten budjettien takana metafile-dekooderissa, mistä kerrotaan artikkelissa rajattu EMF- ja WMF-dekooderi

Budjettivirta TXLSCellImageExporterille HotXLS:ssä: Measure palauttaa pikselikoon ensin, sitten MaxPixels ja MaxBytes rajaavat varauksen ja tulosteen koon
Hylkääminen tapahtuu ennen varausta, ja tavubudjetin epäonnistuminen jättää edellisen kuvan koskemattomaksi kutsujalle

Atomikorvaus ja miksi kansio merkitsee

Save tiedostonimeen ei kirjoita kohteeseen. Se kirjoittaa väliaikaisen tiedoston samaan kansioon, koodaa siihen ja vasta sitten korvaa kohteen. Jos koodaus epäonnistuu, jos budjetti ylittyy kesken tai jos prosessi tapetaan, edellinen kuva on yhä siellä ja yhä pätevä. Kojelauta, joka uusintaa laattansa aikataulun mukaan, ei siksi koskaan näytä katkaistua PNG:tä, mikä on tavallinen oire naiivista kirjoituksesta, joka avaa kohteen ja alkaa virrata

Saman kansion yksityiskohta ei ole sattumaa. Atomikorvaus on atominen vain yhden taltion sisällä, koska taltioiden yli käyttöjärjestelmän on kopioitava ja sitten poistettava, mikä tuo takaisin sen ikkunan, jota yritit sulkea. Mikä tahansa tämän mallin toteutus, joka laittaa väliaikaisen tiedostonsa järjestelmän väliaikaiskansioon, ei ole atominen koneella, jossa tuloste asuu eri asemalla

TXLSCellImageExporterin Save koodaa väliaikaiseen tiedostoon samassa kansiossa ja korvaa sitten kohteen atomisesti; epäonnistumiset jättävät edellisen kuvan päteväksi
Väliaikaisen tiedoston on asuttava kohteen vieressä, koska atomikorvaus toimii vain yhden taltion sisällä

Piirtotapahtumat piirtävät todelliselle canvasille

Sekä aluevientitoiminto että sivuvientitoiminto paljastavat johtavat ja jälkimmäiset piirtotapahtumat, ja ne vastaanottavat täyden vain luku -kontekstin eikä vain canvas-kahvaa. TXLSPagePaintContext kantaa elävän canvasin, pikselirajat, sivukoon pisteinä, käytössä olevan resoluution ja skaalan, dokumentin sivunumeron, taulukon sisäisen sivunumeron, kokonaissivumäärän, taulukon nimen ja alkuperäisen laskentataulukon sekä klassisessa että XLSX-muodossa. Se riittää piirtämään vesileiman, joka skaalautuu oikein, tai sivuleiman, joka tietää, missä kohtaa ajoa se on

procedure TReportJob.StampDraft(Sender: TObject;
  const AContext: TXLSPagePaintContext);
begin
  // Skaalatietoinen, joten leima näyttää samalta arvoilla 1x ja 3x
  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;

Kolmeen käyttäytymiseen kannattaa luottaa. Tapahtumat laukeavat täsmälleen kerran per renderöity kehys, mukaan lukien jokainen monisivuisen TIFF:n kehys, joten laskuri, joka kasvatetaan käsittelijässä, on luotettava. Ne pysyvät hiljaa mittauksen aikana, joten käsittelijä sivuvaikutuksella ei aja kahdesti yhtä tulostetta kohden. Ja jos johtava tapahtuma heittää, jälkimmäinen tapahtuma ei laukea eikä mitään osittaisia kuvatavuja kirjoiteta, joten poikkeus omassa piirtokoodissasi ei voi tuottaa puoliksi leimattua tiedostoa

Muodon valitseminen

PNG kaikelle tekstipainotteiselle. JPEG soveltaa lohkotransformaatiota, joka tuottaa näkyvää rengasmaista häiriötä ohuiden suurikontrastisten vetojen ympärillä, mikä solujen reunat ja pieni teksti täsmälleen ovat, ja artefaktit selviävät laatuasetuksissa, joissa valokuva näyttää täydelliseltä. JPEG ansaitsee paikkansa, kun aluetta hallitsevat upotetut valokuvat ja tiedostokoko merkitsee enemmän kuin reunojen uskollisuus. Läpinäkyvät taustat vaativat PNG:n, koska JPEG:llä ei ole alfakanavaa, joten laatta, jonka on tarkoitus istua värilliselle pinnalle, on tehnyt valinnan puolestasi

Jos alueesi sisältää yhdistettyjä soluja, tarkista tuloste taulukon suhteen: yhdistetyt alueet ovat vuorovaikutuksessa palstanleveyksien kanssa tavalla, joka yllättää ihmisiä, ja asettelusäännöt käsitellään artikkelissa yhdistetyt solut ja raporttipohjat. HotXLS lukee ja kirjoittaa muodot XLS, XLSX, ODS ja CSV Delphistä ja C++Builderista ilman Excel-riippuvuutta, ja koko vientitoiminnon pinta on dokumentoitu HotXLS Delphi spreadsheet -komponentin tuotesivulla