itext
페이지 이벤트 (iText 5) 대 이벤트 핸들러 및 렌더러 (iText 7)
수색…
비고
iText 5에서는 개발자가 문서를 열 때, 새 페이지를 열 때, 페이지가 끝날 때, 그리고 문서가 닫힐 때 특정 동작을 추가 할 수 있도록 페이지 이벤트 개념을 도입했습니다.
문서에서 우리는 onStartPage()
메서드에 내용을 추가하는 것이 금지되어 있음 을 분명히했습니다. 내용은 onEndPage()
메서드에서만 추가 할 수 있습니다. 또한 페이지 이벤트 메서드에 전달 된 Document
객체가 읽기 전용 으로 만 전달되었다는 점을 분명히했습니다. onEndPage()
메서드에서도 document.add()
를 사용하는 것은 금지 되었습니다.
불행하게도 많은 개발자가 설명서를 완전히 무시하고 다음과 같은 문제를 일으켰습니다.
- "OnEndPage"이벤트 처리기에서 " 'System.StackOverflowException"
- PDF를 생성하는 스택 오버플로 예외 가져 오기
- iTextSharp 행 구분 기호가 PdfPageEventHelper와 함께 사라집니다.
- iTextSharp 오류 문서를 열기 전에 페이지가 없습니다.
- ...
나는 또 다른 개발자가이 질문들을 중복하여 게시했기 때문에 내가 몇 번이나 동요했는지 기억할 수 없다. 사람들은 종종 왜 그들이 가혹한 대답을 얻는 지 궁금해하지만, 그들의 편에서의 최소한의 노력만으로는 자신을 포함하여 모든 사람에게 많은 시간을 절약 할 수 있다는 것을 깨닫지 못합니다. 이 질문들은 모두 "당신이 알고있는 설명서를 읽으십시오"라고 대답함으로써 대답 할 수있었습니다.
또 다른 옵션은 이러한 종류의 문제를 피할 수 있도록 iText의 완전한 정비였습니다.
iText의 유기적 인 성장으로 인해 페이지 이벤트 클래스는 페이지 이벤트와 무관 한 기능으로 확장되었습니다. 여기에는 일반 청크 기능이 포함되어 있으며 단락의 시작과 끝을 등록하는 등의 작업을 수행합니다.
우리가 iText 7에서 수정 한 것 :
우리는 페이지 이벤트 기능을 제거했습니다.
페이지에 대한 모든 이벤트의 경우, 우리는 지금 구현 IEventHandler
인터페이스를, 우리는 사용 addEventHandler
A와이 핸들러를 추가 PdfDocumentEvent
받는 PdfDocument
. 이 예에서는 END_PAGE
이벤트를 사용하지만 START_PAGE
이벤트도 사용할 수 있습니다. 처음부터 끝까지 콘텐츠를 추가하든 상관 없습니다. 이에 대한 자세한 내용은 이벤트 처리를 참조하십시오. iText 7 : Building Blocks 튜토리얼의 7 장인 뷰어 환경 설정 및 기록기 속성 설정하기 .
우리는 빌딩 블록을 더 계층 적으로 만들었다는 의미에서 빌딩 블록을 개선했습니다 ( 시작하기 전에 : iText 7 : Building Blocks 자습서의 소개 인 클래스 및 인터페이스 개요 참조). 또한 각 빌딩 블록에 하나씩 일련의 렌더러 클래스를 도입했으며, 개발자가 렌더러를 조정하여 렌더링시 다른 빌딩 블록이 표시되도록했습니다. 예를 들어, iText 7 : Building Blocks 튜토리얼의 7 장인 AbstractElement 객체 추가하기 (파트 1) 의 렌더러 예제를 참조하십시오.
이러한 변경으로 인해 PDF 및 iText에 대해 많이 알지 못하는 개발자는 기능을 단순화 할 수 있으며 동시에 iText 코드를 깊이 파헤 치지 않아 두려워하지 않는 개발자에게 유연성을 제공합니다. PDF는 그들이 원하는 방식으로 정확하게 전달됩니다.
더 알고 싶으십니까? 무료 전자 책을 받으십시오!
Text2PdfPageEvents.java (iText 5)
다음 텍스트 파일이 있다고 가정합니다. jekyll_hyde.txt
다음과 같이 PDF로 변환하려면 어떻게해야합니까?
제목에 추가 된 파란색 테두리와 각 페이지 하단의 페이지 번호를 확인하십시오. iText 5에서 이러한 요소는 페이지 이벤트를 사용하여 추가됩니다.
class MyPageEvents extends PdfPageEventHelper {
protected float startpos = -1;
protected boolean title = true;
public void setTitle(boolean title) {
this.title = title;
}
@Override
public void onEndPage(PdfWriter writer, Document document) {
Rectangle pagesize = document.getPageSize();
ColumnText.showTextAligned(
writer.getDirectContent(),
Element.ALIGN_CENTER,
new Phrase(String.valueOf(writer.getPageNumber())),
(pagesize.getLeft() + pagesize.getRight()) / 2,
pagesize.getBottom() + 15,
0);
if (startpos != -1)
onParagraphEnd(writer, document,
pagesize.getBottom(document.bottomMargin()));
startpos = pagesize.getTop(document.topMargin());
}
@Override
public void onParagraph(PdfWriter writer, Document document,
float paragraphPosition) {
startpos = paragraphPosition;
}
@Override
public void onParagraphEnd(PdfWriter writer, Document document,
float paragraphPosition) {
if (!title) return;
PdfContentByte canvas = writer.getDirectContentUnder();
Rectangle pagesize = document.getPageSize();
canvas.saveState();
canvas.setColorStroke(BaseColor.BLUE);
canvas.rectangle(
pagesize.getLeft(document.leftMargin()),
paragraphPosition - 3,
pagesize.getWidth() - document.leftMargin() - document.rightMargin(),
startpos - paragraphPosition);
canvas.stroke();
canvas.restoreState();
}
}
Text2Pdf.java (iText 5) 예제에서 텍스트 파일을 PDF로 변환하는 코드를 재사용하고 페이지 이벤트를 PdfWriter
도입 할 수 PdfWriter
.
public void createPdf(String dest)
throws DocumentException, IOException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
MyPageEvents events = new MyPageEvents();
writer.setPageEvent(events);
document.open();
BufferedReader br = new BufferedReader(new FileReader(TEXT));
String line;
Paragraph p;
Font normal = new Font(FontFamily.TIMES_ROMAN, 12);
Font bold = new Font(FontFamily.TIMES_ROMAN, 12, Font.BOLD);
boolean title = true;
while ((line = br.readLine()) != null) {
p = new Paragraph(line, title ? bold : normal);
p.setAlignment(Element.ALIGN_JUSTIFIED);
events.setTitle(title);
document.add(p);
title = line.isEmpty();
}
document.close();
}
Text2PdfPageEvents1.java (iText 7)
다음 텍스트 파일이 있다고 가정하십시오. jekyll_hyde.txt
다음과 같이 PDF로 변환하려면 어떻게해야합니까?
각 페이지 하단의 페이지 번호를 기록하십시오. 이것은 IEventHandler
구현을 사용하여 추가됩니다.
protected class Footer implements IEventHandler {
@Override
public void handleEvent(Event event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdf = docEvent.getDocument();
PdfPage page = docEvent.getPage();
Rectangle pageSize = page.getPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(
page.getLastContentStream(), page.getResources(), pdf);
Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
float y = pageSize.getBottom() + 15;
canvas.showTextAligned(
String.valueOf(pdf.getPageNumber(page)),
x, y, TextAlignment.CENTER);
}
}
Text2Pdf.java (iText 7) 예제는 두 가지 사소한 변경만으로 재사용 할 수 있습니다.
public void createPdf(String dest) throws IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
pdf.addEventHandler(PdfDocumentEvent.END_PAGE, new Footer());
Document document = new Document(pdf)
.setTextAlignment(TextAlignment.JUSTIFIED);
BufferedReader br = new BufferedReader(new FileReader(TEXT));
String line;
PdfFont normal = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
PdfFont bold = PdfFontFactory.createFont(FontConstants.TIMES_BOLD);
boolean title = true;
Border border = new SolidBorder(Color.BLUE, 1);
while ((line = br.readLine()) != null) {
document.add(new Paragraph(line)
.setFont(title ? bold : normal)
.setBorder(title ? border : Border.NO_BORDER));
title = line.isEmpty();
}
document.close();
}
페이지가 끝날 때마다 Footer
클래스의 handleEvent()
메서드를 트리거하는 이벤트 핸들러를 추가합니다. 또한 제목에 사용되는 Paragraph
개체의 테두리를 정의합니다.
출처 : developers.itextpdf.com 및 iText 7 : Building Blocks 튜토리얼.
Text2PdfPageEvents2.java
다음 텍스트 파일이 있다고 가정하십시오. jekyll_hyde.txt
다음과 같이 PDF로 변환하려면 어떻게해야합니까?
이것은 이전에 보았던 것과 매우 비슷하지만 제목의 경계는 둥근 모서리를 갖습니다. 이를 위해 커스텀 ParagraphRenderer
를 만들고, 렌더러를 사용하는 TitleParagraph
객체를 만들었습니다.
public class TitleParagraph extends Paragraph {
public TitleParagraph(String line) {
super(line);
try {
setFont(PdfFontFactory.createFont(FontConstants.TIMES_BOLD));
}
catch (IOException ioe) {
}
}
@Override
protected IRenderer makeNewRenderer() {
return new ParagraphRenderer(this) {
@Override
public void drawBorder(DrawContext drawContext) {
Rectangle occupiedAreaBBox = getOccupiedAreaBBox();
float[] margins = getMargins();
Rectangle rectangle = applyMargins(occupiedAreaBBox, margins, false);
PdfCanvas canvas = drawContext.getCanvas();
canvas.roundRectangle(rectangle.getX() - 1, rectangle.getY() - 1,
rectangle.getWidth() + 2, rectangle.getHeight() + 2, 5).stroke();
}
};
}
}
텍스트를 PDF로 변환하는 코드는 매우 간단합니다. 제목에 글꼴을 더 이상 굵게 설정하지 않아도 더 이상 테두리를 정의 할 필요가 없습니다.
public void createPdf(String dest) throws IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
pdf.addEventHandler(PdfDocumentEvent.END_PAGE, new Footer());
Document document = new Document(pdf)
.setTextAlignment(TextAlignment.JUSTIFIED);
BufferedReader br = new BufferedReader(new FileReader(TEXT));
String line;
PdfFont normal = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
boolean title = true;
Border border = new SolidBorder(Color.BLUE, 1);
while ((line = br.readLine()) != null) {
if (title)
document.add(new TitleParagraph(line));
else
document.add(new Paragraph(line).setFont(normal));
title = line.isEmpty();
}
document.close();
}
출처 : developers.itextpdf.com 및 iText 7 : Building Blocks 튜토리얼.