Kuidas luua PDF-faile React komponentidest [kliendipoolne lahendus]

Kui olete kunagi tegelenud B2B armatuurlauarakendusega, teate, et ettevõtted armastavad pdf-vormingus aruandeid.

Alusfoto Lauren Richmond saidil Unsplash

Kui ma selle probleemiga esimest korda kokku puutusin, oli meil analüüsi leht, mille tahtsime pdf-faili teisendada. Minu instinkt oli lisada fail print.css ja lasta brauseril kogu räpase tööga hakkama saada. Pikk lugu lühike, see ei toimi.

Spetsiifilise stiililehe abil tabasin enamiku oma veebispetsiifiliste stiilide tühistamisest. Ka lõpptulemus polnud kuigi ahvatlev. Samuti on raske PDF-faili sisu HTML-vormingus vormistada. See, mis brauseris peeneks teeb, tundub PDF-is kohutav.

Hakkasime PhantomJS-i eksemplari abil serveri poolel PDF-e genereerima. Näete seda serveripoolset lähenemist toimimas PFRepo veebisaidil: https://pfrepo.me. Seda kasutatakse veebiversioonide pdf-versiooni genereerimiseks)

Parem viis on pdf-faili renderdamine otse esipaneelil. Kliendipoolne lähenemine on kiire (võrgus pole midagi edastada), vähem liikuvaid osi (ilma peata brauseriteta) ja täpne. See võimaldab ka PDF-ide mõtestamise asemel jätkata html-i kujundamist.

Kliendipoolse pdf-faili genereerimine on kolmeastmeline protsess:

  • Teisendage DOM SVG-ks
  • Teisendage svg png-iks
  • Teisendage png pdf-vormingus

Ma kasutan selles näites Reakti, kuid sama lähenemisviis võib toimida ka nurga, vue või mõne muu frontend-süsteemiga. Meil on vaja lihtsalt vanilje js.

Allpool olevas IDE-s näete kahte renderdatud lehte. Üks eeldab, et meie sisu mahub ühele lehele, ja teine, kui sisu suurus võib olla dünaamiline ja vajab rohkem kui ühte lehte.

1. samm: teisendage A4 DOM SVG-ks

html2canvas on hea teek DOM-i teisendamiseks SVG-ks. Api on üsna lihtne.

HTML-i teisendamine SVG-ks

2. samm: teisendage svg PNG-ks

Seda saab teha vanilje js abil:

const input = document.getElementById ('divIdToPrint');
html2kanvas (sisend)
  . seejärel ((lõuend) => {
    const imgData = canvas.toDataURL ('pilt / png');
  })
;

3. samm: teisendage png pdf-faili

Selle saavutab raamatukogu nimega jsPDF. Kasutus muudab 2. sammu koodi järgmiselt:

html2kanvas (sisend)
  . seejärel ((lõuend) => {
    const imgData = canvas.toDataURL ('pilt / png');
    const pdf = uus jsPDF ();
    pdf.addImage (imgData, 'PNG', 0, 0);
    pdf.save ("download.pdf");
  });
;

Mitme lehe käsitsemine

Ok, seega on meil võimalus printida DOM-i pdf-vormingusse, kuid meie praegused seadistused saavad printida ainult üksikuid lehti. Mis saab, kui meil on mitu lehte?

Selle saavutamiseks on kaks võimalust:

> Lihtne viis

Printige piklik pdf ja laske süsteemil lehekatkestustega hakkama saada.

> Õige tee

Tehke mõni kiire matemaatika, et aru saada, kui palju lehti on vaja. Arvutage lehtede nihked ja kõrgused ning käivitage ühe lehe protsess kõigil lehtedel.

Tulemus

Alloleval StackBlitzi IDE-l on kood ja ui töös. Käsitlesin mitut lehte hõlpsalt pärast õigel teel loobumist (mis on koodis olemas).

On ka teisi lahendusi, näiteks React-PDF, mis tutvustavad optimeeritud komponente, mida saab pdfs-le renderdada. Olen proovinud sellega töötada, kuid tunnen, et projekt on alles sündimas. Proovige julgelt ka seda lähenemist.

[25. august 2018] Uuendus 0; Selle lähenemisviisi puudused

Paljud siinsed (ja redditi) inimesed juhtisid tähelepanu sellele, et selle lähenemisviisi abil loodud pdf-failide teksti ei saa valida. Kui see tekitab muret, võiksite lugeda seda William Kwoki postitust. See kõnnib läbi veel ühe teegi, mis võimaldab genereerida reageerivaid komponente valitava tekstiga pdf-is.

Kui teile see artikkel meeldis ja soovite end värskendada, siis jälgige mind saidil: Keskmine, Github või Twitter

Ta