Przetwarzanie niestandardowych plików PDF.
Wprowadzenie
Netuno generuje pliki PDF z obsługą obrazów, tabel, czcionek i wielu innych elementów poprzez zasób PDF, który zapewnia abstrakcję low-code dla iTextPDF w różnych językach programowania obsługiwanych przez Netuno.
Aplikacja dostarczana z Netuno o nazwie demo (aplikacja demonstracyjna) zawiera wiele przykładów możliwych implementacji kodu w różnych językach, w tym demonstrację eksportu do PDF poprzez usługę export-pdf, która znajduje się w:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
netuno/apps/demo/server/services/samples/javascript/export-pdf.js
netuno/apps/demo/server/services/samples/typescript/export-pdf.ts
netuno/apps/demo/server/services/samples/python/export-pdf.py
netuno/apps/demo/server/services/samples/ruby/export-pdf.rb
netuno/apps/demo/server/services/samples/kotlin/export-pdf.kts
netuno/apps/demo/server/services/samples/groovy/export-pdf.groovy
Inicjalizacja
Najpierw należy utworzyć obiekt, który będzie zawierał kontekst tworzonego nowego dokumentu; domyślnie rozmiar stron to A4.
Podczas tworzenia dokumentu określa się, gdzie zostanie wygenerowany.
Jeśli nic nie zostanie określone, zostanie wygenerowany na wyjściu danych usługi, na przykład:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.newDocument()
const dokumentPdf = _pdf.newDocument()
dokumentPdf = _pdf.newDocument()
dokumentPdf = _pdf.newDocument()
val dokumentPdf = _pdf.newDocument()
def dokumentPdf = _pdf.newDocument()
Aby wygenerować plik PDF w folderze docs aplikacji, można to zrobić tak:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.newDocument(_app.file("docs/plik.pdf").output())
const dokumentPdf = _pdf.newDocument(_app.file("docs/plik.pdf").output())
dokumentPdf = _pdf.newDocument(_app.file("docs/plik.pdf").output())
dokumentPdf = _pdf.newDocument(_app.file("docs/plik.pdf").output())
val dokumentPdf = _pdf.newDocument(_app.file("docs/plik.pdf").output())
def dokumentPdf = _pdf.newDocument(_app.file("docs/plik.pdf").output())
Jeśli dokument ma zostać wygenerowany w nowym pliku poza aplikacją, na przykład:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.newDocument(_os.file("/tmp/plik.pdf").output())
const dokumentPdf = _pdf.newDocument(_os.file("/tmp/plik.pdf").output())
dokumentPdf = _pdf.newDocument(_os.file("/tmp/plik.pdf").output())
dokumentPdf = _pdf.newDocument(_os.file("/tmp/plik.pdf").output())
val dokumentPdf = _pdf.newDocument(_os.file("/tmp/plik.pdf").output())
def dokumentPdf = _pdf.newDocument(_os.file("/tmp/plik.pdf").output())
Lub jeszcze w storage aplikacji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output())
const dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output())
dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output())
dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output())
val dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output())
def dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output())
Domyślnie dokument jest tworzony z formatem strony A4.
Format strony
Aby dostosować format strony, wystarczy wskazać go podczas tworzenia dokumentu.
Tworzy nowy dokument na wyjście danych usługi ze stronami w formacie letter:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.newDocument(_pdf.pageSize("letter"))
const dokumentPdf = _pdf.newDocument(_pdf.pageSize("letter"))
dokumentPdf = _pdf.newDocument(_pdf.pageSize("letter"))
dokumentPdf = _pdf.newDocument(_pdf.pageSize("letter"))
val dokumentPdf = _pdf.newDocument(_pdf.pageSize("letter"))
def dokumentPdf = _pdf.newDocument(_pdf.pageSize("letter"))
Tworzy nowy dokument dla pliku w katalogu głównym aplikacji w formacie strony B3:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.newDocument(_app.file("plik.pdf").output(), _pdf.pageSize("B3"))
const dokumentPdf = _pdf.newDocument(_app.file("plik.pdf").output(), _pdf.pageSize("B3"))
dokumentPdf = _pdf.newDocument(_app.file("plik.pdf").output(), _pdf.pageSize("B3"))
dokumentPdf = _pdf.newDocument(_app.file("plik.pdf").output(), _pdf.pageSize("B3"))
val dokumentPdf = _pdf.newDocument(_app.file("plik.pdf").output(), _pdf.pageSize("B3"))
def dokumentPdf = _pdf.newDocument(_app.file("plik.pdf").output(), _pdf.pageSize("B3"))
Tworzy nowy dokument w storage aplikacji w formacie strony legal:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output(), _pdf.pageSize("legal"))
const dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output(), _pdf.pageSize("legal"))
dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output(), _pdf.pageSize("legal"))
dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output(), _pdf.pageSize("legal"))
val dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output(), _pdf.pageSize("legal"))
def dokumentPdf = _pdf.newDocument(_storage.filesystem("server", "plik.pdf").output(), _pdf.pageSize("legal"))
Zobacz dokumentację dotyczącą definiowania rozmiaru stron.
Dokumenty PDF można tworzyć z niestandardowym rozmiarem strony; w tym celu użyj pageSize, przekazując wartość szerokości i wysokości strony, na przykład:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
Nagłówek HTTP
Aby utworzyć usługę w API REST, która zwraca plik PDF jako wyjście danych, należy dodać w nagłówku parametr Content-Type protokołu HTTP.
Przykład określenia zawartości jako PDF:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_header.contentType("pdf")
_header.contentType("pdf")
_header.contentType("pdf")
_header.contentType("pdf")
_header.contentType("pdf")
_header.contentType("pdf")
Kod pdf jest skrótem dla:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_header.contentType("application/pdf")
_header.contentType("application/pdf")
_header.contentType("application/pdf")
_header.contentType("application/pdf")
_header.contentType("application/pdf")
_header.contentType("application/pdf")
Podział strony
Aby utworzyć nową stronę, używane jest areaBreak:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
dokumentPdf.add(
_pdf.areaBreak()
)
dokumentPdf.add(
_pdf.areaBreak()
)
dokumentPdf.add(
_pdf.areaBreak()
)
dokumentPdf.add(
_pdf.areaBreak()
)
dokumentPdf.add(
_pdf.areaBreak()
)
dokumentPdf.add(
_pdf.areaBreak()
)
Akapit
Dodaje nowy akapit do dokumentu:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
dokumentPdf.add(
_pdf.paragraph("Mój tekst tutaj...")
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Mój tekst tutaj...")
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Mój tekst tutaj...")
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Mój tekst tutaj...")
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Mój tekst tutaj...")
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Mój tekst tutaj...")
.setFontSize(15)
)
Aby dodać akapit w stałej pozycji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
dokumentPdf.add(
dokumentPdf.add(
_pdf.paragraph("Mój stały tekst...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
dokumentPdf.add(
dokumentPdf.add(
_pdf.paragraph("Mój stały tekst...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
dokumentPdf.add(
dokumentPdf.add(
_pdf.paragraph("Mój stały tekst...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
dokumentPdf.add(
dokumentPdf.add(
_pdf.paragraph("Mój stały tekst...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
dokumentPdf.add(
dokumentPdf.add(
_pdf.paragraph("Mój stały tekst...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
dokumentPdf.add(
dokumentPdf.add(
_pdf.paragraph("Mój stały tekst...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
W powyższym kodzie, w metodzie setFixedPosition, pierwszy parametr to pozycja X (100), drugi parametr to pozycja Y (500), a trzeci parametr to szerokość (200).
Uwaga: jeśli Y zostanie ustawione na wartość 0, oznacza to, że znajduje się na dole strony; aby przejść wyżej, należy zwiększyć wartość Y. Im większa wartość Y, tym wyżej element się pojawi, ale jeśli będzie zbyt wysoka względem długości strony, nie będzie widoczny.
Dokumentacja ze wszystkimi metodami obiektu akapitu iText.
Czcionka
Aby zdefiniować czcionkę natywną, możemy to zrobić w następujący sposób:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const helvetica = _pdf.font("helvetica")
const helveticaBold = _pdf.font("helvetica-bold")
const helveticaBoldOblique = _pdf.font("helvetica-boldoblique")
const helveticaOblique = _pdf.font("helvetica-oblique")
const helvetica = _pdf.font("helvetica")
const helveticaBold = _pdf.font("helvetica-bold")
const helveticaBoldOblique = _pdf.font("helvetica-boldoblique")
const helveticaOblique = _pdf.font("helvetica-oblique")
helvetica = _pdf.font("helvetica")
helveticaBold = _pdf.font("helvetica-bold")
helveticaBoldOblique = _pdf.font("helvetica-boldoblique")
helveticaOblique = _pdf.font("helvetica-oblique")
helvetica = _pdf.font("helvetica")
helveticaBold = _pdf.font("helvetica-bold")
helveticaBoldOblique = _pdf.font("helvetica-boldoblique")
helveticaOblique = _pdf.font("helvetica-oblique")
val helvetica = _pdf.font("helvetica")
val helveticaBold = _pdf.font("helvetica-bold")
val helveticaBoldOblique = _pdf.font("helvetica-boldoblique")
val helveticaOblique = _pdf.font("helvetica-oblique")
def helvetica = _pdf.font("helvetica")
def helveticaBold = _pdf.font("helvetica-bold")
def helveticaBoldOblique = _pdf.font("helvetica-boldoblique")
def helveticaOblique = _pdf.font("helvetica-oblique")
Aby zdefiniować czcionkę niestandardową, możemy użyć storage:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
const viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
val viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
def viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
Możemy również użyć pliku w aplikacji; ten przykład pokazuje, że czcionka znajduje się w folderze fonts w katalogu głównym aplikacji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
const roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
val roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
def roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
Można też użyć pliku w dowolnej ścieżce systemowej; w tym przykładzie czcionka znajduje się w folderze fonts wewnątrz systemowego folderu plików tymczasowych:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
const roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
val roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
def roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
Dokumentacja ze wszystkimi metodami obiektu czcionki iText.
Aby użyć czcionki w tekstach, należy przekazać stałą czcionki do akapitu w następujący sposób:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
dokumentPdf.add(
_pdf.paragraph("Używanie pogrubionej czcionki.")
.setFont(helveticaBold)
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Używanie pogrubionej czcionki.")
.setFont(helveticaBold)
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Używanie pogrubionej czcionki.")
.setFont(helveticaBold)
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Używanie pogrubionej czcionki.")
.setFont(helveticaBold)
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Używanie pogrubionej czcionki.")
.setFont(helveticaBold)
.setFontSize(15)
)
dokumentPdf.add(
_pdf.paragraph("Używanie pogrubionej czcionki.")
.setFont(helveticaBold)
.setFontSize(15)
)
Obraz
Wstawianie obrazów do programowo generowanego dokumentu PDF odbywa się w następujący sposób:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
dokumentPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
dokumentPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
dokumentPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
dokumentPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
dokumentPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
dokumentPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
Zauważ, że metoda scaleAbsolute jest bardzo przydatna do zmiany rozmiaru i dopasowania obrazu.
Alternatywnie możemy użyć pliku w aplikacji, jak w tym przykładzie:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const obrazLogo = _pdf.image(_app.file("public/images/logo.png")
const obrazLogo = _pdf.image(_app.file("public/images/logo.png")
obrazLogo = _pdf.image(_app.file("public/images/logo.png")
obrazLogo = _pdf.image(_app.file("public/images/logo.png")
val obrazLogo = _pdf.image(_app.file("public/images/logo.png")
def obrazLogo = _pdf.image(_app.file("public/images/logo.png")
Można też użyć pliku w dowolnej ścieżce systemowej, jak w tym przykładzie:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const obrazLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
const obrazLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
obrazLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
obrazLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
val obrazLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
def obrazLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
Aby dodać obraz w stałej pozycji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
dokumentPdf.add(
obrazLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
dokumentPdf.add(
obrazLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
dokumentPdf.add(
obrazLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
dokumentPdf.add(
obrazLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
dokumentPdf.add(
obrazLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
dokumentPdf.add(
obrazLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
Przy czym powyżej, w metodzie setFixedPosition, pierwszy parametr to pozycja X (100), a drugi parametr to pozycja Y (500).
Uwaga: jeśli Y zostanie ustawione na wartość 0, oznacza to, że znajduje się na dole strony; aby przejść wyżej, należy zwiększyć wartość Y. Im większa wartość Y, tym wyżej element się pojawi, ale jeśli będzie zbyt wysoka względem długości strony, nie będzie widoczny.
Dokumentacja ze wszystkimi metodami obiektu obrazu iText.
Tabela
Można tworzyć tabele, co pozwala przedstawić zestaw danych w bardziej czytelny sposób.
Liczbę kolumn tabeli definiuje się parametrem: _pdf.table(liczbaKolumn)
W poniższym przykładzie liczbaKolumn to liczba 1, czyli jedna kolumna.
Ponieważ dodajemy dwie komórki do tabeli, druga komórka przejdzie do następnego wiersza.
Zauważ:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
dokumentPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Osoba")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nikola")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
dokumentPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Osoba")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nikola")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
dokumentPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Osoba")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nikola")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
dokumentPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Osoba")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nikola")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
dokumentPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Osoba")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nikola")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
dokumentPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Osoba")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nikola")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
Metoda addCell pozwala wstawić definicję komórek wraz z ich odpowiednią zawartością.
Dokumentacja ze wszystkimi metodami obiektu komórki iText.
Zamykanie i zapisywanie dokumentu
Dokument jest w pełni zapisywany lub generowany dopiero po wywołaniu metody close, w następujący sposób:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
dokumentPdf.close()
dokumentPdf.close()
dokumentPdf.close()
dokumentPdf.close()
dokumentPdf.close()
dokumentPdf.close()
Miejsce generowania dokumentu jest określane podczas inicjalizacji; to właśnie przy inicjalizacji dokumentu definiujemy, gdzie zostanie wygenerowany dokument końcowy — na wyjściu danych usługi (output) czy w pliku.
Edytowanie pliku
Można edytować istniejący dokument PDF, na przykład:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.openDocument(_app.file("plik.pdf"))
const dokumentPdf = _pdf.openDocument(_app.file("plik.pdf"))
dokumentPdf = _pdf.openDocument(_app.file("plik.pdf"))
dokumentPdf = _pdf.openDocument(_app.file("plik.pdf"))
val dokumentPdf = _pdf.openDocument(_app.file("plik.pdf"))
def dokumentPdf = _pdf.openDocument(_app.file("plik.pdf"))
Wygenerowany dokument końcowy zostanie wysłany na wyjście danych usługi.
Jest to bardzo przydatne, aby użyć PDF jako bazy, jakby był szablonem.
Przykład edycji dokumentu w storage aplikacji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.openDocument(_storage.filesystem('server', 'plik.pdf'))
const dokumentPdf = _pdf.openDocument(_storage.filesystem('server', 'plik.pdf'))
dokumentPdf = _pdf.openDocument(_storage.filesystem('server', 'plik.pdf'))
dokumentPdf = _pdf.openDocument(_storage.filesystem('server', 'plik.pdf'))
val dokumentPdf = _pdf.openDocument(_storage.filesystem('server', 'plik.pdf'))
def dokumentPdf = _pdf.openDocument(_storage.filesystem('server', 'plik.pdf'))
Używa dokumentu jako bazy, ale zapisuje zmiany w nowym pliku PDF:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.openDocument(
_app.file("dokument-bazowy.pdf"),
_app.file("dokument-finalny.pdf")
)
const dokumentPdf = _pdf.openDocument(
_app.file("dokument-bazowy.pdf"),
_app.file("dokument-finalny.pdf")
)
dokumentPdf = _pdf.openDocument(
_app.file("dokument-bazowy.pdf"),
_app.file("dokument-finalny.pdf")
)
dokumentPdf = _pdf.openDocument(
_app.file("dokument-bazowy.pdf"),
_app.file("dokument-finalny.pdf")
)
val dokumentPdf = _pdf.openDocument(
_app.file("dokument-bazowy.pdf"),
_app.file("dokument-finalny.pdf")
)
def dokumentPdf = _pdf.openDocument(
_app.file("dokument-bazowy.pdf"),
_app.file("dokument-finalny.pdf")
)
Przykład użycia jako bazy dokumentu w storage, ale zapisania w innym:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const dokumentPdf = _pdf.openDocument(
_storage.filesystem("server", "umowa-bazowa.pdf"),
_storage.filesystem("server", "umowa-finalna.pdf")
)
const dokumentPdf = _pdf.openDocument(
_storage.filesystem("server", "umowa-bazowa.pdf"),
_storage.filesystem("server", "umowa-finalna.pdf")
)
dokumentPdf = _pdf.openDocument(
_storage.filesystem("server", "umowa-bazowa.pdf"),
_storage.filesystem("server", "umowa-finalna.pdf")
)
dokumentPdf = _pdf.openDocument(
_storage.filesystem("server", "umowa-bazowa.pdf"),
_storage.filesystem("server", "umowa-finalna.pdf")
)
val dokumentPdf = _pdf.openDocument(
_storage.filesystem("server", "umowa-bazowa.pdf"),
_storage.filesystem("server", "umowa-finalna.pdf")
)
def dokumentPdf = _pdf.openDocument(
_storage.filesystem("server", "umowa-bazowa.pdf"),
_storage.filesystem("server", "umowa-finalna.pdf")
)
Po załadowaniu dokumentu możemy dodawać treści, a po zamknięciu metodą close na końcu generowany jest dokument końcowy z nową treścią dodaną programowo.
Przykład usługi, która używa istniejącego PDF jako szablonu do wygenerowania pliku PDF z dodaną dynamiczną treścią:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_header.contentType("pdf")
const dokumentPdf = _pdf.openDocument(_app.file("szablon-1.pdf"))
dokumentPdf.add(
_pdf.paragraph("Moja dynamiczna treść.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
dokumentPdf.close()
_header.contentType("pdf")
const dokumentPdf = _pdf.openDocument(_app.file("szablon-1.pdf"))
dokumentPdf.add(
_pdf.paragraph("Moja dynamiczna treść.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
dokumentPdf.close()
_header.contentType("pdf")
dokumentPdf = _pdf.openDocument(_app.file("szablon-1.pdf"))
dokumentPdf.add(
_pdf.paragraph("Moja dynamiczna treść.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
dokumentPdf.close()
_header.contentType("pdf")
dokumentPdf = _pdf.openDocument(_app.file("szablon-1.pdf"))
dokumentPdf.add(
_pdf.paragraph("Moja dynamiczna treść.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
dokumentPdf.close()
_header.contentType("pdf")
val dokumentPdf = _pdf.openDocument(_app.file("szablon-1.pdf"))
dokumentPdf.add(
_pdf.paragraph("Moja dynamiczna treść.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
dokumentPdf.close()
_header.contentType("pdf")
def dokumentPdf = _pdf.openDocument(_app.file("szablon-1.pdf"))
dokumentPdf.add(
_pdf.paragraph("Moja dynamiczna treść.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
dokumentPdf.close()
Odczyt pliku
Aby odczytać dokument PDF, wyodrębniając informacje tekstowe.
Używamy metody extract, która pobiera wszystkie dane pliku PDF do obiektu JSON.
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const danePdf = _pdf.extract(_app.file("plik-1.pdf"))
_out.json(danePdf)
const danePdf = _pdf.extract(_app.file("plik-1.pdf"))
_out.json(danePdf)
danePdf = _pdf.extract(_app.file("plik-1.pdf"))
_out.json(danePdf)
danePdf = _pdf.extract(_app.file("plik-1.pdf"))
_out.json(danePdf)
val danePdf = _pdf.extract(_app.file("plik-1.pdf"))
_out.json(danePdf)
def danePdf = _pdf.extract(_app.file("plik-1.pdf"))
_out.json(danePdf)
Zwrócony JSON ma klucz content zawierający całą treść tekstową pliku PDF oraz klucz metadata z różnymi właściwościami pliku PDF.
Oto przykład JSON zwróconego przez extract:
{
"content": "Cała treść tekstowa pliku PDF znajduje się tutaj...",
"metadata":{
"Content-Type":"application/pdf",
"dc:format":"application/pdf; version=1.4",
"dc:title":"Linux 1",
"pdf:PDFVersion":"1.4",
"pdf:charsPerPage":"580",
"pdf:containsDamagedFont":"false",
"pdf:containsNonEmbeddedFont":"false",
"pdf:docinfo:producer":"Skia/PDF m125 Google Docs Renderer",
"pdf:docinfo:title":"Plik 1",
"pdf:encrypted":"false",
"xmpTPg:NPages":"3",
...
}
}
Istnieje wiele innych danych uzyskiwanych w metadata, ale zostały pominięte w ..., aby przykład nie był zbyt długi.
Konwersja
Można programowo konwertować PDF na tekst, a nawet na HTML.
PDF na tekst
Możemy wyodrębnić całą zawartość pliku PDF jako ciągły tekst za pomocą metody:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_pdf.toText(...)
_pdf.toText(...)
_pdf.toText(...)
_pdf.toText(...)
_pdf.toText(...)
_pdf.toText(...)
Przykład użycia do odczytania pliku w katalogu głównym aplikacji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_out.print(_pdf.toText(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toText(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toText(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toText(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toText(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toText(_app.file("moj-dokument.pdf")))
Lub jeszcze przy użyciu pliku w storage aplikacji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_out.print(_pdf.toText(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "moj-dokument.pdf")))
PDF na HTML
Możemy wyodrębnić całą zawartość pliku PDF jako HTML za pomocą metody:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_pdf.toHTML(...)
_pdf.toHTML(...)
_pdf.toHTML(...)
_pdf.toHTML(...)
_pdf.toHTML(...)
_pdf.toHTML(...)
Przykład użycia do odczytania pliku w katalogu głównym aplikacji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_out.print(_pdf.toHTML(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toHTML(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toHTML(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toHTML(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toHTML(_app.file("moj-dokument.pdf")))
_out.print(_pdf.toHTML(_app.file("moj-dokument.pdf")))
Lub jeszcze przy użyciu pliku w storage aplikacji:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_out.print(_pdf.toHTML(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "moj-dokument.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "moj-dokument.pdf")))
HTML na PDF
Można generować pliki PDF z kodu HTML za pomocą metody:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_pdf.fromHTML(...)
_pdf.fromHTML(...)
_pdf.fromHTML(...)
_pdf.fromHTML(...)
_pdf.fromHTML(...)
_pdf.fromHTML(...)
Przykład użycia do wygenerowania pliku do pobrania w usłudze:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const ikona = _app.file("public/images/icon.png");
const plikPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto;
}
div.sidebar {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 100px;
background: #1B5886;
}
div.sidebar > div {
position: absolute;
top: 350px;
transform: rotate(-90deg) translate(-50%, -34px);
font-family: Limelight;
font-size: 40px;
color: #89CFF1;
}
main {
padding-left: 150px;
}
h1 {
margin: 0 auto;
text-align: center;
font-family: Limelight;
color: #BA250E;
}
table {
margin: 0 auto;
border: 1px solid black;
border-spacing: 0;
border-collapse: collapse;
}
table > thead {
background: #40712A;
color: #fff;
}
table td, table th {
padding: 5px;
text-align: center;
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1;
}
a {
font-family: Limelight;
font-size: 16px;
font-weight: bold;
text-decoration: none;
color: #1E5FB5;
}
</style>
</head>
<body>
<div class="sidebar">
<div>Demonstracja</div>
</div>
<main>
<h1>PDF z HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
To jest przykładowy HTML do wygenerowania pliku PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Imię</th>
<th>Wiek</th>
</tr>
</thread>
<tbody>
<tr>
<td>Maria Luiza</td>
<td>23</td>
</tr>
<tr>
<td>Józef Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`);
_header.contentTypePDF();
_out.copy(plikPdf.input());
const ikona = _app.file("public/images/icon.png");
const plikPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto;
}
div.sidebar {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 100px;
background: #1B5886;
}
div.sidebar > div {
position: absolute;
top: 350px;
transform: rotate(-90deg) translate(-50%, -34px);
font-family: Limelight;
font-size: 40px;
color: #89CFF1;
}
main {
padding-left: 150px;
}
h1 {
margin: 0 auto;
text-align: center;
font-family: Limelight;
color: #BA250E;
}
table {
margin: 0 auto;
border: 1px solid black;
border-spacing: 0;
border-collapse: collapse;
}
table > thead {
background: #40712A;
color: #fff;
}
table td, table th {
padding: 5px;
text-align: center;
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1;
}
a {
font-family: Limelight;
font-size: 16px;
font-weight: bold;
text-decoration: none;
color: #1E5FB5;
}
</style>
</head>
<body>
<div class="sidebar">
<div>Demonstracja</div>
</div>
<main>
<h1>PDF z HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
To jest przykładowy HTML do wygenerowania pliku PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Imię</th>
<th>Wiek</th>
</tr>
</thread>
<tbody>
<tr>
<td>Maria Luiza</td>
<td>23</td>
</tr>
<tr>
<td>Józef Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`);
_header.contentTypePDF();
_out.copy(plikPdf.input());
ikona = _app.file("public/images/icon.png")
plikPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto
}
div.sidebar {
position: fixed
top: 0
bottom: 0
left: 0
width: 100px
background: #1B5886
}
div.sidebar > div {
position: absolute
top: 350px
transform: rotate(-90deg) translate(-50%, -34px)
font-family: Limelight
font-size: 40px
color: #89CFF1
}
main {
padding-left: 150px
}
h1 {
margin: 0 auto
text-align: center
font-family: Limelight
color: #BA250E
}
table {
margin: 0 auto
border: 1px solid black
border-spacing: 0
border-collapse: collapse
}
table > thead {
background: #40712A
color: #fff
}
table td, table th {
padding: 5px
text-align: center
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1
}
a {
font-family: Limelight
font-size: 16px
font-weight: bold
text-decoration: none
color: #1E5FB5
}
</style>
</head>
<body>
<div class="sidebar">
<div>Demonstracja</div>
</div>
<main>
<h1>PDF z HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
To jest przykładowy HTML do wygenerowania pliku PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Imię</th>
<th>Wiek</th>
</tr>
</thread>
<tbody>
<tr>
<td>Maria Luiza</td>
<td>23</td>
</tr>
<tr>
<td>Józef Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`)
_header.contentTypePDF()
_out.copy(plikPdf.input())
ikona = _app.file("public/images/icon.png")
plikPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto
}
div.sidebar {
position: fixed
top: 0
bottom: 0
left: 0
width: 100px
background: #1B5886
}
div.sidebar > div {
position: absolute
top: 350px
transform: rotate(-90deg) translate(-50%, -34px)
font-family: Limelight
font-size: 40px
color: #89CFF1
}
main {
padding-left: 150px
}
h1 {
margin: 0 auto
text-align: center
font-family: Limelight
color: #BA250E
}
table {
margin: 0 auto
border: 1px solid black
border-spacing: 0
border-collapse: collapse
}
table > thead {
background: #40712A
color: #fff
}
table td, table th {
padding: 5px
text-align: center
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1
}
a {
font-family: Limelight
font-size: 16px
font-weight: bold
text-decoration: none
color: #1E5FB5
}
</style>
</head>
<body>
<div class="sidebar">
<div>Demonstracja</div>
</div>
<main>
<h1>PDF z HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
To jest przykładowy HTML do wygenerowania pliku PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Imię</th>
<th>Wiek</th>
</tr>
</thread>
<tbody>
<tr>
<td>Maria Luiza</td>
<td>23</td>
</tr>
<tr>
<td>Józef Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`)
_header.contentTypePDF()
_out.copy(plikPdf.input())
val ikona = _app.file("public/images/icon.png")
val plikPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto
}
div.sidebar {
position: fixed
top: 0
bottom: 0
left: 0
width: 100px
background: #1B5886
}
div.sidebar > div {
position: absolute
top: 350px
transform: rotate(-90deg) translate(-50%, -34px)
font-family: Limelight
font-size: 40px
color: #89CFF1
}
main {
padding-left: 150px
}
h1 {
margin: 0 auto
text-align: center
font-family: Limelight
color: #BA250E
}
table {
margin: 0 auto
border: 1px solid black
border-spacing: 0
border-collapse: collapse
}
table > thead {
background: #40712A
color: #fff
}
table td, table th {
padding: 5px
text-align: center
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1
}
a {
font-family: Limelight
font-size: 16px
font-weight: bold
text-decoration: none
color: #1E5FB5
}
</style>
</head>
<body>
<div class="sidebar">
<div>Demonstracja</div>
</div>
<main>
<h1>PDF z HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
To jest przykładowy HTML do wygenerowania pliku PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Imię</th>
<th>Wiek</th>
</tr>
</thread>
<tbody>
<tr>
<td>Maria Luiza</td>
<td>23</td>
</tr>
<tr>
<td>Józef Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`)
_header.contentTypePDF()
_out.copy(plikPdf.input())
final ikona = _app.file("public/images/icon.png")
final plikPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto
}
div.sidebar {
position: fixed
top: 0
bottom: 0
left: 0
width: 100px
background: #1B5886
}
div.sidebar > div {
position: absolute
top: 350px
transform: rotate(-90deg) translate(-50%, -34px)
font-family: Limelight
font-size: 40px
color: #89CFF1
}
main {
padding-left: 150px
}
h1 {
margin: 0 auto
text-align: center
font-family: Limelight
color: #BA250E
}
table {
margin: 0 auto
border: 1px solid black
border-spacing: 0
border-collapse: collapse
}
table > thead {
background: #40712A
color: #fff
}
table td, table th {
padding: 5px
text-align: center
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1
}
a {
font-family: Limelight
font-size: 16px
font-weight: bold
text-decoration: none
color: #1E5FB5
}
</style>
</head>
<body>
<div class="sidebar">
<div>Demonstracja</div>
</div>
<main>
<h1>PDF z HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
To jest przykładowy HTML do wygenerowania pliku PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Imię</th>
<th>Wiek</th>
</tr>
</thread>
<tbody>
<tr>
<td>Maria Luiza</td>
<td>23</td>
</tr>
<tr>
<td>Józef Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`)
_header.contentTypePDF()
_out.copy(plikPdf.input())
Filmy
Poniżej znajdują się przykładowe filmy pokazujące, jak programowo generować pliki PDF: