الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

توليد وتعديل ملفات pdf بواسطة iText - الجزء الثاني

بدأه herch في 8 ديسمبر 2009 · 9 رد · 1,645 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بعد أن تعرفنا على كيفية توليد ملفات pdf في الموضوع السابق توليد ملفات pdf بواسطة iText - الجزء الأول، سنرى الآن كيف نعدل ملفات موجودة مسبقا.

لهذا الغرض نستعمل الكلاس PdfContentByte التي تمثل محتوى الملف والتي تتيح لنا إضافة ما نريد لهذا المحتوى.

للحصول على كائن من هذه الكلاس، نحتاج إلى الكلاس PdfStamper التي تحتوي على الدوال getOverContent و getUnderContent. الأولى تعيد PdfContentByte يمثل مقدمة الوثيقة، أي المحتوى، getUnderContent تعيد PdfContentByte يمثل خلفية الوثيقة، والتي غالبا تكون فارغة، لكن أحيانا يمكن أن نستعملها مثلا لوضع logo الشركة على خلفية وثيقة.

سنحتاج إلى الكلاس PdfReader التي تمكننا من التعرف على خصائص الملف pdf الذي نريد تعديله، كما أن الconstructor الخاص بPdfStamper يحتاج أيضا لهذه الكلاس.

أولا ننشئ PdfReader ونممر له مسار الملف الذي نريد تعديله

PdfReader reader = new PdfReader("source.pdf");

ثم ننشئ PdfStamper ونمرر له الPdfReader الذي أنشأناه، وأيضا FileOutputStream وهو يمثل الملف الذي سنكتب فيه نتيجة التعديل. أي أننا لن نعدل مباشرة في الملف الاصلي، بل سننتج ملفا جديدا يحتوي على التعديلات.

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("result.pdf"));

ما سنقوم به الأن هو إضافة رقم الصفحة إلى كل صفحات الملف. لهذا الغرض نقوم بعمل loop على كل صفحات الملف، لأنه لا يوجد PdfContentByte خاص بالملف بأكمله، بل كل صفحة لها PdfContentByte خاص بها.

سنحتاج معرفة عدد صفحات الملف حتى نتمكن من عمل الloop، لذلك سنستعمل getNumberOfPages الخاصة بPdfReader

for (int i = 1; i <= reader.getNumberOfPages(); i++) {
	PdfContentByte overContent = stamper.getOverContent(i);
	//...
}

بعد أن حصلنا على كائن PdfContentByte يمثل المحتوى الموجود في المقدمة، سنقوم بكتابة رقم الصفحة، لكن قبل ذلك يجب أن نحدد الخط الذي سيكتب به النص وحجمه

overContent.setFontAndSize(BaseFont.createFont(), 12);

الكلاس BaseFont هي كلاس خاصة بiText وهي تمثل خطا، الرقم 12 يمثل حجم الخط.

بعد أن حددنا الخط يجب أن نحدد المكان الذي سنكتب فيه، اي الإحداثيات x و y

overContent.setTextMatrix(reader.getPageSize(i).getWidth()/2, 20);

نريد أن نكتب في وسط الصفحة أفقيا، لذلك نسترجع عرض الصفحة الحالية ونقسمه على 2، بالنسبة للموقع العمودي فهو 20 من الاسفل!!! نعم من الاسفل، ففي iText الإحداثيات (0-0) موجودة في اسفل اليسار، وليس في أعلى اليسار كما تعودنا مع الجافا.

الآن بقي لنا أن نكتب النص الذي تريد، وهو رقم الصفحة

overContent.showText("page " + i);

الشكل النهائي للloop هو كالتالي

for (int i = 1; i <= reader.getNumberOfPages(); i++) {
	PdfContentByte overContent = stamper.getOverContent(i);
	overContent.setFontAndSize(BaseFont.createFont(), 12);
	overContent.setTextMatrix(reader.getPageSize(i).getWidth()/2, 20);
	overContent.showText("page " + i);
}

بعد أن أضفنا النص، سنحاول اىن إضافة صورة. كما سبق وقلت فإننا نتوفر على مكانين لإضافة محتوى ما، المقدمة، ونحصل عليها بgetOverContent والخلفية الممثلة بgetUnderContent. هاتان الصورتان توضحان الفرق,

post-181903-12602891581696_thumb.png

post-181903-12602891719318_thumb.png

في الحالة الأولى أضفنا الصورة للمقدمة، وفي الثانية أضفناها للخلفية.

أولا، ننشئ الصورة التي نريد إظهارها، ثم نحدد إحداثيتها، مثلا (200-200)

Image img = Image.getInstance("img.png");
img.setAbsolutePosition(200, 200);

هذه الكلاس Image هي كلاس خاصة بiText ولا علاقة لها بتلك الموجودة في الحزمة java.awt.

بعد أن حصلنا على الصورة، سنعمل loop على كل صفحات الملف، كما فعلنا مع كتابة النص، لكن هنا سنستعمل getUnderContent بدل getOverContent لأننا نريد الكتابة في الخلفية

for (int i = 1; i <= reader.getNumberOfPages(); i++) {
	PdfContentByte underContent = stamper.getUnderContent(i);
	underContent.addImage(img);
}

بعد أن انتهينا نقفل الPdfStamper والPdfReader

stamper.close();
reader.close();

وهذا الكود النهائي

import com.lowagie.text.DocumentException;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import java.io.FileOutputStream;
import java.io.IOException;

public class ModifyPdf {

	public static void main(String[] args) {
		try {
			PdfReader reader = new PdfReader("source.pdf");
			PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("result.pdf"));

			//add the page number
			for (int i = 1; i <= reader.getNumberOfPages(); i++) {
				PdfContentByte overContent = stamper.getOverContent(i);
				overContent.setFontAndSize(BaseFont.createFont(), 12);
				overContent.setTextMatrix(reader.getPageSize(i).getWidth() / 2, 20);
				overContent.showText("page " + i);
			}

			//add the image to the background
			Image img = Image.getInstance("img.png");
			img.setAbsolutePosition(200, 200);
			for (int i = 1; i <= reader.getNumberOfPages(); i++) {
				PdfContentByte underContent = stamper.getUnderContent(i);
				underContent.addImage(img);
			}
			stamper.close();
			reader.close();
			System.out.println("File modified successfully.");
		} catch (DocumentException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
}
1
#2

مجهود جبار يا عصام ....

لكن لدي سؤال .. هلى المكتبة تدعم توليد ملفات pdf باللغة العربية ؟؟؟

#3

شكرا لك يا عصام ...

MKSoft كتب:

مجهود جبار يا عصام ....

لكن لدي سؤال .. هلى المكتبة تدعم توليد ملفات pdf باللغة العربية ؟؟؟

نعم ...

#4

نعم، تدعم العربية، لكن لا أعرف كيف حاليا :unsure: :D

حاولت توليد ملف بمحتوى عربي لكن لم يظهر المحتوى :blink:

#5

هناك عده امور يجب ان تتأكد منها لتوليد ملف pdf باللغة العربية بواسطة iText

1- ان يكون نوع الخط يدعم اللغة العربية . (لذلك يتطلب الامر احيانا اضافة ملف الخط مع البرنامج)

String fontPath = "ARIAL.TTF";
			BaseFont bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H,true);
			Font font = new Font(bf, 8, Font.NORMAL);
.
.
.
new Paragraph("...text...",font)

2- اعداد المستند للكتابة من اليمين الى اليسار.

لتجربة برنامج الاخ عصام

src.rar

تم تعديل هذه المشاركة بواسطة العيافـي في 9 ديسمبر 2009 في 14:25

#6

شكرا لك أخ عيافي. اعرف أنه يجب إضافة خط يدعم العربية، لكن كانت تأتيني exception عند استعمال خط جديد، وفي الحقيقة أحبطتني فقلت أتركها لوقت آخر

هل سبق وتعاملت مع هذه المكتبة؟؟

تم تعديل هذه المشاركة بواسطة herch في 9 ديسمبر 2009 في 14:24

#7

المرفق برنامج الاخ عصام بصيغة jar

يمكنك تجربة اللغة العربية

herch_test.rar

#8
herch كتب:

شكرا لك أخ عيافي. اعرف أنه يجب إضافة خط يدعم العربية، لكن كانت تأتيني exception عند استعمال خط جديد، وفي الحقيقة أحبطتني فقلت أتركها لوقت آخر

هل سبق وتعاملت مع هذه المكتبة؟؟

قمت بتجربتها سابقا و ارى انها اسوأ مكتبه في جافا ...

لسبب واحد و هو في كل اصدار تتغير اسماء الطرق ...

اما الاصدار الجديد من itext رقم 5 فتم تغيير اسم الحزمة بالكامل

من com.lowagie.text.*

الى com.itextpdf.text.*

والله اعلم

#9

سمعت أنه سيتم تغييرها، لكن لم أكن اعلم أن ذلك تم بالفعل,

حتى طريقة تنظيمها غريبة، فمن أجل الكتابة يجب أن تمرر للكلاس التي تكتب object من كلاس تقوم بالقراءة!!! واشياء غريبة أخرى...

كما أن المصدر الوحيد الشامل للمعلومات عن الحزمة هو الكتاب الذي كتبه صاحب الحزمة نفسه

لكنها تتيح إمكانيات هائلة. هل هناك مكتبة أخرى مثلها؟؟

#10
herch كتب:

سمعت أنه سيتم تغييرها، لكن لم أكن اعلم أن ذلك تم بالفعل,

حتى طريقة تنظيمها غريبة، فمن أجل الكتابة يجب أن تمرر للكلاس التي تكتب object من كلاس تقوم بالقراءة!!! واشياء غريبة أخرى...

كما أن المصدر الوحيد الشامل للمعلومات عن الحزمة هو الكتاب الذي كتبه صاحب الحزمة نفسه

لكنها تتيح إمكانيات هائلة. هل هناك مكتبة أخرى مثلها؟؟

اكيد بانها تتيح امكانيات هائلة .. وكذلك يستخدما IReport . ولكني ارى ان تصميمها سيء لسبب الذي ذكرته سابقا "خاصة اني تضررت منها سابقا".

لست متأكد من وجود مكتبه اخرى .... لكن يمكنك البحث عن ملف جار باسم orinoco اعتقد بانه يدور حول PDF

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…