Apache PDFBOX Java Library - هل هناك واجهة برمجة تطبيقات لإنشاء الجداول؟
سؤال
أنا أستخدم مكتبة Apache PDFBox Java لإنشاء PDFs. هل هناك طريقة لإنشاء جدول بيانات باستخدام PDFBox؟ إذا لم يكن هناك مثل هذا API للقيام بذلك ، فسأحتاج إلى رسم الجدول يدويًا باستخدام السحب وما إلى ذلك ، أي اقتراحات حول كيفية القيام بذلك؟
المحلول
مصدر: إنشاء جداول مع pdfbox
ترسم الطريقة التالية جدولًا بمحتوى الجدول المحدد. انها قليلا من الاختراق وسيعمل مع سلاسل صغيرة من النص. لا يؤدي غلاف الكلمات ، ولكن يمكنك الحصول على فكرة عن كيفية القيام بذلك. جربها!
/**
* @param page
* @param contentStream
* @param y the y-coordinate of the first row
* @param margin the padding on left and right of table
* @param content a 2d array containing the table data
* @throws IOException
*/
public static void drawTable(PDPage page, PDPageContentStream contentStream,
float y, float margin,
String[][] content) throws IOException {
final int rows = content.length;
final int cols = content[0].length;
final float rowHeight = 20f;
final float tableWidth = page.findMediaBox().getWidth() - margin - margin;
final float tableHeight = rowHeight * rows;
final float colWidth = tableWidth/(float)cols;
final float cellMargin=5f;
//draw the rows
float nexty = y ;
for (int i = 0; i <= rows; i++) {
contentStream.drawLine(margin, nexty, margin+tableWidth, nexty);
nexty-= rowHeight;
}
//draw the columns
float nextx = margin;
for (int i = 0; i <= cols; i++) {
contentStream.drawLine(nextx, y, nextx, y-tableHeight);
nextx += colWidth;
}
//now add the text
contentStream.setFont( PDType1Font.HELVETICA_BOLD , 12 );
float textx = margin+cellMargin;
float texty = y-15;
for(int i = 0; i < content.length; i++){
for(int j = 0 ; j < content[i].length; j++){
String text = content[i][j];
contentStream.beginText();
contentStream.moveTextPositionByAmount(textx,texty);
contentStream.drawString(text);
contentStream.endText();
textx += colWidth;
}
texty-=rowHeight;
textx = margin+cellMargin;
}
}
الاستخدام:
PDDocument doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage( page );
PDPageContentStream contentStream = new PDPageContentStream(doc, page);
String[][] content = {{"a","b", "1"},
{"c","d", "2"},
{"e","f", "3"},
{"g","h", "4"},
{"i","j", "5"}} ;
drawTable(page, contentStream, 700, 100, content);
contentStream.close();
doc.save("test.pdf" );
نصائح أخرى
لقد قمت بإنشاء واجهة برمجة تطبيقات صغيرة لإنشاء جداول باستخدام PDFBox. يمكن العثور عليها على جيثب ( https://github.com/dhorions/boxable ) .
يمكن العثور على عينة من ملف pdf المتولد هنا http://goo.gl/a7qvrm.
أي تلميحات أو اقتراحات مرحب بها.
الإجابة المقبولة لطيفة لكنها ستعمل معها Apache pdfbox 1.x فقط ل Apache pdfbox 2.x ستحتاج إلى تعديل الكود قليلاً لجعله يعمل بشكل صحيح.
لذا ، إليك نفس الرمز ولكن هذا متوافق مع Apache pdfbox 2.x:
طريقة drawTable
:
public static void drawTable(PDPage page, PDPageContentStream contentStream,
float y, float margin, String[][] content) throws IOException {
final int rows = content.length;
final int cols = content[0].length;
final float rowHeight = 20.0f;
final float tableWidth = page.getMediaBox().getWidth() - 2.0f * margin;
final float tableHeight = rowHeight * (float) rows;
final float colWidth = tableWidth / (float) cols;
//draw the rows
float nexty = y ;
for (int i = 0; i <= rows; i++) {
contentStream.moveTo(margin, nexty);
contentStream.lineTo(margin + tableWidth, nexty);
contentStream.stroke();
nexty-= rowHeight;
}
//draw the columns
float nextx = margin;
for (int i = 0; i <= cols; i++) {
contentStream.moveTo(nextx, y);
contentStream.lineTo(nextx, y - tableHeight);
contentStream.stroke();
nextx += colWidth;
}
//now add the text
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12.0f);
final float cellMargin = 5.0f;
float textx = margin + cellMargin;
float texty = y - 15.0f;
for (final String[] aContent : content) {
for (String text : aContent) {
contentStream.beginText();
contentStream.newLineAtOffset(textx, texty);
contentStream.showText(text);
contentStream.endText();
textx += colWidth;
}
texty -= rowHeight;
textx = margin + cellMargin;
}
}
تم تحديث الاستخدام لاستخدام تجرب مع الموارد بيان لإغلاق الموارد بشكل صحيح:
try (PDDocument doc = new PDDocument()) {
PDPage page = new PDPage();
doc.addPage(page);
try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {
String[][] content = {{"a", "b", "1"},
{"c", "d", "2"},
{"e", "f", "3"},
{"g", "h", "4"},
{"i", "j", "5"}};
drawTable(page, contentStream, 700.0f, 100.0f, content);
}
doc.save("test.pdf");
}
نظرًا لأنني واجهت نفس المشكلة منذ بعض الوقت ، بدأت في بناء مكتبة صغيرة لها والتي أحاول أيضًا مواكبة ذلك.
يستخدم Apache pdfbox 2.x ويمكن العثور عليها هنا:https://github.com/vandeseer/Asytable
يسمح ببعض التخصيصات مثل ضبط الخط ولون الخلفية والحشو وما إلى ذلك على مستوى الخلية ، والمحاذاة الرأسية والأفقية ، والخلية امتداد ، ولف الكلمات والصور في الخلايا.
من الممكن أيضًا رسم الجداول عبر عدة صفحات.
يمكنك إنشاء جداول مثل هذا على سبيل المثال:
يمكن العثور على رمز هذا المثال هنا - أمثلة أخرى في نفس المجلد كذلك.