→ Php генерация pdf из html. Сравнение способов генерации pdf из html

Php генерация pdf из html. Сравнение способов генерации pdf из html

PDF (portable document format) - это популярный формат документов, который не зависит от операционной системы или железа. Очевидно, его можно использовать для генерации отчетов, дипломов, чеков в приложениях, а так же для редактирования документов. Для этих целей лучше всего подойдет java-библиотека iText . Кстати, библиотека доступна так же и для C#.

В статье мы рассмотрим следующие вопросы:

  • Генерация нового PDF документа на примере чека.
  • Заполнение шаблона PDF документа.
  • Краткий обзор некоторых классов и методов библиотеки iText.

Для нетерпеливых сразу же привожу java код, который создает pdf-шаблон чека, а потом заполняет его данными из объекта Receipt. Не забудьте скачать jar-файл библиотеки и положить его на classpath.

Import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import java.io.FileInputStream; import java.io.FileOutputStream; import java.net.URL; import java.text.NumberFormat; import java.util.Date; public class PdfGeneration { static int FONT_SIZE_SMALL = 16; static int FONT_SIZE_BIG = 32; static int OFFSET = 40; public static void main(String args) throws Exception { createTemplate(); Receipt receipt = new Receipt("This is a veeeeeeeeeeeeeeeeeeeeee" + "eeeeeeeeeeeeeeeeeeeeery long purpose " + "text, so it will overflow with font size = 16", 123.45, "Name Surname"); fillInReceipt(receipt); } public static void createTemplate() throws Exception { Document document = new Document(); Font font1 = new Font(Font.FontFamily.HELVETICA, FONT_SIZE_BIG, Font.BOLD); Font font2 = new Font(Font.FontFamily.HELVETICA, FONT_SIZE_SMALL, Font.ITALIC | Font.UNDERLINE); PdfWriter.getInstance(document, new FileOutputStream("template.pdf")); document.open(); // отцентрированный параграф Paragraph title = new Paragraph("Receipt", font1); title.setAlignment(Element.ALIGN_CENTER); title.setSpacingAfter(FONT_SIZE_BIG); document.add(title); // параграф с текстом Paragraph purpose = new Paragraph("Purpose", font2); purpose.setSpacingAfter(FONT_SIZE_BIG); document.add(purpose); // параграф с добавленным чанком текста Paragraph amount = new Paragraph(); amount.setFont(font2); amount.setSpacingAfter(8); amount.add(new Chunk("Amount")); document.add(amount); // параграф с фразой, в которую добавлен чанк Paragraph date = new Paragraph(); date.setFont(font2); Phrase phrase = new Phrase(); phrase.add(new Chunk("Date")); date.add(phrase); document.add(date); document.add(new Paragraph("Name", font2)); Paragraph footer = new Paragraph("Important - please retain for your records - "); // ссылка Anchor anchor = new Anchor("Javenue"); anchor.setReference("http://www..add(anchor); footer.setAlignment(Element.ALIGN_CENTER); footer.setSpacingBefore(FONT_SIZE_BIG); document.add(footer); // картинка, загруженная по URL String imageUrl = "http://www..png"; // Image.getInstance("sample.png") Image stamp = Image.getInstance(new URL(imageUrl)); stamp.setAlignment(Element.ALIGN_RIGHT); document.add(stamp); document.close(); } public static void fillInReceipt(Receipt receipt) throws Exception { PdfReader reader = new PdfReader(new FileInputStream("template.pdf")); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("receipt.pdf")); PdfContentByte stream = stamper.getOverContent(1); stream.beginText(); stream.setColorFill(BaseColor.BLUE); BaseFont font = BaseFont.createFont(); float pageWidth = reader.getPageSize(1).getWidth(); stream.setFontAndSize(font, FONT_SIZE_SMALL); float v = stream.getEffectiveStringWidth(receipt.getPurpose(), false); float fitSize = (pageWidth-OFFSET*2) * FONT_SIZE_SMALL/v; stream.setFontAndSize(font, fitSize); stream.setTextMatrix(OFFSET, 680); stream.showText(receipt.getPurpose()); stream.setFontAndSize(font, FONT_SIZE_SMALL); String amount = NumberFormat.getCurrencyInstance() .format(receipt.getAmount()); v = stream.getEffectiveStringWidth(amount, false); stream.setTextMatrix(pageWidth - v - OFFSET, 655); stream.showText(amount); v = stream.getEffectiveStringWidth(receipt.getDate() + "", false); stream.setTextMatrix(pageWidth - v - OFFSET, 630); stream.showText(receipt.getDate() + ""); v = stream.getEffectiveStringWidth(receipt.getName(), false); stream.setTextMatrix(pageWidth - v - OFFSET, 605); stream.showText(receipt.getName()); stream.endText(); stamper.setFullCompression(); stamper.close(); } static class Receipt { private String purpose; private double amount; private Date date = new Date(); private String name; public Receipt(String purpose, double amount, String name) { this.purpose = purpose; this.amount = amount; this.name = name; } public String getPurpose() { return purpose;} public void setPurpose(String purpose) { this.purpose = purpose; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }

Для начала необходимо создать экземпляр com.itextpdf.text.Document и с помощью PDFWriter связать его с файлом на файловой системе. Создать шрифт можно с помощью класса Font, указывая размер шрифта, его семейство и стиль.

Основные объекты, с которыми вы будете работать, это Phrase, Paragraph, возможно Anchor и самый маленький кусок текста - Chunk. Обратите внимание, что для каждого параграфа вы можете задать свой шрифт и далее добавлять в параграф объекты Chunk, Phrase, Anchor.

C помощью следующего кода можно добавить картинку в PDF документ:

String imageUrl = "http://site.com/image.png"; Image stamp = Image.getInstance(new URL(imageUrl)); stamp.setAlignment(Element.ALIGN_RIGHT); document.add(stamp);

Не забудьте вызвать document.close() после добавления всех объектов. Это необходимо для того, чтобы корректно закрыть PDFWriter.

Писать поверх существующего PDF документа можно через PdfContentByte. Немного придется помучиться с расположением текста на чеке, но кто говорил, что будет легко. Думаю, код метода fillInReceipt понятен и не требует дополнительных объяснений.

А вот еще классы из iText API, которые могут вам пригодиться:

  • List и ListItem - это список и элемент списка, который может быть добавлен как list.add(new ListItem("item")). Списки как и в HTML могут быть упорядоченные и неупорядоченные.
  • Chapter и Section - раздел и соответственно его секция. Секции можно добавлять с помощью вызова chapter.addSection
  • Более сложный объект PdfPTable, состоящий из ячеек PdfPCell. Можно делать достаточно красивые таблички, но как по мне API не самый удобный.

Вот и все. Если есть вопросы - обращайтесь: всегда рад помочь.

Для того, чтобы генерировать PDF файл из HTML, мы будем использовать библиотеку DomPDF для PHP. И вместе с ней мы сможем получить качественно сгенерированные PDF файлы с русскими символами.

Итак, приступим. Для начала необходимо скачать саму библиотеку по адресу:

Или установить её через composer:

Composer require dompdf/dompdf

Однако, стоит отметить, что стандартная сборка НЕ поддерживает русскоязычные символы. Поэтому, приходится долго копать интернет и пробовать, пробовать, пробовать. Чтобы сократить Ваше время, мы уже собрали все. Ниже, Вы сможете скачать библиотеку с поддержкой русскоязычных символов.

Если Вы хотите использовать стандартную сборку, то просто замените файлы из данного архива (916 KB) .

Вам необходимо будет заменить файлы в папке:

../dompdf/lib/fonts

С данным скриптом Вы сможете формировать сложные PDF файлы с таблицами, изображениями, которые из HTML встроятся в PDF файл.

Мы используем эту библиотеку для генерации PDF при ajax запросе. В скачанном архиве Вы найдете файл index.php, который обрабатывает приходящие данные, подключает шаблон, в который уже встроены изображения. Мы выгрузили для Вас полностью рабочий и используемый нами вариант (5 MB) .

Скачать пример сгенерированного PDF файла (580 KB)

Если Вы скачали библиотеку, то подключите к Вашему PHP файлу её с помощью подключения автозагрузчика:

Require_once "dompdf/autoload.inc.php";

Или используйте GIT:

Git clone https://github.com/dompdf/dompdf.git
cd dompdf
git clone https://github.com/PhenX/php-font-lib.git lib/php-font-lib
cd lib/php-font-lib
git checkout 0.5.1
cd ..
git clone https://github.com/PhenX/php-svg-lib.git php-svg-lib
cd php-svg-lib
git checkout v0.3

Сам обработчик выглядит так:

//подключаем автозагрузчик include_once "autoload.inc.php"; //функция очистки кода от вредоносных данных function challsrt($data){ $array1=array("\"","*","%","0x","&","\0","\n","\r","\s","\t","\\","`","^","$","{","}","[","]","(",")","wss","blob","localhost","–","

 

 

Это интересно: