Tekninen artikkeli

Excel-taulukoiden vienti PDF-muotoon Delphissä ilman Officea

Viedäksesi Excel-taulukon PDF-muotoon Delphistä tai C++Builderista ilman, että koneelle on asennettu Officea, kutsu SaveAsPDF-metodia HotXLS-taulukolle tai -työkirjalle. HotXLS on natiivi VCL Excel -komponentti, ja sen taulukko-PDF-vienti renderöi taulukon käytetyn alueen (used range) itsenäiseksi PDF 1.4 -tiedostoksi. Se mäppää Excelin sarakkeleveydet ja solujen näyttötekstit A4-sivuille automaattisella sivutuksella. Renderöintiin ei osallistu Excel-kopio, tulostinohjain eikä ulkoinen DLL-kirjasto

HotXLS käsittelee PDF-muotoa tietojen esitysmuotona, joka on sen CSV-, TSV- ja HTML-vientipolkujen sisarus, eikä niinkään pikselintarkkana renderöintimoottorina. Vienti toistaa taulukkomuotoisen sisällön ja asettelun: ruudukossa näkyvät arvot, sarakkeiden suhteet ja solujen ympärillä olevat apuviivat. Tällä rajauksella on merkitystä, koska se asettaa rehellisen odotuksen etukäteen, ja loppuosa tästä artikkelista käsittelee sitä, mihin raja tarkalleen ottaen asettuu

Miten Excel muunnetaan PDF-muotoon Delphissä ilman Officea?

Lyhin polku on yksi kutsu. TXLSWorksheet tarjoaa ylikuormitetut metodit SaveAsPDF(FileName) ja SaveAsPDF(Stream), ja TXLSWorkbook tarjoaa samat kaksi ylikuormitusta, jotka välittävät kutsun aktiiviselle taulukolle. Kukin palauttaa kokonaisluvun (Integer), jossa 1 tarkoittaa onnistumista ja -1 epäonnistumista, joten voit haarautua tuloksen perusteella ilman, että sinun tarvitsee kääriä kutsua omaan poikkeustenkäsittelyyn

var
  Book: TXLSWorkbook;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('sales-june.xlsx');
    // Renderöi aktiivisen taulukon käytetty alue suoraan tiedostoon report.pdf.
    if Book.SaveAsPDF('report.pdf') = 1 then
      Writeln('PDF written');
  finally
    Book.Free;
  end;
end;

Kun kutsut SaveAsPDF-metodia taulukolle, HotXLS vie kyseisen taulukon UsedRange-alueen eli jokaisen täytetyn solun ympäröivän suorakulmion. Työkirjan ylikuormitus on mukavuusmetodi, joka delegoi kutsun aktiiviselle taulukolle, joten monisivuinen raportti joko silmukoi tarvittavat taulukot tai valitsee aktiivisen taulukon ennen kutsua. Työkirjassa ei ole kokonaista työkirjaa kerralla yhdistävää tilaa, joka yhdistäisi jokaisen välilehden yhdeksi tiedostoksi: jokainen kutsu renderöi yhden taulukon tai yhden alueen

Miten HotXLS muuttaa käytetyn alueen PDF-sivuiksi?

HotXLS käy läpi käytetyn alueen solu solulta ja asettelee sen sivutetuksi ruudukoksi. Sarakkeiden geometria tulee suoraan Excelistä: kukin sarakkeen leveys muunnetaan Excelin leveysyksiköstä typografisiksi pisteiksi, ja siinä on minimiraja, jotta mikään sarake ei kutistu olemattomaksi. Kun sarakkeet yhdessä ovat leveämpiä kuin käytettävissä oleva sivu, HotXLS skaalaa ne tasaisesti sopiviksi. Kun ne jo mahtuvat sivulle, se jättää ne luonnolliseen leveyteensä sen sijaan, että venyttäisi niitä sivun poikki

Rivit virtaavat sivua alaspäin, kunnes seuraava ylittäisi alareunuksen, jolloin HotXLS avaa uuden sivun ja jatkaa. Siten tuhatrivinen taulukko sivutetaan itsestään ilman, että sinun tarvitsee pitää kirjaa sivunvaihdoista. Jokainen solu tulostaa FormattedText-arvonsa, eli näyttömerkkijonon joka syntyy lukumuotoilun soveltamisen jälkeen, joten päivämäärä näkyy taulukon mukaisena ja valuuttasolu säilyttää tuhansien erottimensa ja symbolinsa. Teksti, joka ylittää sarakkeensa, leikataan sarakkeen leveyteen sen sijaan, että se valuisi naapurisolun päälle

Suunnan, reunusten ja fonttikoon hallinta

Kaikessa oletusasettelun ylittävässä hallinnassa ohjaa vientiohjelmaa suoraan. TXLSPDFExport on yhden rivin apureiden taustalla oleva luokka, ja se julkaisee kolme ominaisuutta: Orientation (xlsPdfPortrait tai xlsPdfLandscape, oletuksena pysty), Margin (pisteinä, oletus 40) ja FontSize (pisteinä, oletus 9). Aseta ne ennen kuin kutsut SaveAsPDF-metodia, ja koko asiakirja omaksuu ne

var
  Book: TXLSWorkbook;
  Exporter: TXLSPDFExport;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('wide-ledger.xlsx');
    Exporter := TXLSPDFExport.Create;
    try
      Exporter.Orientation := xlsPdfLandscape;  // sovita leveät taulukot sivulle
      Exporter.Margin := 28;                     // tiukempi sivumarginaali pisteinä
      Exporter.FontSize := 8;                    // tiheämmät rivit
      Exporter.SaveAsPDF(Book.ActiveSheet, 'ledger.pdf');
    finally
      Exporter.Free;
    end;
  finally
    Book.Free;
  end;
end;

TXLSPDFExport ottaa vastaan myös alueen kokonaisen taulukon sijasta SaveAsPDF(Range: IXLSRange; ...)-metodin kautta. Tällä tavalla voit viedä yhteenvetolohkon taulukosta, joka sisältää myös luonnoslaskelmia. Tämä alueylikuormitus on sama, johon taulukkoapuri nojaa sisäisesti, joten asettelu, skaalaus ja sivutus käyttäytyvät identtisesti riippumatta siitä, annatko sille täyden käytetyn alueen vai käsin valitun osan

var
  Book: TXLSWorkbook;
  Exporter: TXLSPDFExport;
  Summary: IXLSRange;
begin
  Book := TXLSWorkbook.Create;
  try
    Book.Open('quarter.xlsx');
    // Vie vain yhteenvetolohko, älä sen vieressä olevia luonnossarakkeita.
    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;

Miksi HotXLS ei upota fonttia: Helvetica- ja WinAnsi-kompromissi

HotXLS kirjoittaa tekstin PDF:n sisäänrakennetulla Helvetica-fontilla ja WinAnsiEncoding-koodauksella. Tämä on tietoinen nollariippuvuusvalinta, jolla on yksi todellinen rajoitus. Koska Helvetica on yksi niistä standardista 14 fontista, jotka jokainen yhteensopiva PDF-lukija jo sisältää, vientiohjelma ei upota fonttiohjelmaa lainkaan. Tiedosto pysyy pienenä ja avautuu missä tahansa, ilman että sen mukana tarvitsee lisensoida tai toimittaa mitään. Tämän valinnan hinta on sivulla näytettävien merkkien valikoima

WinAnsiEncoding kattaa Windows-1252-merkistön, joten latinalainen teksti, yleiset välimerkit ja tavalliset länsieurooppalaiset aksentit renderöityvät oikein, ja HotXLS sijoittaa kourallisen typografisia merkkejä, kaarevia lainausmerkkejä, en- ja em-viivoja sekä euro-symbolin niiden CP1252-paikoille. Tämän alueen ulkopuolella olevat merkit, kuten CJK-ideografit, kyrilliset, kreikkalaiset ja arabialaiset merkit, romahtavat sivulla kysymysmerkiksi. Jos taulukkosi sisältävät muuta kuin latinalaista tekstiä, tämä vientiohjelma on väärä työkalu, ja täydellisen tyylittelyn tarjoava PDF-renderöijä on tehtävään sopiva valinta

Mihin taulukko-PDF-vienti pysähtyy

HotXLS renderöi sisällön ja rakenteen, ei taulukon täydellistä visuaalista tyyliä. Solujen täytöt, reunaviivojen tyylit reunoittain, solukohtaiset fontit ja värit, kaaviot ja upotetut kuvat jäävät vientiohjelman piirtämän alueen ulkopuolelle. Saat tulokseksi tekstiruudukon tasaisilla apuviivoilla. Tämä on sama sopimus, jota HTML- ja RTF-vientiohjelmat noudattavat, ja se on oikea valinta raportille tai tiedonluovutukselle, jossa luvut kantavat merkityksen eikä teema

Kun tavoitteena on tyylitelty, brändin mukainen asiakirja, yleinen malli on koota luvut ensin taulukkomalliin, mitä malliohjattu raportinluontityönkulku käsittelee syvällisesti. Ja koska mikään tästä ei kosketa COM-liittymää tai käynnissä olevaa Excel-instanssia, putki sopii samaan Office-vapaaseen automaatiomalliin, jota HotXLS käyttää läpi linjan: puhdasta Pascalia, joka on otettavissa käyttöön headless-palvelimella ilman lisensoitavaa tai valvottavaa interopia

Itsenäinen PDF, tavu tavulta

HotXLS rakentaa PDF-tiedostorakenteen käsin ja laskee sen ristiviitetaulukon (cross-reference table) tarkoista tavujen siirtymistä (byte offsets). Tämä on syy siihen, miksi tuloste avautuu jokaisessa lukijassa. Kun se sarjoittaa kunkin objektin, HotXLS tallentaa kyseisen objektin aloitusaseman ennen sen tavujen lisäämistä ja siirtää sitten juoksevaa asemaa juuri kirjoittamansa pituuden verran, joten xref-taulukko kohdistuu tarkasti jokaiseen objektiin ja startxref merkitsee paikan, josta kyseinen taulukko alkaa. Lukija, joka havaitsee näiden siirtymien olevan vaikkapa vain yhden tavun vinossa, hylkää koko tiedoston, mikä tekee itse lasketusta siirtymästä vientiohjelman tärkeimmän sopimuksen

Tällä sopimuksella on yksi tiukka seuraus, joka on syytä tietää. Pages-solmu kirjoitetaan ensin objektina 1, mutta sen lapsisivujen luettelo ei ole tiedossa ennen kuin jokainen sivu on tuotettu, joten HotXLS varaa sen paikkamerkiksi ja paikkaa lopulliset lapset ja määrän ennen offset-vaiheen ajamista, ei koskaan sen jälkeen. Kun objektin tavut on mitattu xref-taulukkoa varten, ne jäätyvät: yhdenkin tavun muuttaminen sen jälkeen siirtäisi jokaista seuraavaa siirtymää ja korruptoisi taulukkoa. Se on pieni kurinalaisuus, joka ostaa standardien mukaisen PDF 1.4 -tiedoston ilman kirjastoa sen alla

Tässä esitetyt SaveAsPDF-metodit ja TXLSPDFExport-luokka toimitetaan HotXLS Delphi Excel -komponentin mukana, yhdessä CSV-, HTML- ja RTF-vientiohjelmien sekä Delphin ja C++Builderin täydellisen taulukko-API:n kanssa