Jak utworzyć plik PDF ze swojej aplikacji internetowej?
Opublikowany: 2022-03-10Wiele aplikacji internetowych wymaga udostępnienia użytkownikowi możliwości pobrania czegoś w formacie PDF. W przypadku aplikacji (takich jak sklepy internetowe) te pliki PDF muszą być tworzone przy użyciu dynamicznych danych i być natychmiast dostępne dla użytkownika.
W tym artykule omówię sposoby generowania plików PDF bezpośrednio z aplikacji internetowej w locie. Nie jest to wyczerpująca lista narzędzi, ale zamiast tego zamierzam zademonstrować różne podejścia. Jeśli masz ulubione narzędzie lub własne doświadczenia, którymi możesz się podzielić, dodaj je do komentarzy poniżej.
Zaczynając od HTML i CSS
Nasza aplikacja internetowa prawdopodobnie już tworzy dokument HTML, korzystając z informacji, które zostaną dodane do naszego pliku PDF. W przypadku faktury użytkownik może być w stanie wyświetlić informacje online, a następnie kliknąć, aby pobrać plik PDF do swojej dokumentacji. Być może tworzysz listy przewozowe; po raz kolejny informacje są już przechowywane w systemie. Chcesz to w ładny sposób sformatować do pobrania i wydrukowania. Dlatego dobrym miejscem do rozpoczęcia jest rozważenie, czy możliwe jest użycie tego kodu HTML i CSS do wygenerowania wersji PDF.
CSS ma specyfikację, która dotyczy CSS w druku, a jest to moduł Paged Media. Mam przegląd tej specyfikacji w moim artykule „Projektowanie do druku za pomocą CSS”, a CSS jest używany przez wielu wydawców książek we wszystkich swoich wydrukach. Skoro więc CSS sam posiada specyfikacje materiałów drukowanych, to z pewnością powinniśmy być w stanie z niego korzystać?
Najprostszym sposobem, w jaki użytkownik może wygenerować plik PDF, jest użycie przeglądarki. Wybierając drukowanie w formacie PDF zamiast na drukarce, zostanie wygenerowany plik PDF. Niestety ten plik PDF zwykle nie jest całkowicie satysfakcjonujący! Na początek będzie zawierał nagłówki i stopki, które są automatycznie dodawane, gdy drukujesz coś ze strony internetowej. Zostanie również sformatowany zgodnie z arkuszem stylów drukowania — zakładając, że go masz.
Problem, na który napotykamy, to słaba obsługa specyfikacji fragmentacji w przeglądarkach; może to oznaczać, że zawartość Twoich stron łamie się w nietypowy sposób. Obsługa fragmentacji jest niejednolita, jak odkryłem, gdy przejrzałem mój artykuł „Breaking Boxes with CSS Fragmentation”. Oznacza to, że możesz nie być w stanie zapobiec nieoptymalnemu łamaniu treści, ponieważ nagłówki są pozostawiane jako ostatni element na stronie i tak dalej.
Ponadto nie mamy możliwości kontrolowania zawartości pól marginesów strony, np. dodawania wybranego przez nas nagłówka do każdej strony lub numerowania stron, aby pokazać, ile stron ma złożona faktura. Te elementy są częścią specyfikacji Paged Media, ale nie zostały zaimplementowane w żadnej przeglądarce.
Mój artykuł „A Guide To the State Of Print Stylesheets In 2018” jest nadal dokładny, jeśli chodzi o rodzaj wsparcia, jakie przeglądarki mają do drukowania bezpośrednio z przeglądarki za pomocą arkusza stylów drukowania.
Drukowanie za pomocą silników renderujących w przeglądarce
Istnieją sposoby drukowania do formatu PDF za pomocą silników renderujących w przeglądarce, bez przechodzenia przez menu drukowania w przeglądarce i kończących się nagłówkami i stopkami tak, jakbyś wydrukował dokument. Najpopularniejszymi opcjami w odpowiedzi na mój tweet były wkhtmltopdf i drukowanie za pomocą bezgłowego Chrome i Puppeteer.
wkhtmltopdf
Rozwiązaniem, o którym wielokrotnie wspominano na Twitterze, jest narzędzie wiersza poleceń o nazwie wkhtmltopdf. To narzędzie pobiera plik HTML lub wiele plików wraz z arkuszem stylów i zamienia je w plik PDF. Robi to za pomocą silnika renderującego WebKit.
Używamy wkhtmltopdf. Nie jest idealny, chociaż prawdopodobnie był to błąd użytkownika, ale z łatwością wystarczająco dobry dla aplikacji produkcyjnej.
— Paul Cardno (@pcardno) 15 lutego 2019 r.
Zasadniczo zatem to narzędzie robi to samo, co drukowanie z przeglądarki, jednak nie otrzymasz automatycznie dodanych nagłówków i stopek. Z tej pozytywnej strony, jeśli masz działający arkusz stylów drukowania dla swojej treści, powinien on również ładnie wyprowadzać go do formatu PDF za pomocą tego narzędzia, a więc prosty układ może być bardzo ładnie wydrukowany.
Niestety, nadal napotkasz te same problemy, co podczas drukowania bezpośrednio z przeglądarki internetowej, jeśli chodzi o brak obsługi specyfikacji Paged Media i właściwości fragmentacji, ponieważ nadal drukujesz za pomocą silnika renderującego w przeglądarce. Istnieje kilka flag, które można przekazać do wkhtmltopdf, aby dodać niektóre brakujące funkcje, które domyślnie byłyby dostępne przy użyciu specyfikacji Paged Media. Wymaga to jednak dodatkowej pracy oprócz napisania dobrego HTML i CSS.
Bezgłowy Chrome
Inną interesującą możliwością jest użycie Headless Chrome i Puppeteer do drukowania w formacie PDF.
Lalkarz. To niesamowite.
— Alex Russell (@slightlylate) 15 lutego 2019 r.
Jednak po raz kolejny jesteś ograniczony przez obsługę przeglądarki Paged Media i fragmentację. Istnieje kilka opcji, które można przekazać do funkcji page.pdf()
. Podobnie jak wkhtmltopdf, dodają one niektóre funkcje, które byłyby możliwe z CSS, gdyby istniała obsługa przeglądarek.
Równie dobrze może być tak, że jedno z tych rozwiązań zrobi wszystko, czego potrzebujesz, jednak jeśli okaże się, że toczysz coś w rodzaju bitwy, prawdopodobnie przekraczasz granice tego, co jest możliwe z obecnymi silnikami renderującymi w przeglądarkach, i będzie musiał poszukać lepszego rozwiązania.
Wypełnienia JavaScript w mediach stronicowanych
Istnieje kilka prób, aby zasadniczo odtworzyć specyfikację Paged Media w przeglądarce za pomocą JavaScript — zasadniczo tworząc Polyfill Paged Media. Może to zapewnić wsparcie dla Paged Media podczas korzystania z programu Puppeteer. Spójrz na paged.js i Vivliostyle.
TAk. W przypadku prostych dokumentów, takich jak certyfikaty kursów, możemy użyć przeglądarki Chrome, która ma minimalną obsługę strony @. Do czegokolwiek innego używamy PrinceXML lub polyfill paged.js w Chrome. Oto potwierdzenie koncepcji WIP przy użyciu paged.js dla książek: https://t.co/AZ9fO94PT2
— Electric Book Works (@electricbook) 15 lutego 2019 r.
Korzystanie z agenta użytkownika drukowania
Jeśli chcesz pozostać przy rozwiązaniu HTML i CSS, musisz skorzystać z agenta użytkownika (UA) zaprojektowanego do drukowania z HTML i CSS, który ma interfejs API do generowania plików PDF z twoich plików. Te agenty użytkownika implementują specyfikację Paged Media i mają znacznie lepszą obsługę właściwości fragmentacji CSS; to da ci większą kontrolę nad wyjściem. Wiodące wybory obejmują:
- Książę
- Dom antenowy
- PDFReaktor
Print UA sformatuje dokumenty za pomocą CSS — tak jak robi to przeglądarka internetowa. Podobnie jak w przypadku obsługi CSS przez przeglądarkę, musisz sprawdzić dokumentację tych UA, aby dowiedzieć się, co obsługują. Na przykład Prince (który jest mi najbardziej znany) obsługuje Flexbox, ale nie CSS Grid Layout w momencie pisania tego tekstu. Wysyłając swoje strony do narzędzia, którego używasz, zazwyczaj jest to z określonym arkuszem stylów do drukowania. Podobnie jak w przypadku zwykłego arkusza stylów drukowania, nie wszystkie style CSS używane w witrynie będą odpowiednie dla wersji PDF.
Tworzenie arkusza stylów dla tych narzędzi jest bardzo podobne do tworzenia zwykłego arkusza stylów drukowania, w którym podejmuje się decyzje dotyczące tego, co wyświetlić lub ukryć, być może przy użyciu innego rozmiaru lub koloru czcionki. Będziesz wtedy mógł skorzystać z funkcji specyfikacji Paged Media, dodając przypisy, numery stron i tak dalej.
Jeśli chodzi o korzystanie z tych narzędzi z aplikacji internetowej, musisz zainstalować je na swoim serwerze (oczywiście po wykupieniu licencji). Głównym problemem z tymi narzędziami jest to, że są drogie. To powiedziawszy, biorąc pod uwagę łatwość, z jaką można następnie tworzyć za ich pomocą drukowane dokumenty, mogą one dobrze zapłacić za zaoszczędzony czas programisty.
Z Prince'a można korzystać za pośrednictwem API, na zasadzie pay per document, za pośrednictwem usługi DocRaptor. Byłoby to z pewnością dobre miejsce dla wielu aplikacji na początek, ponieważ gdyby wyglądało na to, że hostowanie własnego stanie się bardziej opłacalne, koszt opracowania zmiany byłby minimalny.
Bezpłatną alternatywą, która nie jest tak wszechstronna jak powyższe narzędzia, ale może osiągnąć pożądane rezultaty, jest WeasyPrint. Nie w pełni implementuje wszystkie Paged Media, jednak implementuje więcej niż silnik przeglądarki. Zdecydowanie jeden do wypróbowania!
Inne narzędzia, które twierdzą, że obsługują konwersję z HTML i CSS, to PDFCrowd, który śmiało twierdzi, że obsługuje HTML5, CSS3 i JavaScript. Nie mogłem jednak znaleźć żadnych szczegółów na temat tego, co było obsługiwane i czy była jakaś specyfikacja Paged Media. Również w odpowiedzi na mój tweet wzmiankę o mnie otrzymał mPDF.
Odejście od HTML i CSS
Istnieje szereg innych rozwiązań, które odchodzą od korzystania z HTML i CSS i wymagają stworzenia określonych danych wyjściowych dla narzędzia. Oto kilka konkurentów JavaScript:
- jsPDF
- pdfmake
Bezgłowa przeglądarka + zapisywanie do PDF były kiedyś moim pierwszym wyborem, ale zawsze dawały słabe wyniki dla czegokolwiek innego niż jednostronicowy dokument. Przeszliśmy na https://t.co/3o8Ce23F1t, aby uzyskać wielostronicowe raporty, które wymagały znacznie więcej wysiłku, ale w końcu były tego warte!
— JimmyJoy (@jimle_uk) 15 lutego 2019 r.
Zalecenia
Poza podejściami opartymi na JavaScript, które wymagałyby stworzenia zupełnie innej reprezentacji treści do druku, piękno wielu z tych rozwiązań polega na tym, że są one wymienne. Jeśli Twoje rozwiązanie opiera się na wywołaniu narzędzia wiersza poleceń i przekazaniu temu narzędziu kodu HTML, CSS i prawdopodobnie kodu JavaScript, przełączanie się między narzędziami jest dość proste.
W trakcie pisania tego artykułu odkryłem również wrapper Pythona, który może obsługiwać wiele różnych narzędzi. (Pamiętaj, że musisz już mieć zainstalowane same narzędzia, jednak może to być dobry sposób na przetestowanie różnych narzędzi na przykładowym dokumencie).
Jeśli chodzi o obsługę Paged Media i fragmentację, Prince, Antenna House i PDFReactor wyjdą na szczyt. Jako produkty komercyjne są również objęte wsparciem. Jeśli masz budżet, złożone strony do drukowania w formacie PDF, a Twoim ograniczeniem jest czas programisty, najprawdopodobniej uznasz, że jest to najszybsza droga do prawidłowego działania tworzenia plików PDF.
Jednak w wielu przypadkach darmowe narzędzia będą dla Ciebie dobre. Jeśli Twoje wymagania są bardzo proste, to wkhtmltopdf lub podstawowe bezgłowe rozwiązanie Chrome i Puppeteer może załatwić sprawę. Z pewnością zadziałało to dla wielu osób, które odpowiedziały na mój oryginalny tweet.
Jeśli jednak masz problemy z uzyskaniem żądanego wyniku, pamiętaj, że może to być ograniczenie drukowania przeglądarki, a nie coś, co robisz źle. Jeśli chcesz uzyskać więcej wsparcia Paged Media, ale nie jesteś w stanie skorzystać z produktu komercyjnego, spójrz na WeasyPrint.
Mam nadzieję, że jest to przydatne podsumowanie dostępnych narzędzi do tworzenia plików PDF z Twojej aplikacji internetowej. Jeśli nic więcej, to pokazuje, że istnieje wiele możliwości wyboru, jeśli twój początkowy wybór nie działa dobrze.
Dodaj swoje własne doświadczenia i sugestie w komentarzach, jest to jedna z tych rzeczy, z którymi wielu z nas ma do czynienia, a dzielenie się osobistymi doświadczeniami może być niezwykle pomocne.
Dalsza lektura
Podsumowanie różnych zasobów i narzędzi wymienionych w tym artykule, wraz z kilkoma innymi przydatnymi zasobami do pracy z plikami PDF z aplikacji internetowych.
Specyfikacje
- Moduł stronicowanych mediów
- Podział
Artykuły i zasoby
- Projektowanie do druku za pomocą CSS
- Łamanie pudełek za pomocą fragmentacji CSS
- Przewodnik po stanie arkuszy stylów druku w 2018 r.
- Pierwsze kroki z Headless Chrome i Puppeteer
- print-css.rocks
Narzędzia
- wkhtmltopdf
- paged.js
- Vivliostyle
- Książę
- Dom antenowy
- PDFReaktor
- DocRaptor
- WeasyPrint
- PDFCrowd
- mPDF
- jsPDF
- pdfmake
- Serwer produkcji i publikacji