itext
पृष्ठ ईवेंट (iText 5) बनाम ईवेंट हैंडलर और रेंडरर्स (iText 7)
खोज…
टिप्पणियों
IText 5 में, हमने डेवलपर्स को दस्तावेज़ खोलते समय, नए पृष्ठ को खोलने पर, जब पृष्ठ समाप्त होता है, और जब कोई दस्तावेज़ बंद होता है, तो विशिष्ट व्यवहार को जोड़ने की अनुमति देने के लिए पृष्ठ घटनाओं की अवधारणा पेश की।
दस्तावेज़ीकरण में, हमने यह बहुत स्पष्ट कर दिया कि onStartPage()
विधि में सामग्री जोड़ना मना था; सामग्री केवल onEndPage()
विधि में जोड़ी जा सकती है। हमने यह भी स्पष्ट किया है कि Document
घटना पृष्ठ के तरीकों के लिए पारित किया गया था केवल पढ़ने के लिए केवल उद्देश्यों के लिए पारित किया गया था। यह onEndPage()
विधि में भी document.add()
का उपयोग करने के लिए मना किया गया था।
दुर्भाग्य से, कई डेवलपर्स पूरी तरह से प्रलेखन को अनदेखा करते हैं, जिसके कारण समस्याएं पैदा हुईं जैसे:
- "OnEndPage" ईवेंट हैंडलर में "System.StackOverflowException"
- स्टैक ओवरफ्लो एक्सेप्शन प्राप्त करना एक पीडीएफ उत्पन्न करता है
- iTextSharp लाइन विभाजक PdfPageEventHelper के साथ गायब हो जाता है
- iTextSharp त्रुटि दस्तावेज़ को खोलने से पहले कोई पृष्ठ नहीं है
- ...
मुझे याद नहीं है कि मैं कितनी बार उत्तेजित हुआ क्योंकि अभी तक किसी अन्य डेवलपर ने इन सवालों का एक डुप्लिकेट पोस्ट किया था। लोगों को अक्सर आश्चर्य होता है कि उन्हें कठोर जवाब क्यों मिलता है, लेकिन उन्हें इस बात का अहसास नहीं है कि उनकी तरफ से किए गए न्यूनतम प्रयास से हर किसी को बहुत समय बचा होगा। इन सभी सवालों का जवाब "Read The (you-know-which) मैन्युअल" कहकर दिया जा सकता था।
एक अन्य विकल्प iText का एक पूरा ओवरहाल था ताकि इस तरह की समस्याओं से बचा जा सके।
IText के जैविक विकास के कारण, पेज इवेंट क्लास को कार्यक्षमता के साथ भी बढ़ाया गया था जो पेज इवेंट से संबंधित नहीं था। इसमें सामान्य चंक कार्यक्षमता थी, इसने पैराग्राफ की शुरुआत और अंत दर्ज किया, और इसी तरह।
हमने iText 7 में क्या तय किया है:
हमने पृष्ठ ईवेंट कार्यक्षमता को हटा दिया।
पृष्ठों के संबंध में सभी घटनाओं के लिए, हम अब लागू IEventHandler
इंटरफेस है, और हम का उपयोग addEventHandler
एक के रूप में इस हैंडलर जोड़ने के PdfDocumentEvent
को PdfDocument
। उदाहरण में, हम END_PAGE
घटना का उपयोग करते हैं, लेकिन हम START_PAGE
घटना का भी उपयोग कर सकते हैं। इससे कोई फर्क नहीं पड़ता कि आप शुरुआत में या अंत में सामग्री जोड़ते हैं या नहीं। आप हैंडलिंग घटनाओं में इसके बारे में अधिक पढ़ सकते हैं ; व्यूअर वरीयताओं और लेखक गुणों को सेट करना जो iText 7 में अध्याय 7 है : बिल्डिंग ब्लॉक्स ट्यूटोरियल।
हमने बिल्डिंग ब्लॉक में इस अर्थ में सुधार किया कि हमने उन्हें अधिक पदानुक्रमित बनाया (देखें इससे पहले कि हम शुरू करें: कक्षाओं और इंटरफेस का अवलोकन जो iText 7 का परिचय है : बिल्डिंग ब्लॉक्स ट्यूटोरियल)। हमने रेंडरर कक्षाओं का एक सेट भी पेश किया है, जो प्रत्येक बिल्डिंग ब्लॉक के लिए है, और हम डेवलपर्स को इन रेंडरर्स को अनुकूलित करने की अनुमति देते हैं ताकि बिल्डिंग ब्लॉक का प्रतिपादन होने पर एक अलग व्यवहार दिखाई दे। उदाहरण के लिए देखें रेंडर उदाहरण को एसेन्सेमेंट ऑब्जेक्ट्स (भाग 1) में जोड़ना जो अध्याय 7 में अध्याय 7: बिल्डिंग ब्लॉक्स ट्यूटोरियल है।
ये परिवर्तन उन डेवलपर्स के लिए कार्यक्षमता को सरल बनाते हैं, जो PDF और iText के बारे में अधिक नहीं जानना चाहते (जबकि) उन डेवलपर्स के लिए लचीलेपन की प्रचुरता की पेशकश करते हैं, जो iText कोड में गहरी खुदाई करने से डरते नहीं हैं बनाने के लिए पीडीएफ बिल्कुल वैसा ही जैसा वे चाहते हैं।
अधिक जानना चाहते हैं? मुफ्त ebook जाओ!
Text2PdfPageEvents.java (iText 5)
मान लीजिए कि हमारे पास निम्नलिखित पाठ फ़ाइल है: jekyll_illy.txt
हम इसे एक पीडीएफ में कैसे बदलते हैं जो इस तरह दिखता है:
नीले रंग की सीमा को नोट करें, जो शीर्षकों में जोड़ा गया है, और प्रत्येक पृष्ठ के नीचे पृष्ठ संख्या। 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) उदाहरण से एक पीडीएफ में बदलने के लिए कोड का पुन: उपयोग कर सकते हैं, और पेज इवेंट को 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();
}
स्रोत: Developers.itextpdf.com
Text2PdfPageEvents1.java (iText 7)
मान लें कि आपके पास निम्न पाठ फ़ाइल है: jekyll_illy.txt
हम इसे एक पीडीएफ में कैसे बदलते हैं जो इस तरह दिखता है:
प्रत्येक पृष्ठ के नीचे पृष्ठ संख्या नोट करें। इन्हें 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();
}
हम एक ईवेंट हैंडलर कि ट्रिगर किया जाएगा जोड़ने handleEvent()
की विधि Footer
वर्ग हर बार एक पृष्ठ समाप्त हो जाती है। हम Paragraph
ऑब्जेक्ट्स के लिए एक सीमा को भी परिभाषित करते हैं जो एक शीर्षक के लिए उपयोग किए जाते हैं।
स्रोत: Developers.itextpdf.com और iText 7: बिल्डिंग ब्लॉक्स ट्यूटोरियल।
Text2PdfPageEvents2.java
मान लें कि आपके पास निम्न पाठ फ़ाइल है: jekyll_illy.txt
हम इसे एक पीडीएफ में कैसे बदलते हैं जो इस तरह दिखता है:
ध्यान दें कि यह बहुत कुछ वैसा ही है जैसा पहले हमारे पास था, लेकिन शीर्षकों की सीमा अब गोल कोनों की है। हमने इसे प्राप्त करने के लिए एक कस्टम 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();
}
};
}
}
पाठ को पीडीएफ में बदलने के लिए हमारा कोड अब बहुत सरल है। हमें अब शीर्षक के लिए फ़ॉन्ट को सेट करने की आवश्यकता नहीं है और हमें अब सीमा को परिभाषित नहीं करना है:
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: बिल्डिंग ब्लॉक्स ट्यूटोरियल।