PDF generated by iText -> text missing after saving PDF to local drive - java

I am producing a PDF file in a HttpServlet with itText. Adding a Text on the canvas. If I open the url the PDF is shown correctly with the text. Also if I print it direclty from the browser, the text is visible on the printed paper. If I download the PDF on the other hand, the text not shown anymore (The image still is). The PDF can be viewed here: http://www.vegantastic.de/pdfTest
My code looks like this:
Document document = new Document();
// step 2
ByteArrayOutputStream baos = new ByteArrayOutputStream();
private PdfWriter writer = PdfWriter.getInstance(document, baos);
// step 3
document.open();
Font helvetica = new Font(FontFamily.TIMES_ROMAN, 12);
BaseFont bf_helv = helvetica.getCalculatedBaseFont(false);
PdfContentByte canvas = writer.getDirectContentUnder();
canvas.setFontAndSize(bf_helv, 12);
canvas.showTextAligned(Element.ALIGN_LEFT, "Test TEXT - Why is it missing after download?", 100, 800,0);
document.close();
// setting some response headers
response.setHeader("Expires", "0");
response.setHeader("Cache-Control",
"must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
// setting the content type
response.setContentType("application/pdf");
// the contentlength
response.setContentLength(baos.size());
// write ByteArrayOutputStream to the ServletOutputStream
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
Is there any reasonable explanation for that or this this some kind of bug? Any way to resove this?

You aren't adding the text correctly. The PDF you are creating contains a serious syntax error. Some PDF viewers will ignore this syntax error and show the text anyway (which may be why you can print the PDF from a browser); others will not show anything because you are showing text outside a text object.
There are different ways to add text at an absolute position. One way is to create a text object yourself:
canvas.beginText();
canvas.setFontAndSize(bf_helv, 12);
canvas.showTextAligned(Element.ALIGN_LEFT, "Test TEXT - Why is it missing after download?", 100, 800,0);
canvas.endText();
In this case, you need to manually begin and end the text object. That's missing in your code.
Another way, is to have iText create the text object:
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
new Phrase("Test TEXT - Why is it missing after download?", new Font(bf_helv, 12)),
100, 800,0);
This single line is the equivalent of the four lines above.
Important note:
You are using this canvas:
PdfContentByte canvas = writer.getDirectContentUnder();
However: if your document contains opaque elements (an image, a colored rectangle,...), then whatever text you're adding will be covered by these opaque elements. Are you sure you don't want:
PdfContentByte canvas = writer.getDirectContent();

Try this
PdfContentByte canvas = writer.getDirectContentUnder();
canvas.saveState();
canvas.beginText();
canvas.setFontAndSize(bf_helv, 12);
canvas.showTextAligned(Element.ALIGN_LEFT, "Test TEXT - Why is it missing after download?", 100, 800,0);
canvas.endText();
canvas.restoreState();

Related

How to render Colored Text in Apache PDFBox

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.

iText add image to pdf - setAbsolutePosition [duplicate]

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.

Image width and height not getting set while using XMLWorkerHelper in Itext

Hi i'm trying to add an image to my pdf. It's getting added but the problem is i'm not able to set user defined width and height. I'm using XMLWorkerHelper to convert the HTML code and write it in PDF.
try {
String image="<img alt=\"Not Loading\" src=\"C:\\Users\\sathesh_S\\Desktop\\Itext\\football.jpg\" style=\"width: 50px; height: 75px\" />";
OutputStream file = new FileOutputStream(new File("C:\\Test.pdf"));
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, file);
document.open();
InputStream is = new ByteArrayInputStream(image.getBytes());
XMLWorkerHelper.getInstance().parseXHtml(writer, document, is);
document.close();
file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
Here i'm setting the width and height as 50 and 75 pixel. But the original image is getting added to the PDF. How can i rectify this.
XMLWorker doesn't support width and height css properties on images[1].
The default image tag processor (ie com.itextpdf.tool.xml.html.Image) uses width/height attributes of tag. So there are two solutions:
write your own image tag processor (and probably CssAplier) for images (consult librabry source code for details), or simply:
use height and width attributes of img tag, for example:
String image="<img src=\"football.jpg\" width=\"50px\" height=\"75px\"/>";
Second solution is much easier and should be enough in most cases.
[1] http://demo.itextsupport.com/xmlworker/itextdoc/CSS-conformance-list.htm

Image positioning in iText - Java

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.

Exporting SWT Image into PDF using Java iText API

I have a an SWT image I want to export this image into a pdf file using iText API.
I have tried saving this image on the disk and then using the path of image to export
it to the pdf, this takes lots of time to generate the pdf.
I have also tried converting the SWT image into AWT image and then exporting it into the
pdf, this approach takes even more time to generate pdf.
Another approach I have been trying is to convert the raw data of image into
jpeg byteArrayOutputStream using ImageLoader Object as shown below :
ImageLoader tempLoader = new ImageLoader();
tempLoader.data = new ImageData[] {
image.getImageData()
};
ByteArrayOutputStream bos = new ByteArrayOutputStream();
tempLoader.save(bos, SWT.IMAGE_JPEG);
Now I am using this ByteArrayOutputStream as input to
OutputStream outStream = new FileOutputStream(selectedPathAndName);
Document document = new Document();
document.setMargins(0,0,0,0);
document.setPageSize(new Rectangle(0,0,width,height));
PdfWriter.getInstance(document, outStream);
document.open();
com.itextpdf.text.Image pdfImage = com.itextpdf.text.Image.getInstance(bos.toByteArray());
document.add(pdfImage);
document.close();
This generates pdf files with the width and height I have set, but the page seems to be empty.
Any suggestions or any other approach is most welcome.
Thank you,
It looks your page sizes are zero, try setting them to something like A4 in the constructor.
Document document = new Document(PageSize.A4, 50, 50, 50, 50);

Categories