Case StudiesBlogO nas
Porozmawiajmy

Jak wygenerować PDF z HTML w aplikacji React/Node.js

Eugene Zolotarenko

20 maj 20216 min czytania

ReactNode.js

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 - 

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.

Opublikowany 20 maja 2021

Udostępnij


Eugene Zolotarenko

Front-End Developer

Digital Transformation Strategy for Siemens Finance

Cloud-based platform for Siemens Financial Services in Poland

See full Case Study
Ad image
Jak wygenerować PDF z HTML w aplikacji React/Node.js
Nie przegap żadnego artykułu - zapisz się do naszego newslettera
Zgadzam się na otrzymywanie komunikacji marketingowej od Startup House. Kliknij, aby zobaczyć szczegóły

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

Jak wybrać najlepszą agencję Node.js w 2023 roku: kompleksowy przewodnik
Node.jsDigital products

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 20236 min czytania

4 powody, aby użyć Chakra UI w swoim kolejnym projekcie
Chakra UIReact

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 20214 min czytania

Jak wdrożyliśmy SWR w projekcie i dlaczego go pokochaliśmy
Next.jsReact

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 20216 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.

Rainbow logo
Siemens logo
Toyota logo

Budujemy to, co będzie dalej.

Firma

Startup Development House sp. z o.o.

Aleje Jerozolimskie 81

Warszawa, 02-001

VAT-ID: PL5213739631

KRS: 0000624654

REGON: 364787848

Kontakt

hello@startup-house.com

Nasze biuro: +48 789 011 336

Nowy biznes: +48 798 874 852

Obserwuj nas

Award
logologologologo

Copyright © 2026 Startup Development House sp. z o.o.

UE ProjektyPolityka prywatności