Jak wygenerować PDF z HTML w aplikacji React/Node.js
Eugene Zolotarenko
20 maj 2021・6 min czytania
Spis treści
Korzystanie z natywnego drukowania w przeglądarce i reguł wydruku CSS
Zrzut ekranu z DOM (HTML => Canvas => Obraz => PDF)
Użycie bibliotek PDF / JavaScript
Puppeteer, Headless Chrome i Node.js
Podsumowanie
FAQ
Generowanie PDF ze strony internetowej może się wydawać prostą czynnością, niewymagającą wiele czasu ani wysiłku. Rzeczywistość bywa jednak inna, a znalezienie najlepszego rozwiązania często okazuje się wyzwaniem.
Rozważmy taki hipotetyczny scenariusz:
Mamy aplikację React, w której chcemy utworzyć PDF z całej strony lub tylko z jej fragmentu. Nasz dokument PDF może zawierać wykresy, tabele, obrazy i/lub zwykły tekst i powinien być złożony bez ucięć ani nakładających się elementów. Chcemy też przycisk na stronie, który pozwoli nam zapisać dokument.
W tym artykule przeprowadzę Cię przez różne rozwiązania, wskazując ich plusy i minusy. Zaczniemy od najprostszego, a potem przejdziemy do najbardziej złożonych.
Korzystanie z natywnego drukowania w przeglądarce i reguł wydruku CSS
Generalnie przeglądarka potrafi już zapisywać i drukować PDF-y z naszych stron: wystarczy wcisnąć Ctrl/Cmd + P, aby wyświetlić okno z ustawieniami wyglądu dokumentu.
Przycisk wywołujący tę samą akcję może wyglądać tak:
const SavePdfButton=()=>{
return (
<button onClick={window.print()}>Download PDF</button>
)
}Jeśli chcemy zmienić wygląd, ukryć pewne elementy lub dopasować ich rozmiar w PDF-ie, możemy napisać reguły wydruku w CSS:
@media print {
.save-button {
display: none;
}
.content {
width: 100%;
}
}Możemy też kontrolować podziały stron i/lub wyeliminować nakładanie się elementów. Służą do tego konkretne właściwości CSS, np.:
@media print {
h1 {
break-before: always;
}
table, img, svg {
break-inside: avoid;
}
}Oto świetny, darmowy artykuł opisujący więcej możliwości reguł wydruku w CSS.
Przy małych, prostych przypadkach to rozwiązanie jest idealne i użycie bibliotek byłoby tu przerostem formy nad treścią. Nie sprawdzi się jednak, gdy potrzebujemy mieć dostęp do dokumentów generowanych z poziomu kodu.
Zalety:
Brak zewnętrznych bibliotek
Prosta implementacja, włącznie z ustawieniem orientacji strony
Nie obciąża komputera użytkownika
Umożliwia zaznaczanie i wyszukiwanie tekstu
Wady:
Trudno uzyskać identyczny efekt w różnych przeglądarkach
Różnice w renderowaniu mogą utrudniać znalezienie przycisków zapisu
Brak dostępu do PDF-a generowanego z poziomu kodu
Zawartość PDF-a zależy od rozmiaru okna przeglądarki
Zrzut ekranu z DOM (HTML => Canvas => Obraz => PDF)
To kolejne proste rozwiązanie: wykonaj zrzut strony lub elementu i przekształć go w PDF za pomocą Canvas i konwersji obrazu:
html2canvas – do utworzenia zrzutu z HTML i wygenerowania Canvas
jsPDF – do przekształcenia obrazu w PDF
Część Canvas => Obraz można zrobić w czystym JavaScripcie. Funkcja może wyglądać tak:
import html2canvas from 'html2canvas'
import jsPdf from 'jspdf';
function savePdf(){
const domElement=document.querySelector('#container')
html2canvas(domElement, { onclose: (document)=>{
document.querySelector('#save-button').style.visibility='hidden'
}})
.then((canvas)=>{
const img=canvas.toDataURL('image/jpeg')
const pdf=new jsPdf()
pdf.addImage(imgData, 'JPEG',0,0,width,height)
pdf.save('filename.pdf')
})
}Jak widać, przed konwersją HTML => Canvas można dodać własne style.
Jeśli jednak HTML jest długi, możesz rozdzielić różne elementy na osobne strony. Zrób zrzuty wielu elementów i połącz je w jeden dokument PDF:
import html2canvas from 'html2canvas'
import jsPdf from 'jspdf'
function savePdf(){
const domElements=document.querySelectorAll('.container')
const pdf=new jsPdf()
domElements.forEach((element,i)=>{
const img=canvas.toDataURL('image/jpeg')
pdf.addImage(imgData,'JPEG',0,0,width,height)
const isSectionLast=domElements.length===i+1;
if(isSectionLast){
pdf.save('filename.pdf')
}else{
doc.addPage()
}
}
}W ten sposób przygotujesz całkiem dobre PDF-y, bardzo zbliżone do oryginalnego HTML-a, z kontrolą nad wyglądem dokumentu i zakresem elementów, które się w nim znajdą. Minusem jest nadal brak możliwości zaznaczania i wyszukiwania tekstu.
Zalety:
Bardzo wierne względem HTML-a
Łatwa implementacja
Dostęp do PDF-a generowanego z poziomu kodu
Wady:
Brak możliwości zaznaczania i wyszukiwania tekstu, zwłaszcza przy banerach cookies
Zawartość PDF-a zależy od rozmiaru okna przeglądarki
Wymaga zewnętrznych paczek
Użycie bibliotek PDF / JavaScript
jsPDF (wspomniane wyżej), PDFKit, React-pdf to biblioteki, których możesz użyć do tworzenia PDF w React, jednak pozostaje problem: cały HTML i CSS trzeba przygotować specjalnie dla dokumentu PDF.
W naszym scenariuszu to również za mało, ponieważ wolimy po prostu skopiować istniejący HTML z drobnymi zmianami, a nie pisać go od nowa w wariancie pod PDF. Mimo to to dobre wyjście, jeśli chcesz tworzyć PDF od zera na podstawie danych z innego źródła.
Tak może to wyglądać z React-pdf:
import {Page,Text,View,Document,StyleSheet} from "@reat-pdf/renderer';
const styles=StyleSheet.create({
page:{
backgroundColor: "#E4E4E4"
},
section:{
margin: 10,
}
})
const MyDocument=()=>{
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section</Text>
</View>
</Page>
</Document>
}Zalety:
Daje dostęp do PDF-a generowanego z poziomu kodu
Zawartość PDF-a nie zależy od rozmiaru okna przeglądarki ani daty utworzenia.
Wynik jest identyczny w różnych przeglądarkach
Umożliwia zaznaczanie i wyszukiwanie tekstu
Wady:
Nie skopiujesz istniejącego HTML-a ze strony
Może być czasochłonne.
Kod często zawiera dwie wersje tego samego projektu
Puppeteer, Headless Chrome i Node.js
Ponieważ kod działa po stronie backendu, to rozwiązanie jest najbardziej złożone i inne niż w pełni klienckie podejścia wspomniane wyżej.
Innymi słowy, Puppeteer to przeglądarka uruchamiana z poziomu Node.js. Z dokumentacji wynika, że można go użyć do generowania zrzutów ekranu i PDF-ów stron.
Oto przykład, który przechodzi bezpośrednio pod wskazany URL, dodaje styl i generuje plik PDF:
const puppeter=require('puppeteer')
async function savePdf(){
const browser=await puppeteer.launch({headless: true})
const page=await browser.newPage();
await page.goto('https://start-up.house',{waitUntil:'networkidle0'});
await page.addStyleTag({content: '#save-button {display: none}'})
const pdf=await page.pdf({format: 'A4'});
await browser.close();
return pdf;
}Po utworzeniu dokument jest odsyłany do frontendu. Po stronie klienta pobieramy go, zamieniamy na Blob i zapisujemy.
Na przykład tak:
function savePdf(){
return fetchPdfData().then((pdfData)=>{
const blob=new Blob([pdfData],{type: 'application/pdf'})
const link=document.createElement('a')
link.href=window.URL.createObjectURL(blob)
link.download='file-name.pdf'
link.click()
}
}To wydaje się najbardziej kompletne rozwiązanie, bo daje najwięcej korzyści i poradzi sobie nawet z trudnymi przypadkami. Co więcej, wygenerowany dokument pozwala zaznaczać i wyszukiwać tekst, a także może być zapisany na serwerze bez dodatkowych wywołań API.
Zalety:
Dostęp do PDF-a generowanego z poziomu kodu
Zawartość PDF-a nie zależy od rozmiaru okna przeglądarki
Umożliwia zaznaczanie i wyszukiwanie tekstu
Bardzo zbliżone do HTML-a
Nie obciąża komputera użytkownika
Wady:
Wymaga kodu po stronie klienta i serwera
Implementacja bywa skomplikowana w niektórych przypadkach
Podsumowanie
Jak widzieliśmy, generowanie PDF-ów z HTML-a bywa problematyczne. Nie musi jednak takie być — powyższe przykłady to tylko kilka opcji, które warto rozważyć. Z odrobiną prób i błędów wyjdziesz z impasu, więc testuj różne podejścia, aby sprawdzić, które rozwiązanie najlepiej działa dla Ciebie.
I... powodzenia!
Jeśli chcesz wiedzieć więcej, skontaktuj się z nami - hello@start-up.house
FAQ
Jak zapisać całą stronę HTML jako dokument PDF w React?
- Korzystając z różnych metod opisanych w artykule możesz przekonwertować stronę HTML na dokument PDF. Najprostszym sposobem jest natywne drukowanie w przeglądarce z użyciem reguł wydruku CSS.
Jakie biblioteki pomagają w konwersji HTML do PDF w aplikacji React?
- React PDF, PDFKit i jsPDF to popularne biblioteki do tego celu. Jeśli korzystasz konkretnie z biblioteki React PDF, kluczowe jest użycie odpowiednich komponentów React PDF, aby osiągnąć zamierzony efekt.
Czy eksport strony HTML do pliku PDF zachowuje kolor tła i niestandardowe fonty?
- W dużej mierze zależy to od wybranej metody. Część rozwiązań może nie zachować koloru tła i własnych fontów, ale inne — zwłaszcza oparte na Puppeteer lub dedykowanych bibliotekach — często to robią.
Gdy próbuję utworzyć dokument PDF w aplikacji React, kolor tła różni się od oryginalnej strony HTML. Dlaczego?
- Dokładne odwzorowanie koloru tła podczas konwersji HTML do PDF zależy od metody lub biblioteki. Upewnij się, że wybrane rozwiązanie wspiera zachowanie tła.
Czy można wyeksportować domyślną zawartość aplikacji z projektu React do pliku PDF?
- Tak — w zależności od zawartości i struktury aplikacji możesz użyć narzędzi i bibliotek, aby płynnie wyeksportować treści do pliku PDF.
Czy mogę przekonwertować ciąg HTML na dokument PDF w aplikacji React, używając jsPDF?
- Tak. Z jsPDF możesz konwertować HTML, w tym łańcuchy HTML, na dokumenty PDF. Połączenie z innymi narzędziami lub bibliotekami może dodatkowo uprościć proces konwersji w aplikacji React.
Jakie są główne różnice między konwersją HTML do PDF a zrzutem ekranu metodą DOM w aplikacji React?
- Przy bezpośredniej konwersji HTML do PDF powstały plik zwykle pozwala zaznaczać i wyszukiwać tekst. W metodzie zrzutu (HTML => Canvas => Obraz => PDF) PDF jest w praktyce obrazem, więc zaznaczanie tekstu może nie być możliwe.
Jak zapewnić spójny kolor tła podczas konwersji strony HTML do dokumentu PDF?
- Wybieraj dedykowane narzędzia i biblioteki, które priorytetowo traktują zachowanie stylów, takie jak Puppeteer lub React PDF — to pomaga utrzymać spójny kolor tła podczas konwersji.
Co jest bardziej czasowo efektywne: tworzenie pliku PDF od zera przy użyciu React PDF czy konwersja HTML do PDF?
- Konwersja istniejącego HTML do PDF jest zazwyczaj szybsza, bo wykorzystujesz już gotową treść. Tworzenie PDF-a od zera w React PDF może być bardziej czasochłonne, zwłaszcza przy złożonym projekcie.
Jak radzić sobie z dużymi plikami PDF przy konwersji długiej strony HTML w React?
- W przypadku długich stron warto dzielić treść na sekcje lub strony dla lepszej czytelności. Biblioteki takie jak Puppeteer oferują funkcje ułatwiające zarządzanie i paginację długiej treści.
Na czym polega proces 'html to pdf react' w tworzeniu aplikacji webowych?
- Proces 'html to pdf react' odnosi się do metody konwertowania treści HTML w aplikacji React na dokument PDF. Zwykle odbywa się to przy użyciu bibliotek, które odwzorowują strukturę i style HTML, tworząc plik PDF do zapisania, wydruku lub udostępnienia.
Jakie biblioteki są najczęściej używane do konwersji 'html to pdf react'?
- Popularne biblioteki do 'html to pdf react' to jsPDF i html2canvas. Wspólnie pozwalają uchwycić HTML renderowany przez komponenty React i przekonwertować go do formatu PDF, możliwie wiernie zachowując układ i style.
Czy w procesie 'html to pdf react' występują wyzwania?
- Jednym z głównych wyzwań w 'html to pdf react' jest zapewnienie, że przekonwertowany PDF dokładnie odzwierciedla oryginalną zawartość HTML pod względem układu, stylów i ewentualnej interakcji. Częstym wyzwaniem jest też obsługa dynamicznych danych i dużych dokumentów.
Jak zapewnić wysoką jakość wyników w procesie 'html to pdf react'?
- Aby zapewnić wysoką jakość w 'html to pdf react', wybierz sprawdzone biblioteki, testuj konwersję na różnych typach treści i rozważ rozwiązania szyte na miarę dla złożonych layoutów lub danych dynamicznych. Regularne aktualizacje i optymalizacja kodu również pomagają tworzyć lepsze PDF-y.
Czy można obsłużyć treści interaktywne w konwersji 'html to pdf react'?
- Podstawowa interaktywność może być częściowo obsłużona w 'html to pdf react', ale złożone elementy, takie jak efekty hover czy klikalne linki, mogą nie zostać w pełni odwzorowane w PDF. Zazwyczaj celem jest wierne uchwycenie prezentacji wizualnej, a nie interakcji.
Digital Transformation Strategy for Siemens Finance
Cloud-based platform for Siemens Financial Services in Poland


Może Ci się również spodobać...

Jak wybrać najlepszą agencję Node.js w 2023 roku: kompleksowy przewodnik
Node.js stał się kluczową technologią do tworzenia niezawodnych, skalowalnych aplikacji webowych. W tym kontekście rola firm programistycznych specjalizujących się w Node.js jest ważniejsza niż kiedykolwiek. Ten artykuł pomoże Ci wybrać najlepsze firmy specjalizujące się w Node.js, dopasowane do Twoich potrzeb.
Marek Pałys
02 lut 2023・6 min czytania

4 powody, aby użyć Chakra UI w swoim kolejnym projekcie
Chakra UI to prosta, modułowa i dostępna biblioteka komponentów do szybkiego tworzenia aplikacji React. Dzięki łatwemu dostosowaniu, obsłudze trybu ciemnego, responsywnemu designowi i naciskowi na dostępność Chakra UI wyróżnia się na tle innych bibliotek UI, co czyni ją świetnym wyborem dla deweloperów React.
Mateusz Wójcik
19 sty 2021・4 min czytania

Jak wdrożyliśmy SWR w projekcie i dlaczego go pokochaliśmy
SWR, biblioteka React Hooks do zdalnego pobierania danych, oferuje prosty, a zarazem niezwykle skuteczny sposób na obsługę cache, rewalidację i pobieranie danych w aplikacjach React. Dowiedz się, jak SWR upraszcza zarządzanie fragmentami stanu, przyspiesza tworzenie aplikacji i poprawia wydajność UI. Zobacz przykłady implementacji SWR i poznaj jego integracje.
Kamil Polok
09 cze 2021・6 min czytania
Gotowy, aby scentralizować swoje know-how z pomocą AI?
Rozpocznij nowy rozdział w zarządzaniu wiedzą — gdzie Asystent AI staje się centralnym filarem Twojego cyfrowego wsparcia.
Umów bezpłatną konsultacjęPracuj z zespołem, któremu ufają firmy z czołówki rynku.




