Java → Работа с PDF в Java

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

- Генерация нового 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.javenue.info");
footer.add(anchor);

footer.setAlignment(Element.ALIGN_CENTER);
footer.setSpacingBefore(FONT_SIZE_BIG);
document.add(footer);

// картинка, загруженная по URL
String imageUrl = "http://www.javenue.info/files/sample.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-OFFSET2) 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.

Ссылки Anchor могут быть открыты при просмотре PDF документа, если в вашей операционной системе файлы .pdf связаны с программой для их просмотра.

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

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


Кроме загрузки по URL можно считать картинку с файловой системы, например: Image stamp = Image.getInstance("sample.png").

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

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

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

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

Дополнительно:
В NetBeans можно подключить Itext библиотеку с помощью Maven Repositories.
Добавил: javavirys ( 2018-05-14 20:48:43 )
Теги:JAVA ITEXT PDF
Рейтинг: + 0 -
Просмотров: 823

Специальные предложения