Teknisk artikel

Exportera Excel-kalkylblad till PDF i Delphi utan Office

För att exportera ett Excel-kalkylblad till PDF från Delphi eller C++Builder utan att Office är installerat, anropar du SaveAsPDF på ett HotXLS-kalkylblad eller en arbetsbok. HotXLS är en inbyggd VCL Excel-komponent, och dess kalkylblad-till-PDF-export renderar bladets använda område till en fristående PDF 1.4-fil. Den mappar Excels kolumnbredder och cellvisningstext till A4-sidor med automatisk sidnumrering över flera sidor. Varken någon kopia av Excel, skrivardrivrutin eller extern DLL-fil deltar i renderingen

HotXLS behandlar PDF som ett datapresentationsformat, ett syskon till dess CSV-, TSV- och HTML-exportvägar snarare än en pixel-exakt renderingsmotor. Exporten återskapar tabellinnehåll och layout: värdena du ser i rutnätet, kolumnproportionerna och stödlinjerna runt cellerna. Den inramningen är viktig eftersom den sätter en ärlig förväntan i förväg, och resten av den här artikeln handlar om exakt var gränsen går

Hur konverterar du Excel till PDF i Delphi utan Office?

Den kortaste vägen är ett enda anrop. TXLSWorksheet exponerar SaveAsPDF(FileName) och SaveAsPDF(Stream), och TXLSWorkbook exponerar samma två överlagringar som vidarebefordrar till det aktiva bladet. Var och en returnerar ett heltal (Integer), 1 vid framgång och -1 vid misslyckande, så att du kan förgrenas utifrån resultatet utan att behöva packa in anropet i egen undantagshantering

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;

När du anropar SaveAsPDF på ett kalkylblad exporterar HotXLS det bladets UsedRange, vilket är den omslutande rektangeln för varje ifylld cell. Arbetsbokens överlagring är en bekvämlighet som delegerar till det aktiva bladet, så en rapport med flera blad antingen loopar över de blad den behöver eller väljer det aktiva bladet före anropet. Det finns inget läge för hela arbetsboken som slår ihop alla flikar i ett enda steg: varje anrop renderar ett blad eller ett område

Hur förvandlar HotXLS ett använt område till PDF-sidor?

Hur förvandlar HotXLS ett använt område till PDF-sidor?

HotXLS går igenom det använda området cell för cell och lägger ut det som ett sidnumrerat rutnät. Kolumngeometrin kommer direkt från Excel: varje kolumnbredd konverteras från Excels breddenhet till typografiska punkter, med en minsta gräns så att ingen kolumn kollapsar till ett streck. När kolumnerna tillsammans är bredare än den användbara sidan skalar HotXLS ner dem enhetligt för att få plats; när de redan får plats lämnar den dem i sin naturliga bredd istället för att sträcka ut dem över bladet

Raderna flödar sedan nerför sidan tills nästa rad skulle korsa den nedre marginalen, varvid HotXLS öppnar en ny sida och fortsätter. Det innebär att ett kalkylblad med tusen rader sidnumreras automatiskt utan att du behöver hålla ordning på sidbrytningar. Varje cell skriver ut sin FormattedText, vilket är den visningssträng som produceras efter att talformatet har tillämpats, så att ett datum visas som det datum bladet visar och en valuta-cell behåller sina tusentalsavgränsare och symboler. Text som överskrider sin kolumn klipps till cellbredden istället för att spilla över till granncellen

Styra orientering, marginaler och teckenstorlek

För allt utöver standardlayouten styr du exportören direkt. TXLSPDFExport är klassen bakom enradshjälparna, och den publicerar tre egenskaper: Orientation (xlsPdfPortrait eller xlsPdfLandscape, stående som standard), Margin (punkter, standard 40) och FontSize (punkter, standard 9). Ställ in dem innan du anropar SaveAsPDF så plockar hela dokumentet upp them

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;

TXLSPDFExport accepterar också ett område istället för ett helt blad via SaveAsPDF(Range: IXLSRange; ...), vilket är hur du exporterar ett sammanfattningsblock ur ett blad som också innehåller tillfälliga beräkningar. Den överlagringen för område är samma som kalkylbladshjälparen lutar sig mot internt, så layouten, skalningen och sidnumreringen beter sig identiskt oavsett om du ger den ett helt använt område eller ett handvalt urval

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;

Varför HotXLS inte bäddar in något teckensnitt: avvägningen med Helvetica och WinAnsi

HotXLS skriver texten med PDF-filens inbyggda Helvetica och WinAnsiEncoding, ett medvetet val med noll beroenden men med en verklig begränsning. Eftersom Helvetica är ett av de standardiserade 14 teckensnitt som alla kompatibla PDF-läsare redan bär på, bäddar exportören inte in något teckensnittsprogram alls: filen förblir liten och kan öppnas var som helst, utan något att licensiera eller skicka med. Kostnaden för det valet är den teckenrepertoar som sidan kan visa

WinAnsiEncoding täcker Windows-1252-uppsättningen, så latinsk text, vanliga skiljetecken och de vanliga västeuropeiska accenterna renderas korrekt, och HotXLS lägger till en handfull typografiska tecken, smarta citattecken, tankstreck (en- och em-dash) samt eurotecknet i deras respektive CP1252-platser. Tecken utanför det intervallet, såsom CJK-ideogram, kyrilliska, grekiska och arabiska tecken, kollapsar till ett frågetecken på sidan. Om dina blad innehåller icke-latinsk text är denna exportör fel verktyg, och en PDF-renderingsmotor med full styling är det jobb som passar

Var kalkylblad-till-PDF-exporten upphör

HotXLS renderar innehåll och struktur, inte bladets fullständiga visuella stil. Cellfyllningar, kantstilar per kant, teckensnitt och färger per cell, diagram och inbäddade bilder ligger utanför vad exportören ritar; vad du får är textrutnätet med enhetliga stödlinjer. Det är samma kontrakt som HTML- och RTF-exportörerna respekterar, och det är det rätta för en rapport eller en dataöverföring där siffrorna bär innebörden och temat inte gör det

När målet är ett stylat, varumärkeskonsekvent dokument är det vanliga mönstret att först sätta ihop siffrorna i en kalkylbladsmall, vilket det mallstyrda rapportgenereringsflödet täcker på djupet. Och eftersom inget av detta rör COM eller en körande Excel-instans passar pipelinen samma Office-fria automationsmodell som HotXLS använder överallt: ren Pascal, driftsättbar på en headless server, utan något COM-interop att licensiera eller passa

Den fristående PDF-filen, byte for byte

HotXLS bygger PDF-filstrukturen för hand och beräknar sin korsreferenstabell utifrån exakta byte-offsetter, vilket är anledningen till att utdata kan öppnas i alla läsare. När den serialiserar varje objekt registrerar HotXLS objektets startoffset innan den lägger till dess byte, och flyttar sedan den löpande positionen med den längd den just skrev, så att xref-tabellen landar exakt på varje objekt och startxref markerar var den tabellen börjar. En läsare som hittar dessa offsetter ens en enda byte fel avvisar hela filen, vilket gör den självberäknade offsetten till exportörens mest bärande kontrakt

Det kontraktet medför en strikt konsekvens som är värd att känna till. Pages-noden skrivs först som objekt 1, men dess lista över underliggande sidor är inte känd förrän varje sida har genererats, så HotXLS reserverar den som en platshållare och korrigerar in de slutliga undersidorna och antalet innan offset-genomgången körs, aldrig efter. När ett objekts byte väl har mätts för xref är de frysta: att ändra en enda byte efteråt skulle förskjuta varje efterföljande offset och korrumpera tabellen. Det är en liten disciplin som ger en standardkompatibel PDF 1.4 utan något underliggande bibliotek

Metoderna SaveAsPDF och klassen TXLSPDFExport som visas här levereras med HotXLS Delphi Excel Component, tillsammans med exportörerna för CSV, HTML och RTF samt hela kalkylblads-API:et för Delphi och C++Builder