i want to generate a pdf label for CD using java itext. i have drawn the circle but i am unable to set image and multiple paragraphs inside the circle.
Below is the code snippet.code snippet
String printingPath = "CD_label.pdf";
Document document = new Document(new Rectangle(PageSize.A4));
PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream(printingPath));
document.open();
PdfContentByte cb = writer.getDirectContent();
cb.setRGBColorFill(0xFF, 0xFF, 0xFF);
BaseColor colorval = new BaseColor(102,178,255);
cb.setColorStroke(colorval);
cb.circle(300.0f, 650.0f, 150.0f);
cb.circle(300.0f, 650.0f, 20.0f);
cb.stroke();
//cb.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA,BaseFont.CP1257,BaseFont.EMBEDDED), 10);
//cb.beginText();
//cb.resetRGBColorStroke();
//cb.setTextMatrix(320, 420);
//cb.showText("Text inside cd");
// ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,new Phrase("Hello itext"),50, 700, 0); cb.endText();
Image img = Image.getInstance("Symbol.png");
img.setAbsolutePosition(270f, 740f);
img.scaleAbsolute(60, 34);
document.close();
Why don't you see your text?
You set the fill color to WHITE:
cb.setRGBColorFill(0xFF, 0xFF, 0xFF);
Text (usually) is drawn by filling glyph outlines defined in some font. Thus, your uncommented text drawing code
cb.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA,BaseFont.CP1257,BaseFont.EMBEDDED), 10);
cb.beginText();
cb.resetRGBColorStroke();
cb.setTextMatrix(320, 420);
cb.showText("Text inside cd");
ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,new Phrase("Hello itext"),50, 700, 0);
cb.endText();
does draw text... in WHITE on WHITE...
If you remove that cb.setRGBColorFill instruction (or select a clearly different fill color), you'll see your text:
(The point (320, 420) clearly is outside a circle with center (300, 650) and radius 150, consequentially so is your "Text inside cd" text...)
Another issue: ColumnText.showTextAligned starts its own text object, so to create a valid PDF you must move it after your cb.endText():
cb.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA,BaseFont.CP1257,BaseFont.EMBEDDED), 10);
cb.beginText();
cb.resetRGBColorStroke();
cb.setTextMatrix(320, 420);
cb.showText("Text inside cd");
cb.endText();
ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,new Phrase("Hello itext"),50, 700, 0);
Why don't you see your image?
Because you don't add it!
If you add it to your PdfContentByte cb
Image img = Image.getInstance("Symbol.png");
img.setAbsolutePosition(270f, 740f);
img.scaleAbsolute(60, 34);
cb.addImage(img);
the result becomes like this:
(I obviously don't have your image, so I use a simple example image instead.)
Related
I'm using iText to create barcodes on a PDF with the same format as this one:
The problem is the the left number, the first zero digits must be smaller, while the rest of the numbers must also be bold. "T.T.C." also has to be even smaller (it doesn't have to be on another line).
I was able to rotate the number with the following code:
String price = "23000 T.T.C.";
PdfContentByte cb = docWriter.getDirectContent();
PdfTemplate textTemplate = cb.createTemplate(50, 50);
ColumnText columnText = new ColumnText(textTemplate);
columnText.setSimpleColumn(0, 0, 50, 50);
columnText.addElement(new Paragraph(price));
columnText.go();
Image image;
image = Image.getInstance(textTemplate);
image.setAlignment(Image.MIDDLE);
image.setRotationDegrees(90);
doc.add(image);
The problem is that I cannot find a way online to change the font of certain characters of the String price when it is printed on the PDF.
I have created a small Proof of Concept that results in a PDF that looks like this:
As you can see, it has text in different sizes and styles. It also has a bar code that is rotated.
Take a look at the RotatedText example:
public void createPdf(String dest) throws IOException, DocumentException {
// step 1
Document document = new Document(new Rectangle(60, 120), 5, 5, 5, 5);
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
// step 3
document.open();
// step 4
PdfContentByte canvas = writer.getDirectContent();
Font big_bold = new Font(FontFamily.HELVETICA, 12, Font.BOLD);
Font small_bold = new Font(FontFamily.HELVETICA, 6, Font.BOLD);
Font regular = new Font(FontFamily.HELVETICA, 6);
Paragraph p1 = new Paragraph();
p1.add(new Chunk("23", big_bold));
p1.add(new Chunk("000", small_bold));
document.add(p1);
Paragraph p2 = new Paragraph("T.T.C.", regular);
p2.setAlignment(Element.ALIGN_RIGHT);
document.add(p2);
BarcodeEAN barcode = new BarcodeEAN();
barcode.setCodeType(Barcode.EAN8);
barcode.setCode("12345678");
Rectangle rect = barcode.getBarcodeSize();
PdfTemplate template = canvas.createTemplate(rect.getWidth(), rect.getHeight() + 10);
ColumnText.showTextAligned(template, Element.ALIGN_LEFT,
new Phrase("DARK GRAY", regular), 0, rect.getHeight() + 2, 0);
barcode.placeBarcode(template, BaseColor.BLACK, BaseColor.BLACK);
Image image = Image.getInstance(template);
image.setRotationDegrees(90);
document.add(image);
Paragraph p3 = new Paragraph("SMALL", regular);
p3.setAlignment(Element.ALIGN_CENTER);
document.add(p3);
// step 5
document.close();
}
This example solves all of your issues:
You want a Paragraph to use different fonts: compose a Paragraph using different Chunk objects.
You want to add extra text on top of a bar code: add the bar code to a PdfTemplate and add the extra text using ColumnText.showTextAligned() (not that you can also compose a Phrase using different Chunk objects if you need more than one font in that extra text).
You want to rotate the bar code: wrap the PdfTemplate inside an Image object and rotate the image.
You can check the result: rotated_text.pdf
I hope this helps.
Im using PdfTemplate.createTemplate with following code,
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:\\Report.pdf"));
document.open();
document.add(new Paragraph("A Hello World PDF new TEXT document."));
PdfContentByte contentByte = writer.getDirectContent();
PdfTemplate template = contentByte.createTemplate(50,50);
template.beginText();
BaseFont bf=BaseFont.createFont(BaseFont.HELVETICA,BaseFont.CP1252,BaseFont.NOT_EMBEDDED);
template.setFontAndSize(bf,10);
template.setTextMatrix(100,100);
template.showText("Text at the position 100,100 (relative to the template!)");
template.endText();
contentByte.addTemplate(template, 10, 100);
document.close();
But the text is not visible in the pdf
When you do this:
PdfTemplate template = contentByte.createTemplate(50,50);
You create a canvas that measures 50 user units by 50 user units. All the content that you add to this canvas will be clipped to that size.
When you do this:
template.setTextMatrix(100,100);
You deliberately move outside the visible area of the small square with lower-left corner 0,0 and upper-right corner 50,50. Whatever you add in this area will be clipped.
You are correct when you say: the text is not visible in the pdf. If the text were visible, you would have found a bug.
I am combining 2 strings to Paragraph this way,
String str2="";
String str1="";
ColumnText ct = new ColumnText(cb);
ct.setSimpleColumn(36, 600, 600, 800);
ct.addElement(new Paragraph(str1 + str2));
int status1 = ct.go();
The problem is I am getting same font color for both str1 & str2.
I want to have different font color and size for str1 & str2..
How Can i do that on ColumnText/Paragraph?
Can someone help me in this...
When you combine text into a Paragraph like this:
Paragraph p = new Paragraph("abc" + "def");
You implicitly tell iText that "abc" and "def" should be rendered using the same (default) font. As you probably know, a Paragraph is a collection of Chunk objects. In iText, a Chunk is like an atomic part of text in the sense that all the text in a Chunk has the same font, font size, font color, etc...
If you want to create a Paragraph with different font colors, you need to compose your Paragraph using different Chunk objects. This is shown in the ColoredText example:
Font red = new Font(FontFamily.HELVETICA, 12, Font.NORMAL, BaseColor.RED);
Chunk redText = new Chunk("This text is red. ", red);
Font blue = new Font(FontFamily.HELVETICA, 12, Font.BOLD, BaseColor.BLUE);
Chunk blueText = new Chunk("This text is blue and bold. ", blue);
Font green = new Font(FontFamily.HELVETICA, 12, Font.ITALIC, BaseColor.GREEN);
Chunk greenText = new Chunk("This text is green and italic. ", green);
Paragraph p1 = new Paragraph(redText);
document.add(p1);
Paragraph p2 = new Paragraph();
p2.add(blueText);
p2.add(greenText);
document.add(p2);
In this example, we create two paragraphs. One with a single Chunk in red. Another one that contains two Chunks with a different color.
In your question, you refer to ColumnText. The next code snippet uses p1 and p2 in a ColumnText context:
ColumnText ct = new ColumnText(writer.getDirectContent());
ct.setSimpleColumn(new Rectangle(36, 600, 144, 760));
ct.addElement(p1);
ct.addElement(p2);
ct.go();
As a result, the paragraphs are added twice: once positioned by iText, once positioned by ourselves by defining coordinates using a Rectangle:
I'm trying to set the background color of my QR Code using iText into a transparent background, however it does not work. Shows only white bars and black background.
What i have done so far:
My Code Snippet:
PdfContentByte cb = writer.getDirectContent();
BarcodeQRCode qrcode = new BarcodeQRCode("sample message on qr", 100, 100, null);
java.awt.Image qrImage = qrcode.createAwtImage(Color.WHITE,new Color(0, 0, 0, 0));
Image finalImage = Image.getInstance(writer, qrImage, 1);
finalImage.setAbsolutePosition(positionX, positionY);
cb.addImage(finalImage);
I have already generated my QR code and produced a PDF, however, when using
qrcode.createAwtImage(Color.WHITE,new Color(0, 0, 0, 0));
It does not produce an alpha background, instead it only shows a black background color.
I have also tried:
java.awt.Image qrImage =
qrcode.createAwtImage(Color.WHITE,Color.OPAQUE);
But obviously, my arguments are incorrect.
Help will be most appreciated, i've been working on this for a day now.
I have also tried Graphics, Graphics2g, converting it into BufferedImage.
Changing the assignment of finalImage to the following works:
Image finalImage = Image.getInstance(qrImage, null)
I don't know why using the getInstance method that takes a PdfWriter as first argument ruins the transparency, though...
I would solve this problem like this:
BarcodeQRCode qrcode = new BarcodeQRCode("sample message on qr", 100, 100, null);
Image image = qrcode.getImage();
Image mask = qrcode.getImage();
mask.makeMask();
image.setImageMask(mask);
document.add(image);
There may be an AWT solution too, but I'm more familiar with native PDF solutions than with using an AWT workaround.
I am trying to complete an example that draws graphics and writes them to PDF, but I keep getting errors that the PDF has no pages. if I add something simple with document.add() after opening it works fine, I just never see the graphics. Here is my code:
Document document = new Document();
PdfWriter writer = new PdfWriter();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition",
" attachment; filename=\"Design.pdf\"");
writer = PdfWriter.getInstance(document, response.getOutputStream());
document.open();
PdfContentByte cb = writer.getDirectContent();
Graphics2D graphics2D = cb.createGraphics(36, 54);
graphics2D.drawString("Hello World", 36, 54);
graphics2D.dispose();
document.close();
Do I have to do something else to add the graphic to the document or is my syntax incorrect?
I am not an expert in IText, but last week I tryed to draw some circles with it. So this is what I have noticed during my tests:
If you draw graphics, you must (or lets say I must when I tryed it) "wrap" the graphics commands in a section starting with saveState() and ending with restoreState(), es well as I needed to invoke fillStroke() -- if I do not invoke fillStroke() then nothing was drawn.
Example
private void circle(float x, float y, PdfWriter writer) {
PdfContentByte canvas = writer.getDirectContent();
canvas.saveState();
canvas.setColorStroke(GrayColor.BLACK);
canvas.setColorFill(GrayColor.BLACK);
canvas.circle(x, y, 2);
canvas.fillStroke();
canvas.restoreState();
}
#Test
public void testPossition() throws DocumentException, IOException {
OutputStream outputStream = FileUtil.openOutputStream("testPosition.pdf");
//this is my personal file util, but it does not anything more
//then creating a file and opening the file stream.
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
markPosition(100, 100, writer);
document.add(new Paragraph("Total: 595 x 842 -- 72pt (1 inch)"));
document.close();
outputStream.flush();
outputStream.close();
}
private void markPosition(float x, float y, PdfWriter writer)
throws DocumentException, IOException {
placeChunck("x: " + x + " y: " + y, x, y, writer);
circle(x, y, writer);
}
private void placeChunck(String text, float x, float y, PdfWriter writer)
throws DocumentException, IOException {
PdfContentByte canvas = writer.getDirectContent();
BaseFont font = BaseFont.createFont(BaseFont.HELVETICA,
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
canvas.saveState();
canvas.beginText();
canvas.moveText(x, y);
canvas.setFontAndSize(font, 9);
canvas.showText(text);
canvas.endText();
canvas.restoreState();
}
But PdfContentByte (canvas) has much more functions, for example rectangle.
Does Document doc = new Document(PageSize.A4);
make any difference?
I don't know if you need to add a Paragraph like this:
doc.add(new Paragraph(...));
Also we use doc.add(ImgRaw); to add images.
Without going too far into it, I think your general approach is fine. I think what might be happening here is that the Graphics2D origin is different from the PDF origin, so maybe you need to change the call to drawString() so it uses 0,0 as the location??
I think the problem is that directcontent writes directly to the page object. This way you can add backgrounds or backdrop images. Try adding a new page (doc.newPage()) before writing to the directcontent.
Have you tried drawing operations on the g2d object that just use shapes instead of text? That would eliminate the possibility of something odd going on with font selection or something like that.
iText In Action Chapter 12 has exactly what you are looking for - it really is worth picking up. Preview of Chapter 12
I just put together the following unit test against the latest HEAD of iText:
Document document = new Document();
PdfWriter writer = new PdfWriter();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
writer = PdfWriter.getInstance(document, baos);
document.open();
PdfContentByte cb = writer.getDirectContent();
Graphics2D graphics2D = cb.createGraphics(36, 54);
graphics2D.setColor(Color.black);
graphics2D.drawRect(0, 0, 18, 27);
Font font = new Font("Serif", Font.PLAIN, 10);
graphics2D.setFont(font);
graphics2D.drawString("Yo Adrienne", 0, 54);
graphics2D.dispose();
document.close();
TestResourceUtils.openBytesAsPdf(baos.toByteArray());
And it works fine - I get a small black rectangle in the lower left hand corner of the page, plus text. Note that I am specifying X=0 for my drawString method (you were specifying 36 which causes the text to render outside of the image bounds). Note also that I explicitly specified a font - if I leave that out, it still renders, but it's usually a great idea to not trust the defaults for that sort of thing. Finally, I explicitly set the foreground color - again, not truly necessary, but trusting defaults can be scary.
So I'd have to say that the core issue here was the placement of the text at x=36.
In none of my tests was I able to create an error saying that the PDF has no pages - can you post the stack trace of the exception you are getting?
I can't imagine that adding a paragraph to the document makes any difference to this (that's the sort of bug that would have gotten taken care of long, long ago)