Techninis straipsnis

Excel langelių srities eksportas vienu atvaizdu HotXLS

Kartais pristatomasis rezultatas nėra dokumentas — tai lentelės paveikslas. Santraukos blokas būsenos el. laiške, atvaizduota KPI sritis valdymo pulte, miniatiūra greta paieškos rezultato: visi jie nori langelių ir nė vienas nenori popieriaus. TXLSCellImageExporter HotXLS paima klasikinį arba XLSX langelių stačiakampį ir pagamina vieną kompaktišką PNG arba JPEG be puslapio dydžio, be paraščių, be antraščių ar poraščių, be spaudinio antraščių ir be puslapių lūžių. Skiriamoji geba, mastelis, formatas ir JPEG kokybė konfigūruojami, objektai, tinklelis ir langelių rėmeliai turi nepriklausomus jungiklius, fonas gali būti spalva arba permatomas, o failo įrašymas eina per atominį tame pačiame aplanke esantį pakeitimą, paliekantį esamą taikinį nepaliestą, jei kas nepavyksta

Priežastis, kodėl tai reikalauja savo eksportuotojo, o ne vėliavėlės spaudinio kelyje, yra ta, kad puslapiavimas nėra pasirinktinas sluoksnis, kurį galima išjungti. Tai yra tas dalykas, dėl kurio puslapių konvejeris egzistuoja

Kodėl neatvaizduoti srities per spaudinio konvejerį?

Nes spaudinio konvejeris įterpia puslapį tarp jūsų ir langelių. Popieriaus dydis nusprendžia, kiek telpa, paraštės stumia turinį į vidų, antraštės ir poraštės užima juostas, kurių neprašėte, spaudinio antraštės kartoją eilutes, kurias jau turite, o puslapių lūžiai perskelia sritį. Santraukos blokas, atsitiktinai peršokantis per lūžį, išeina kaip du atvaizdai su perpjauta per pusę įdomia eilute. Galite tai kompensuoti sukonfigūravę pasirinktinį puslapio dydį, tiksliai atitinkantį sritį, ir žmonės tai daro, bet tai reiškia popieriaus geometrijos perskaičiavimą kaskart, kai keičiasi sritis, ir vis tiek palieka antraštės juostą bei spaudinio antraščių logiką kelyje

Llangelių eksportuotojas išmatuoja stačiakampį, išskiria būtent tokio dydžio bitmap, piešia langelius į jį ir užkoduoja. Puslapio nėra, todėl nėra ko konfigūracijomis pašalinti. Atvejams, kai vis dėlto norite popieriaus, PDF eksporto kelias yra tinkamas įrankis ir dengiamas darbalapio PDF eksporto straipsnyje

TXLSCellImageExporter matuoja, piešia ir užkoduoja vieną atvaizdą langelių sričiai, o spaudinio konvejeris perskelia sritį puslapių lūžiais
Puslapių konvejeris įterpia popieriaus geometriją tarp jūsų ir langelių; langelių eksportuotojas neturi puslapio niekur kelyje

Išmatuokite prieš atvaizduodami

Measure grąžina pikselių matmenis, kuriuos duotų esami nustatymai, nieko neužkoduodama. Tai svarbu dėl dviejų priežasčių. HTML arba el. laiško šablonas paprastai reikalauja atvaizdo matmenų, kol atvaizdo dar nėra, kad galėtų rezervuoti langelį ir išvengti išdėstymo poslinkio. Ir tarnyba, atvaizduojanti vartotojo parinktas sritis, reikalauja būdo atmesti absurdišką užklausą prieš jos išteklių išskyrimą

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 išlaiko plonus brūkšnius aštrius
      Exporter.DPI := 96;
      Exporter.Scale := 2.0;             // retina tankio išvestis
      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 ir H dabar žinomi; rezervuokite išdėstymo langelį prieš kodavimą
      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;

Biudžetai, nes mastelis dauginasi

MaxPixels ir MaxBytes nėra gynybinė dekoracija. Pikselių skaičius auga su mastelio koeficiento kvadratu ir su skiriamosios gebos santykio kvadratu, todėl sritis, protinga 1200 iš 800 ties 96 DPI, tampa maždaug 47 megapikselių ties 600 DPI, o vartotojas, parinkęs visą naudotą sritį vietoj santraukos bloko, prideda dar vieną eilės dydį ant viršaus. Be ribos gedimo režimas yra išskyrimas, kurio procesas negali patenkinti, kas nukloja viską, ką tas procesas darė kita

Su riba užklausa nepavyksta, o iškviečiantysis gauna pasirinkimą: atsisakyti, sumažinti mastelį arba susiaurinti sritį. Tai gerokai geresnė ataskaitų serverio pozicija, ir tai tas pats samprotavimas už aiškių biudžetų metafailų dekoderiuje, aprašytas riboto EMF ir WMF dekoderio straipsnyje

TXLSCellImageExporter HotXLS biudžeto eiga: Measure pirmiausia grąžina pikselių dydį, tada MaxPixels ir MaxBytes riboja išskyrimą bei išvesties dydį
Atsisakymas vyksta prieš išskyrimą, o baitų biudžeto nesėkmė palieka ankstesnį atvaizdą nepaliestą iškviečiančiajam

Atominis pakeitimas ir kodėl aplankas svarbus

Save į failo vardą nerašo į taikinį. Ji rašo laikiną failą tame pačiame aplanke, į jį užkoduoja ir tik tada pakeičia taikinį. Jei kodavimas nepavyksta, jei biudžetas viršytas pusiaukelėje arba procesas nužudytas, ankstesnis atvaizdas tebėra ten ir tebėra teisėtas. Valdymo pultas, atnaujinantis savo plyteles pagal grafiką, todėl niekada nerodo nukirpto PNG, kas yra įprastas naivaus rašymo simptomas, atveriančio paskirtį ir pradedančio srautinti

Tame pačiame aplanke esanti detalė nėra atsitiktinė. Atominis pakeitimas yra atominiu tik vieno tomo viduje, nes per tomus operacinė sistema privalo nukopijuoti ir paskui ištrinti, kas vėl atkuria langą, kurį bandėte uždaryti. Bet koks šio modelio įgyvendinimas, padedantis savo laikiną failą sistemos laikinųjų kataloge, nėra atominiu mašinoje, kurioje išvestis gyvena kitame diske

TXLSCellImageExporter Save užkoduoja į laikiną failą tame pačiame aplanke, tada atomiškai pakeičia taikinį; nesėkmės palieka ankstesnį atvaizdą teisėtą
Laikinas failas privalo gyventi greta taikinio, nes atominis pakeitimas veikia tik vieno tomo viduje

Tapymo įvykiai piešia ant tikros drobės

Ir srities eksportuotojas, ir puslapio eksportuotojas atveria priekinius ir galinius tapymo įvykius, ir jie gauna pilną tik skaitomą kontekstą, o ne vien drobės rankenėlę. TXLSPagePaintContext neša gyvą drobę, pikselių ribas, puslapio dydį taškais, faktiškai naudojamą skiriamąją gebą ir mastelį, dokumento puslapio numerį, darbalapio vidinį puslapio numerį, visą puslapių skaičių, lapo vardą ir kilmės darbalapį tiek klasikiniame, tiek XLSX variante. To užtenka nupiešti vandens ženklą, teisingai besimastelįjantį, arba puslapio antspaudą, žinantį, kur jis yra sekoje

procedure TReportJob.StampDraft(Sender: TObject;
  const AContext: TXLSPagePaintContext);
begin
  // Mastelio suvokiantis, todėl antspaudas atrodo tas pats ties 1x ir 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;

Trys elgsenos verta pasitikėjimo. Įvykiai pakyla tiksliai kartą per atvaizduotą kadrą, įskaitant kiekvieną daugialapio TIFF kadrą, todėl apdorojusiajame didinamas skaitiklis yra patikimas. Jie tyli matuodami, todėl šalutinį poveikį turintis apdorotojas nevyksta du kartus vienai išvečiai. Ir jei priekinis įvykis meta išimtį, galinis nevyksta ir jokia dalinė atvaizdo baitų dalis nerašoma, todėl išimtis jūsų pačių piešimo kode negali pagaminti pusiau antspaudo failo

Formato pasirinkimas

PNG bet kam, kur gausu teksto. JPEG taiko blokinę transformaciją, duodančią matomą dūzgesį aplink plonus didelio kontrasto brūkšnius, o būtent tai yra langelių rėmeliai ir mažas tekstas, ir artefaktai išgyvena tokiuose kokybės nustatymuose, kuriuose fotografija atrodo tobulai. JPEG užsitarnauja savo vietą, kai sritį dominuoja įterptos fotografijos ir failo dydis svarbiau už kraštų tikslumą. Permatomi fonai reikalauja PNG, nes JPEG neturi alfa kanalo, todėl plytelė, skirta sėdėti ant spalvoto paviršiaus, apsisprendė už jus

Jeigu jūsų sritis turi sujungtų langelių, patikrinkite išvestį prieš lapą: sujungti regionai sąveikauja su stulpelių pločiais taip, kad stebina žmones, o išdėstymo taisyklės dengiamos sujungtų langelių ir ataskaitų šablonų straipsnyje. HotXLS skaito ir rašo XLS, XLSX, ODS ir CSV iš Delphi ir C++Builder be Excel priklausomybės, o visas eksportuotojo paviršius dokumentuotas HotXLS Delphi spreadsheet component produkto puslapyje