i am creating one pdf output using iText 5.0.5.
I am reading the data in the form of bytes from database and then adding it to the document using HTMLWorker to generate pdf.
BUt i am not able to add header on each paage for that pdf document.
please help.
1) The latest iText is 5.0.6.
2) To create a page header and footer, you need to use the PdfPageEvent interface. This is generally done by deriving from PdfPageEventHelper, and overriding just the methods you need.
In the PdfPageEvent, you must draw to the PDF using a PdfContentByte. The good news is that you can use a ColumnText to add aligned text into a given bounding box, and it'll handle line breaks for you.
public class HeaderFooterPageEvent extends PdfPageEventHelper {
private String headerStr, footerStr;
private Rectangle hBox, fBox;
public HeaderFooterPageEvent(String hStr, Rectangle _hBox, String fString, Rectangle _fBox) {
headerStr = hStr;
hBox = _hBox;
footerStr = fStr;
fBox = _fBox;
}
public onEndPage(PdfWriter writer, Document doc) {
// draw the header text.
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_RIGHT, headerStr, hBox.getRight(), hBox.getTop, 0);
// draw the footer text.
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_RIGHT, footerStr, fBox.getRight(), fBox.getTop, 0);
}
}
This won't work so well if your header & footer are in HTML. For that you'll have to do some round-about hackery.
1) Create a new Document/PdfWriter with page margins matching the size (height & width) of your header.
2) Render all the header HTML into that page.
3) save the pdf.
4) Import that PDF page into your other document, and draw it thusly:
public onEndPage(PdfWriter writer, Document doc) {
PdfReader reader = new PdfReader(headerPDFPath);
PdfImportedPage headerPageImport = writer.getImportedPage(reader, 1); // 1 -> first page
PdfContentByte cb = writer.getDirectContent();
cb.addTemplate(headerPageImport, hBox.bottom(), hBox.left());
}
Related
Yes, it seems a weird question, but I was not able to render a colored text in PDFBox.
Usually the code for generating text looks like that:
//create some document and page...
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
//defined some font
PDFont helveticaRegular = PDType1Font.HELVETICA;
//content stream for writing the text
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
contentStream.setFont(helveticaRegular, 16);
contentStream.setStrokingColor(1f,0.5f,0.2f);
contentStream.newLineAtOffset(64, page.getMediaBox().getUpperRightY() - 64);
contentStream.showText("The hopefully colored text");
contentStream.endText();
//closing the stream
contentStream.close();
[...] //code for saving and closing the document. Nothing special
Interestingly the setStrokingColor is the only method accepting colors on the stream.
So I thought this is the way to color something in PDFBox.
BUT: I'm not getting any color to the text. So I guess this is a method for other types of content.
Does anybody know how to achieve a colored text in PDFBox?
You use
contentStream.setStrokingColor(1f,0.5f,0.2f);
But in PDFs text by default is not drawn by stroking a path but by filling it. Thus, you should try
contentStream.setNonStrokingColor(1f,0.5f,0.2f);
instead.
I am working on migration from iText 5 to iText 7. I have iText 5 code as below. I am not sure which alternative from iText 7(may be Canvas) should be used to implement PdfContentByte and PdfTemplate.
produce(com.itextpdf.text.pdf.PdfWriter writer, width, height, ...) {
com.itextpdf.text.pdf.PdfContentByte cb = writer.getDirectContent();
com.itextpdf.text.pdf.PdfTemplate template = cb.createTemplate(width, height);
try
{
template.beginText();
template.setFontAndSize(font, fontSize);
template.setTextMatrix(0, 0);
template.showTextAligned(com.itextpdf.text.pdf.PdfContentByte.ALIGN_CENTER, value, width/2, linePos, 0);
template.endText();
}
catch(Exception e)
{
}
cb.addTemplate(template, left, areaTop - top - height);
}
Can anyone please suggest the correct alternative to achieve this?
Thanks!
The PdfContentByte instance returned by iText 5 PdfWriter.getDirectContent() essentially is the content of the current page plus a number of methods to add more content.
An iText 5 PdfTemplate essentially is a PDF form XObject and its content plus a number of methods to add more content.
In iText 7 there are dedicated classes PdfPage and PdfFormXObject for pages and PDF form XObjects respectively, and there are classes PdfCanvas and Canvas providing low level and high level methods respectively to add more content to pages or form XObjects.
Thus, the following corresponds approximately to your iText 5 code:
PdfDocument pdfDoc = ...
PdfPage page = ... // e.g. pdfDoc.addNewPage();
PdfFormXObject pdfFormXObject = new PdfFormXObject(new Rectangle(width, height));
try (Canvas canvas = new Canvas(pdfFormXObject, pdfDoc)) {
canvas.showTextAligned(value, width/2, linePos, TextAlignment.CENTER);
}
PdfCanvas pdfCanvas = new PdfCanvas(page);
pdfCanvas.addXObject(pdfFormXObject, left, bottom);
(From AddCanvasToDocument test testAddCanvasForManjushaDC)
I say "approximately" because the architecture of iText 5 and iText 7 differ, so there is not necessarily an exact correspondence, in particular best practices in iText 5 don't directly translate to best practices in iText 7.
I am trying to read one PDF and copy its data into another PDF. The first PDF contains some text and images and I wish to write an image in the second PDF exactly where the text ends(which is basically the end of the PDF file). RIght now it just prints at the top. How can I make this change?
PdfReader reader = null;
reader = new PdfReader(Var.input);
Document document=new Document();
PdfWriter writer = null;
writer = PdfWriter.getInstance(document,new FileOutputStream(Var.output));
PdfImportedPage page = writer.getImportedPage(reader, 1);
reader.close();
document.open();
PdfContentByte cb = writer.getDirectContent();
// Copy first page of existing PDF into output PDF
document.newPage();
cb.addTemplate(page, 0, 0);
// Add your new data / text here
Image image = null;
image = Image.getInstance (Var.qr);
document.add(image);
document.close();
Try this:
First get the location/co-ords of where the image needs to go, then simply add the second line from below to your code so the image is inserted at that location "X, Y"
Image image = Image.getInstance(String RESOURCE);
image.setAbsolutePosition(X, Y);
writer.getDirectContent().addImage(image);
Take a look here for some examples in iText 5: https://itextpdf.com/en/resources/examples/itext-5-legacy/chapter-3-adding-content-absolute-positions
You should use a PdfStamper instead of a PdfWriter with imported pages. Your approach throws away all interactive contents. You can use sorifiend's idea there, too.
To determine where the text on the given page ends, have a look at the iText in Action, 2nd edition example ShowTextMargins which parses a PDF and ads a rectangle showing the text margin.
I was wondering if it was possible to mark strings in pdf with different color or underline them while looping through the pdf document ?
It's possible on creating a document. Just use different chunks to set the style. Here's an example:
Document document = new Document();
PdfWriter.getInstance(document, outputStream);
document.open();
document.add(new Chunk("This word is "));
Chunk underlined = new Chunk("underlined");
underlined.setUnderline(1.0f, -1.0f); //We can customize thickness and position of underline
document.add(underlined);
document.add(new Chunk(". And this phrase has "));
Chunk background = new Chunk("yellow background.");
background.setBackground(BaseColor.YELLOW);
document.add(background);
document.add(Chunk.NEWLINE);
document.close();
However, it's almost impossible to edit an existing PDF document. The author of iText writes in his book:
In a PDF document, every character or glyph on a PDF page has its
fixed position, regardless of the application that’s used to view the
document. This is an advantage, but it also comes with a disadvantage.
Suppose you want to replace the word “edit” with the word “manipulate”
in a sentence, you’d have to reflow the text. You’d have to reposition
all the characters that follow that word. Maybe you’d even have to
move a portion of the text to the next page. That’s not trivial, if
not impossible.
If you want to “edit” a PDF, it’s advised that you change the original
source of the document and remake the PDF.
Aspose.PDF APIs support to create new PDF document and manipulate existing PDF documents without Adobe Acrobat dependency. You can search and add Highlight Annotation to mark PDF text.
REST API Solution using Aspose.PDF Cloud SDK for Java:
// For complete examples and data files, please go to https://github.com/aspose-pdf-cloud/aspose-pdf-cloud-java
String name = "02_pages.pdf";
String folder="Temp";
String remotePath=folder+"/"+name;
// File to upload
File file = new File("C:/Temp/"+name);
// Storage name is default storage
String storage = null;
// Get App Key and App SID from https://dashboard.aspose.cloud/
PdfApi pdfApi = new PdfApi("xxxxxxxxxxxxxxxxxxxx", "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx");
//Upload file to cloud storage
pdfApi.uploadFile(remotePath,file,storage);
//Text Position
Rectangle rect = new Rectangle().LLX(259.27580539703365).LLY(743.4707997894287).URX(332.26148873138425).URY(765.5148007965088);
List<AnnotationFlags> flags = new ArrayList<>();
flags.add(AnnotationFlags.DEFAULT);
HighlightAnnotation annotation = new HighlightAnnotation();
annotation.setName("Name Updated");
annotation.rect(rect);
annotation.setFlags(flags);
annotation.setHorizontalAlignment(HorizontalAlignment.CENTER);
annotation.setRichText("Rich Text Updated");
annotation.setSubject("Subj Updated");
annotation.setPageIndex(1);
annotation.setZindex(1);
annotation.setTitle("Title Updated");
annotation.setModified("02/02/2018 00:00:00.000 AM");
List<HighlightAnnotation> annotations = new ArrayList<>();
annotations.add(annotation);
//Add Highlight Annotation to the PDF document
AsposeResponse response = pdfApi.postPageHighlightAnnotations(name,1, annotations, storage, folder);
//Download annotated PDF file from Cloud Storage
File downloadResponse = pdfApi.downloadFile(remotePath, null, null);
File dest = new File("C:/Temp/HighlightAnnotation.pdf");
Files.copy(downloadResponse.toPath(), dest.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
System.out.println("Completed......");
On-Premise Solution using Aspose.PDF for Java:
// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.Pdf-for-Java
// Instantiate Document object
Document document = new Document("C:/Temp/Test.pdf");
// Create TextFragment Absorber instance to search particular text fragment
TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber("Estoque");
// Iterate through pages of PDF document
for (int i = 1; i <= document.getPages().size(); i++) {
// Get first page of PDF document
Page page = document.getPages().get_Item(i);
page.accept(textFragmentAbsorber);
}
// Create a collection of Absorbed text
TextFragmentCollection textFragmentCollection = textFragmentAbsorber.getTextFragments();
// Iterate on above collection
for (int j = 1; j <= textFragmentCollection.size(); j++) {
TextFragment textFragment = textFragmentCollection.get_Item(j);
// Get rectangular dimensions of TextFragment object
Rectangle rect = new Rectangle((float) textFragment.getPosition().getXIndent(), (float) textFragment.getPosition().getYIndent(), (float) textFragment.getPosition().getXIndent() + (float) textFragment.getRectangle().getWidth(), (float) textFragment.getPosition().getYIndent() + (float) textFragment.getRectangle().getHeight());
// Instantiate HighLight Annotation instance
HighlightAnnotation highLight = new HighlightAnnotation(textFragment.getPage(), rect);
// Set opacity for annotation
highLight.setOpacity(.80);
// Set the color of annotation
highLight.setColor(Color.getYellow());
// Add annotation to annotations collection of TextFragment
textFragment.getPage().getAnnotations().add(highLight);
}
// Save updated document
document.save("C:/Temp/HighLight.pdf");
P.S: I work as support/evangelist developer at Aspose.
I am trying to read one PDF and copy its data into another PDF. The first PDF contains some text and images and I wish to write an image in the second PDF exactly where the text ends(which is basically the end of the PDF file). RIght now it just prints at the top. How can I make this change?
PdfReader reader = null;
reader = new PdfReader(Var.input);
Document document=new Document();
PdfWriter writer = null;
writer = PdfWriter.getInstance(document,new FileOutputStream(Var.output));
PdfImportedPage page = writer.getImportedPage(reader, 1);
reader.close();
document.open();
PdfContentByte cb = writer.getDirectContent();
// Copy first page of existing PDF into output PDF
document.newPage();
cb.addTemplate(page, 0, 0);
// Add your new data / text here
Image image = null;
image = Image.getInstance (Var.qr);
document.add(image);
document.close();
Try this:
First get the location/co-ords of where the image needs to go, then simply add the second line from below to your code so the image is inserted at that location "X, Y"
Image image = Image.getInstance(String RESOURCE);
image.setAbsolutePosition(X, Y);
writer.getDirectContent().addImage(image);
Take a look here for some examples in iText 5: https://itextpdf.com/en/resources/examples/itext-5-legacy/chapter-3-adding-content-absolute-positions
You should use a PdfStamper instead of a PdfWriter with imported pages. Your approach throws away all interactive contents. You can use sorifiend's idea there, too.
To determine where the text on the given page ends, have a look at the iText in Action, 2nd edition example ShowTextMargins which parses a PDF and ads a rectangle showing the text margin.