Technický článok

Export hárkov Excelu do PDF v Delphi bez Office

Ak chcete exportovať hárok Excelu do formátu PDF z Delphi alebo C++Builder bez nainštalovaného balíka Office, zavolajte metódu SaveAsPDF na hárku alebo zošite HotXLS. HotXLS je natívny Excel komponent pre VCL a jeho export z hárka do PDF vykresľuje použitý rozsah (UsedRange) hárka do samostatného súboru PDF 1.4, pričom mapuje šírky stĺpcov Excelu a zobrazovaný text buniek na stránky A4 s automatickým stránkovaním. Vykresľovania sa nezúčastňuje žiadna kópia Excelu, ovládač tlačiarne ani externá DLL knižnica

HotXLS považuje PDF za formát na prezentáciu dát, ktorý je obdobou jeho exportných ciest do CSV, TSV a HTML, a nie za engine na pixelovo presné vykresľovanie. Export reprodukuje tabuľkový obsah a rozloženie: hodnoty, ktoré vidíte v mriežke, proporcie stĺpcov a čiary mriežky okolo buniek. Toto zarámovanie je dôležité, pretože hneď na začiatku nastavuje úprimné očakávania, a zvyšok tohto článku je presne o tom, kde táto hranica leží

Ako previesť Excel do PDF v Delphi bez Office?

Najkratšou cestou je jediné volanie. TXLSWorksheet vystavuje metódy SaveAsPDF(FileName) a SaveAsPDF(Stream), a TXLSWorkbook vystavuje rovnaké dve preťaženia, ktoré sa presmerujú na aktívny hárok. Každé z nich vracia hodnotu Integer (1 pri úspechu a -1 pri zlyhaní), takže sa môžete rozhodnúť na základe výsledku bez toho, aby ste museli volanie obaliť do vlastného spracovania výnimiek

uses
  lxHandle;

var
  Book: TXLSWorkbook;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('sales-june.xlsx');
    // Render the active sheet's used range straight to report.pdf.
    if Book.SaveAsPDF('report.pdf') = 1 then
      Writeln('PDF written');
  finally
    Book.Free;
  end;
end;

Keď zavoláte SaveAsPDF na hárku, HotXLS exportuje UsedRange tohto hárka, čo je ohraničujúci obdĺžnik každej vyplnenej bunky. Preťaženie zošita je pohodlná funkcia, ktorá deleguje prácu na aktívny hárok, takže zostava s viacerými hárkami buď prechádza v slučke tie hárky, ktoré potrebuje, alebo pred volaním vyberie aktívny hárok. Neexistuje žiadny režim pre celý zošit (všetko v jednom prechode), ktorý by spojil každý hárok dohromady: každé volanie vykreslí jeden hárok alebo jeden rozsah

Ako HotXLS premieňa použitý rozsah na stránky PDF?

HotXLS prechádza použitý rozsah bunku po bunke a usporadúva ho ako stránkovanú mriežku. Geometria stĺpcov pochádza priamo z Excelu: šírka každého stĺpca sa skonvertuje zo šírkovej jednotky Excelu na typografické body s minimálnou hranicou, aby sa žiadny stĺpec nezúžil na minimum. Keď sú stĺpce spolu širšie ako použiteľná stránka, HotXLS ich rovnomerne zmenší, aby sa zmestili; keď sa už zmestia, ponechá ich v prirodzenej šírke namiesto toho, aby ich rozťahoval po celom hárku

Riadky potom plynú po stránke nadol, až kým by ďalší neprekročil dolný okraj, vtedy HotXLS otvorí novú stránku a pokračuje, takže hárok s tisíckami riadkov sa stránkuje sám bez toho, aby ste museli sledovať konce stránok. Každá bunka vytlačí svoj FormattedText, čo je zobrazený reťazec vytvorený po použití formátu čísla, takže dátum sa zobrazí tak, ako ho zobrazuje hárok, a menová bunka si zachová svoje oddeľovače tisícov a symbol. Text, ktorý presahuje svoj stĺpec, sa oreže na šírku bunky namiesto toho, aby pretiekol do susednej bunky

Nastavenie orientácie, okrajov a veľkosti písma

Pre čokoľvek nad rámec predvoleného rozloženia ovládajte exportér priamo. TXLSPDFExport je trieda stojaca za jednoradkovými pomocníkmi a publikuje tri vlastnosti: Orientation (xlsPdfPortrait alebo xlsPdfLandscape, predvolene na výšku), Margin (body, predvolene 40) a FontSize (body, predvolene 9). Nastavte ich pred volaním SaveAsPDF a prevezme ich celý dokument

uses
  lxHandle, lxPDF;

var
  Book: TXLSWorkbook;
  Exporter: TXLSPDFExport;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('wide-ledger.xlsx');
    Exporter := TXLSPDFExport.Create;
    try
      Exporter.Orientation := xlsPdfLandscape;  // fit wide sheets on the page
      Exporter.Margin := 28;                     // tighter page margin, in points
      Exporter.FontSize := 8;                    // denser rows
      Exporter.SaveAsPDF(Book.ActiveSheet, 'ledger.pdf');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

Trieda TXLSPDFExport prijíma prostredníctvom SaveAsPDF(Range: IXLSRange; ...) aj rozsah namiesto celého hárka, čo je spôsob, ako exportovať súhrnný blok z hárka, ktorý obsahuje aj pomocné výpočty. Toto preťaženie rozsahu je to isté, o ktoré sa interne opiera pomocník hárka, takže rozloženie, mierka a stránkovanie sa správajú identicky, či už mu odovzdáte plný použitý rozsah, alebo ručne vybraný výber

var
  Book: TXLSWorkbook;
  Exporter: TXLSPDFExport;
  Summary: IXLSRange;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('quarter.xlsx');
    // Export only the summary block, not the scratch columns beside it.
    Summary := Book.Sheets[1].Range['A1', 'F20'];
    Exporter := TXLSPDFExport.Create;
    try
      Exporter.SaveAsPDF(Summary, 'summary.pdf');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

Prečo HotXLS nevkladá žiadne písmo: kompromis Helvetica a WinAnsi

HotXLS zapisuje text pomocou vstavaného písma Helvetica a kódovania WinAnsiEncoding, čo je zámerná voľba bez externých závislostí s jedným skutočným obmedzením. Keďže Helvetica patrí medzi 14 štandardných písiem, ktoré už obsahuje každá kompatibilná čítačka PDF, exportér nevkladá vôbec žiadne písmo: súbor zostáva malý a otvorí sa kdekoľvek bez toho, aby ste museli licencovať alebo posielať čokoľvek spolu s ním. Cenou za túto voľbu je repertoár znakov, ktoré môže stránka zobraziť

Kódovanie WinAnsiEncoding pokrýva sadu Windows-1252, takže latinské písmo, bežná interpunkcia a obvyklá západoeurópska diakritika sa vykresľujú správne. HotXLS tiež skladá niekoľko typografických znakov, ozdobné úvodzovky, pomlčky en a em a znak eura do ich pozícií v CP1252. Znaky mimo tohto rozsahu, ako CJK ideogramy, cyrilika, gréčtina a arabčina, sa na stránke zmenia na otáznik. Ak vaše hárky obsahujú nelatinský text, tento exportér je nesprávnym nástrojom a vhodnejší je plnohodnotný vykresľovač PDF

Kde export z hárka do PDF končí

HotXLS vykresľuje obsah a štruktúru, nie plný vizuálny štýl hárka. Výplne buniek, štýly orámovania okrajov, písma a farby jednotlivých buniek, grafy a vložené obrázky sú mimo toho, čo exportér kreslí; to, čo získate, je textová mriežka s jednotnými čiarami. Ide o rovnakú zmluvu, ktorú dodržiavajú exportéry do HTML a RTF, a je správnou voľbou pre reporty alebo odovzdávanie dát, kde čísla nesú význam a grafická téma nie

Keď je cieľom štylizovaný dokument v súlade s vizuálnou identitou značky, obvyklým postupom je najprv zostaviť čísla v šablóne tabuľky, čo podrobne popisuje workflow generovania reportov riadený šablónami. A keďže nič z tohto sa nedotýka COM ani bežiacej inštancie Excelu, potrubie (pipeline) vyhovuje rovnakému automatizačnému modelu bez balíka Office, ktorý HotXLS používa v celom rozsahu: čistý Pascal, nasaditeľný na serveri na pozadí bez potreby licencovania alebo stráženia interopu

Samostatné PDF, bajt po bajte

HotXLS zostavuje štruktúru súboru PDF ručne a počíta tabuľku krížových odkazov z presných bajtových offsetov, čo je dôvod, prečo sa výstup otvorí v každej čítačke. Pri serializácii každého objektu HotXLS zaznamená počiatočný offset tohto objektu pred pripojením jeho bajtov a potom posunie bežnú pozíciu o dĺžku, ktorú práve zapísal, takže tabuľka xref dopadne presne na každý objekt a startxref označuje miesto, kde táto tabuľka začína. Čítačka, ktorá zistí, že tieto offsety sú posunuté čo i len o jeden bajt, odmietne celý súbor, čo robí samovypočítaný offset nosným pilierom exportéra

Táto zmluva nesie so sebou jeden prísny dôsledok, ktorý stojí za to poznať. Uzol Pages sa zapisuje ako prvý ako objekt 1, ale jeho zoznam dcérskych stránok nie je známy, kým sa nevygenerujú všetky stránky, takže si ho HotXLS vyhradí ako zástupný symbol a pred spustením prechodu offsetov doplní finálnych potomkov a počet, nikdy nie potom. Akonáhle sú zmerané bajty objektu pre xref, sú zmrazené: zmena jedného bajtu neskôr by posunula každý nasledujúci offset a poškodila tabuľku. Je to drobná disciplína, ktorá prináša štandardom vyhovujúce PDF 1.4 bez potreby akejkoľvek knižnice pod ním

Metódy SaveAsPDF a trieda TXLSPDFExport zobrazené tu sa dodávajú s komponentom HotXLS Delphi Excel Component, spolu s exportérmi do CSV, HTML a RTF a kompletným API pre hárky pre Delphi a C++Builder