Align Paragraph at the center of the page - java

I am using itext to generate pdf file. I want to align my title in the middle of the page. Presently i am using like this
Paragraph preface = new Paragraph();
for (int i = 0; i < 10; i++) {
preface.add(new Paragraph(" "));
}
Is it correct or is there any another best way to do this.

Use Paragraph#setAlignment(int) :
Paragraph preface = new Paragraph();
preface.setAlignment(Element.ALIGN_CENTER);
See the ALIGN_* constants in the Element interface for more possible values.

Not sure if this is an old version, but for PdfWriter these methods weren't there. Instead I used:
Paragraph p = new Paragraph("This too shall pass");
p.Alignment = Element.ALIGN_CENTER;

public static final String DEST = "results/tables/centered_text.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new CenteredTextInCell().createPdf(DEST);
}
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Font font = new Font(FontFamily.HELVETICA, 12, Font.BOLD);
Paragraph para = new Paragraph("Test", font);
para.setLeading(0, 1);
PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(100);
PdfPCell cell = new PdfPCell();
cell.setMinimumHeight(50);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.addElement(para);
table.addCell(cell);
document.add(table);
document.close();
}

If you are looking for a solution to Itext7 then you can use the method setTextAlignment(...).
Example:
Paragraph preface = new Paragraph();
// add text
preface.setTextAlignment(TextAlignment.CENTER);

If any one is looking for .NET/C# version, below is how I achieved the CENTER alignment.
I am using iText7 library for .NET/C#, and I achieved this using :
Paragraph preface = new Paragraph();
preface.SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER);

This is what worked for me (itext 5.0.5 ):
Paragraph p3= new Paragraph("Hello" );
p3.setAlignment(Element.ALIGN_CENTER);

I have searching solution for this to align PdfPCell text into right and also center. After modify and change the code sequence it is work.
This code is not work to align text to center.
PdfPCell cell = new PdfPCell();
cell.addElement(new Phrase("Testing Page");
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
After modifying code with this , it is working now.
Paragraph p = new Paragraph("Testing Page");
//Pass Paragraph object into PdfPCell
PdfPCell cell = new PdfPCell(p);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);

Related

iTextPDF - Cannot use writeSelectedRows() on a table where an anchor has been inserted

I am in the process of converting the contents page of my PDF from using page numbers as a hyperlink, to anchors because of a few circumstantial limitations and the linking needs to be more dynamic.
I have omitted outer-loop code, but I am attempting to create a hyperlinked entry in the contents page using the following:
PdfPCell cell = new PdfPCell();
Paragraph p = new Paragraph();
Anchor anchor = new Anchor("page18 link");
anchor.setReference("#page18");
p.add(anchor);
cell.addElement(p);
table.addCell(cell);
Once the contents page has been generated (i.e. all the rows have been added), I then use the writeSelectedRows on the table:
table.writeSelectedRows(0, -1, PageSize.A4.getWidth()*.05f, PageSize.A4.getHeight()-100, stamper.getOverContent(prevSectionPageCount+currentIndexPage+1));
On doing this, I get the following exception:
Cause Exception was: Error in StamperPDFPlugin. null
java.lang.NullPointerException at
com.itextpdf.text.pdf.internal.PdfAnnotationsImp.addPlainAnnotation(PdfAnnotationsImp.java:125)
at com.itextpdf.text.pdf.PdfDocument.localGoto(PdfDocument.java:2115)
at
com.itextpdf.text.pdf.PdfDocument.writeLineToContent(PdfDocument.java:1612)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:1025) at
com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:877) at
com.itextpdf.text.pdf.ColumnText.goComposite(ColumnText.java:1381) at
com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:882) at
com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:877) at
com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:866) at
com.itextpdf.text.pdf.PdfPRow.writeCells(PdfPRow.java:549) at
com.itextpdf.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:767)
at
com.itextpdf.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:897)
at
com.itextpdf.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:845)
at
com.itextpdf.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:823)
at
com.ems.rendition.cts.plugin.StamperPDFPlugin.transform(StamperPDFPlugin.java:584)
at
com.ems.rendition.cts.plugin.StamperPDFPlugin.transform(StamperPDFPlugin.java:328)
at
com.ems.rendition.cts.plugin.StamperPDFPlugin.executeProfile(StamperPDFPlugin.java:171)
On seeing the stack trace entry for localGoto, I took out the line anchor.setReference("#18.pdf"); and it completed fine without error (but obviously with the absence of the hyperlinks - only plain text).
What is going wrong here? Am I adding the anchor to the cell incorrectly?
Thanks
Please take a look at LinkInPositionedTable:
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Anchor target = new Anchor("top");
target.setName("page18");
document.add(target);
PdfPTable table = new PdfPTable(1);
table.setTotalWidth(500);
PdfPCell cell = new PdfPCell();
Paragraph p = new Paragraph();
Anchor anchor = new Anchor("page18 link");
anchor.setReference("#page18");
p.add(anchor);
cell.addElement(p);
table.addCell(cell);
table.writeSelectedRows(0, -1, 36, 700, writer.getDirectContent());
document.close();
}
In this example, I create an anchor with name page18 (although it just refers to the top of the page) and a reference to that anchor added to a PdfPTable using your code snippet.
You can find the result here: link_in_positioned_table.pdf
This works for me, when using iText 5.5.7 (which is the most recent version).

When i am generating pdf form I want to add form number on top left of the pdf using itext java

Hi When I am generating form using java with itext I want to add form number on top left of the document
above the header.Please let me know the ways to do it.
PdfPTable table = new PdfPTable(3); // 3 columns.
table.setWidthPercentage(100);
PdfPCell cell1 = new PdfPCell(new Paragraph("Cell 1"));
PdfPCell cell2 = new PdfPCell(new Paragraph("Cell 2"));
PdfPCell cell3 = new PdfPCell(new Paragraph("Cell 3"));
cell1.setBorder(0);
cell2.setBorder(0);
cell3.setBorder(0);
table.addCell(cell1);
table.addCell(cell2);
table.addCell(cell3);
How can I set the table alignment to start of the page margin.
Your question is very confusing. You say you are creating a form, but when you say form, you don't seem to be referring to an interactive form, but to an ordinary PDF containing a table.
You say you want to add a number above the header, but you are not telling us what you mean by header. You are assuming that the people reading your question can read your mind.
I guess you want to use a page event to add a String in the top left corner of each page. That would make your question almost a duplicate of itextsharp: How to generate a report with dynamic header in PDF using itextsharp?
You can create a subclass of PdfPageEventHelper like this:
public class Header extends PdfPageEventHelper {
protected Phrase header;
public void setHeader(Phrase header) {
this.header = header;
}
#Override
public void onEndPage(PdfWriter writer, Document document) {
PdfContentByte canvas = writer.getDirectContentUnder();
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, header, 36, 806, 0);
}
}
You can then use this Header class like this:
public void createPdf(String filename) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
Header event = new Header();
writer.setPageEvent(event);
// step 3
document.open();
// step 4
List<Integer> factors;
for (int i = 2; i < 301; i++) {
factors = getFactors(i);
if (factors.size() == 1) {
document.add(new Paragraph("This is a prime number!"));
}
for (int factor : factors) {
document.add(new Paragraph("Factor: " + factor));
}
event.setHeader(new Phrase(String.format("THE FACTORS OF %s", i)));
document.newPage();
}
// step 5
document.close();
}
In your case, you wouldn't have:
event.setHeader(new Phrase(String.format("THE FACTORS OF %s", i)));
You'd have something like:
event.setHeader(new Phrase(number));
Where number is the number you want to add at the coordinate x = 36, y = 806.

RTL not working in pdf generation with itext 5.5 for Arabic text

I have java code that writes arabic characters with the help of itext 5.5 and xmlworker jars, but its writing left to right even after writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL) is used.
Code used is:
public class CreateArabic extends DefaultHandler {
/** Paths to and encodings of fonts we're going to use in this example */
public static String[][] FONTS = {
{"C:/arialuni.ttf", BaseFont.IDENTITY_H},
{"C:/abserif4_5.ttf", BaseFont.IDENTITY_H},
{"C:/damase.ttf", BaseFont.IDENTITY_H},
{"C:/fsex2p00_public.ttf", BaseFont.IDENTITY_H}
};
/** Holds he fonts that can be used for the peace message. */
public FontSelector fs;
public CreateArabic() {
fs = new FontSelector();
for (int i = 0; i < FONTS.length; i++) {
fs.addFont(FontFactory.getFont(FONTS[i][0], FONTS[i][1], BaseFont.EMBEDDED));
}
}
public static void main(String args[]) {
try {
// step 1
Rectangle pagesize = new Rectangle(8.5f * 72, 11 * 72);
Document document = new Document();//pagesize, 72, 72, 72, 72);// step1
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream("c:\\report.pdf"));
writer.setInitialLeading(200.5f);
//writer.getAcroForm().setNeedAppearances(true);
//writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
document.open();
FontFactory.registerDirectories();
Font font = FontFactory.getFont("C:\\damase.ttf",
BaseFont.IDENTITY_H, true, 22, Font.BOLD);
// step 3
document.open();
// step 4
XMLWorkerHelper helper = XMLWorkerHelper.getInstance();
// CSS
CSSResolver cssResolver = new StyleAttrCSSResolver();
CssFile cssFile = helper.getCSS(new FileInputStream(
"D:\\Itext_Test\\Test\\src\\test.css"));
cssResolver.addCss(cssFile);
// HTML
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider();
// fontProvider.addFontSubstitute("lowagie", "garamond");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(
cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// // Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver,
html);
writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
System.out.println("RUN DIRECTION --> "+writer.getRunDirection());
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker,Charset.forName("UTF-8"));
String htmlString2 = "<html><body style=\"color:red;\">Hello"+"??"+"</body></html>";
String htmlString = "<body style='font-family:arial;'>h"+"??"+"<p style='font-family:arial;' > ????? </p></body>";
String html1 ="<html><head></head><body>Hello <p style=\"color:red\" >oo ??</p> World! \u062a\u0639\u0637\u064a \u064a\u0648\u0646\u064a\u0643\u0648\u062f \u0631\u0642\u0645\u0627 \u0641\u0631\u064a\u062f\u0627 \u0644\u0643\u0644 \u062d\u0631\u0641 "+htmlString+"Testing</body></html>";
ByteArrayInputStream is = new ByteArrayInputStream(htmlString.getBytes("UTF-8"));
p.detectEncoding(is);
p.parse(is, Charset.forName("UTF-8"));//.parse(is, "UTF-8");//parse(is);//ASMO-708
// step 5
document.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Output file is also attached.
As documented, this is not supposed to work:
writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
Arabic (and Hebrew) can only be rendered correctly in the context of ColumnText and PdfPCell. In other words: if you want to use Arabic from XML Worker, you need to create an ElementList and then add the elments to a ColumnText object as is done here.
You need to set the run direction at the level of the ColumnText object.
//This solution works for me: :)
// document
Document document = new Document(PageSize.LEGAL);
//fonts
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("/Users/ibrahimbakhsh/Library/Fonts/tradbdo.ttf", BaseFont.IDENTITY_H);
fontProvider.register("/Users/ibrahimbakhsh/Library/Fonts/trado.otf", BaseFont.IDENTITY_H);
fontProvider.register("/Users/ibrahimbakhsh/Library/Fonts/tahoma.ttf", BaseFont.IDENTITY_H);
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// CSS
CSSResolver cssResolver =
XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, end);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// HTML
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.autoBookmark(false);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream(HTML));
//writer
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
writer.setInitialLeading(12.5f);
writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
// step 4
document.open();
// step 5
for (Element e : elements) {
//out.println(e.toString());
if(e instanceof PdfPTable){
PdfPTable t = (PdfPTable) e;
t.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
ArrayList<PdfPRow> rows = t.getRows();
for(PdfPRow row:rows){
PdfPCell[] cells = row.getCells();
for(PdfPCell cell:cells){
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
}
}
e = t;
}
document.add(e);
}
//try adding new table
PdfPTable table = new PdfPTable(1);
table.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
Font f = new Font(BaseFont.createFont("/Users/ibrahimbakhsh/Library/Fonts/trado.otf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED));
PdfPCell cell = new PdfPCell(new Paragraph("تجربة نص عربي",f));
table.addCell(cell);
document.add(table);
// step 6
document.close();
For developers that need an straightforward solution
I used this trick and output is very clean and nice!
create a PDFPTable with 1 column
for every paragraph of your content, create a Paragraph object and set its alignment to Paragraph.ALIGN_JUSTIFIED (I don't know why but it causes to paragraph align to right of page!!!)
create a PDFPCell and remove its borders using setBorder(Rectangle.NO_BORDER) and add the paragraph to cell
add the cell to the table
here is a code sample to your convenience.
public void main(){
/*
* create and initiate document
* */
// repeat this for all your paragraphs
PdfPTable pTable = new PdfPTable(1);
Paragraph paragraph = getCellParagraph();
paragraph.add("your RTL content");
PdfPCell cell = getPdfPCellNoBorder(paragraph);
pTable.addCell(cell);
// after add all your content
document.add(pTable);
}
private Paragraph getCellParagraph() {
Paragraph paragraph = new Paragraph();
paragraph.setAlignment(Paragraph.ALIGN_JUSTIFIED);
// set other styles you need like custom font
return paragraph;
}
private PdfPCell getPdfPCellNoBorder(Paragraph paragraph) {
PdfPCell cell = new PdfPCell();
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
cell.setPaddingBottom(8);
cell.setBorder(Rectangle.NO_BORDER);
cell.addElement(paragraph);
return cell;
}

Outputstream - create non editable pdf file

Below code is for writing pdf file;
BaseFont bf = BaseFont.createFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
FontSelector fs = new FontSelector();
fs.addFont(new Font(bf));
String fileName = filePath3 + "//DEVIATION_REPORT.pdf";
OutputStream file = new FileOutputStream(new File(fileName));
Font smallFont = new Font(Font.FontFamily.COURIER, 6, Font.NORMAL);
Font headerFont = new Font(Font.FontFamily.HELVETICA, 7, Font.BOLD);
Font tabFont = new Font(Font.FontFamily.HELVETICA, 5, Font.NORMAL);
Font rusFont = new Font(bf, 5);
Font blueFont = new Font(bf, 5);
blueFont.setColor(BaseColor.BLUE);
Font redFont = new Font(bf, 5);
redFont.setColor(BaseColor.RED);
String comType;
if (compType == 2)
comType = "Character";
else
comType = "Word";
Document doc = new Document();
PdfWriter.getInstance(doc, file);
doc.open();
Image image1 = Image.getInstance(cmdpath + "ScRp.jpg");
image1.setAlignment(Element.ALIGN_LEFT);
Paragraph prg = new Paragraph("Compare", smallFont);
prg.setAlignment(Element.ALIGN_RIGHT);
doc.add(image1);
doc.add(prg);
doc.add(new Paragraph("__________________________________________________"));
doc.add(new Paragraph("Passed Report"));
doc.add(new Paragraph(" "));
PdfPTable table = new PdfPTable(2);
PdfPCell cell1 = new PdfPCell(new Paragraph("No", headerFont));
cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
cell1.setPaddingBottom(5);
PdfPCell cell2 = new PdfPCell(new Paragraph("Details", headerFont));
cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
cell2.setPaddingBottom(5);
table.addCell(cell1);
table.addCell(cell2);
doc.add(table);
doc.newPage();
doc.close();
file.close();
How do I do if i want to make the pdf is non editable. I've tried to use
PdfEncryptor.encrypt(
new PdfReader(fileName),
new FileOutputStream("HelloWorldProtected.pdf"),
null,
"StrongPassword".getBytes(),
PdfWriter.AllowPrinting,
PdfWriter.STRENGTH128BITS);
but compiler stops here. I waited more than 15 minutes but nothing happen.
I even make file.setreadOnly(), but it doesn't user to save it after edit. It still allow user to edit. User can Save AS the document and replace with the non editable one.
Is there any other way we can make the file as non editable. Please advice.
You might want to use iText for such kind of work if its fine with your project. I cant see any other option as if now. I have personally used iText and it is quite robust. let me know if this helps.
Edit:
Encryption settings
http://viralpatel.net/blogs/password-protect-pdf-itext-java/
http://www.jarfinder.com/index.php/java/info/com.lowagie.text.pdf.interfaces.PdfEncryptionSettings
Try searching more on google and SO
EDIT: The long waiting of 15 min. problem might be of file write permissions on your file path.

Using iText to create PDF

I'm trying to create a PDF using iText and I'm having a great deal of difficulty. In short, what I want to do is:
Read in a template pdf
Make a copy in memory of the template
Draw a table on the copy
Write the copy pdf to an outputstream
So far, it's looking like this
// read in template pdf
InputStream templateStream = getServletContext().getResourceAsStream(labelsTemplate);
PdfReader reader = new PdfReader(templateStream);
// create a table in a new document
Document document = new Document();
PdfCopy copy = new PdfCopy(document, os);
document.open();
PdfPTable table = new PdfPTable(2);
PdfPCell cell;
cell = new PdfPCell(new Phrase("row 1; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 1; cell 2"));
table.addCell(cell);
document.add(table);
Can someone explain how I can make a copy of the template once I've used PdfReader to read it? Is there a way to write the table onto the template copy and not a new document?
For future references, here's what I've done:
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline;filename=\"scheduler-labels.pdf\"");
ServletOutputStream os = response.getOutputStream();
// read in template pdf
InputStream templateStream = getServletContext().getResourceAsStream(labelsTemplate);
PdfReader reader = new PdfReader(templateStream);
// make new pdf document to draw table and output to memory
Document document = new Document(reader.getPageSize(1));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
// write table
document.open();
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(110);
PdfPCell cell;
cell = new PdfPCell(new Phrase("row 1; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 1; cell 2"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 2; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 2; cell 2"));
table.addCell(cell);
document.add(table);
document.close();
// read in newly generated table pdf
PdfReader tableReader = new PdfReader(baos.toByteArray());
ByteArrayOutputStream baosCombined = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(tableReader, baosCombined);
// get a page from the template pdf
PdfImportedPage page = stamper.getImportedPage(reader, 1);
// add to background of table pdf
PdfContentByte background;
background = stamper.getUnderContent(1);
background.addTemplate(page, 0, 0);
stamper.close();
tableReader.close();
reader.close();
// write to servlet output
baosCombined.writeTo(os);
os.flush();
os.close();
As studying the sample referenced in my comment was just what [Tuan] needed, I formulate it as an answer:
The sample Stationery.java from chapter 6 of iText in Action — 2nd Edition essentially shows how to use the contents of a given PDF as background (stationery-like) of a new PDF while filling its foreground with new content.
The central code is as follows:
public class Stationery extends PdfPageEventHelper
{
[...]
public void createPdf(String filename) throws Exception
{
// step 1
Document document = new Document(PageSize.A4, 36, 36, 72, 36);
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
useStationary(writer);
// step 3
document.open();
// step 4
[... add content to PDF ...]
// step 5
document.close();
}
[...]
public void useStationary(PdfWriter writer) throws IOException
{
writer.setPageEvent(this);
PdfReader reader = new PdfReader(STATIONERY);
page = writer.getImportedPage(reader, 1);
}
public void onEndPage(PdfWriter writer, Document document)
{
writer.getDirectContentUnder().addTemplate(page, 0, 0);
}
[...]
}
As implicit close() calls have been removed more and more recently, the PdfReader reader instantiated in useStationary nowerdays should be stored in some variable of Stationery and closed after createPdf has executed.

Categories