I am creating an image with Barcode128 and am trying to place it in PDf file, but it is going over the page in IE:
if the order number (ETIMS...) is around 20 characters it print normal size barcode.
I tried different values for:
code128.setBarHeight();
code128.setX();
Image.setWidthPercentage();
Image.scaleAbsolute();
Image.scaleToFit();
Image.scalePercent();
But nothing works, it's like something else sets width and height and nothing I do changes it.
parts of the code where this is happening:
float[] widths1 = { 10f, 4f };
PdfPTable tableReqNumberBarcode;
Paragraph p1 = new Paragraph();
PdfPCell cellReqNumberBarcode;
while (iteratorPDFReader.hasNext())
{
tableReqNumberBarcode = new PdfPTable(widths1);
cellReqNumberBarcode = new PdfPCell(p1);
cellReqNumberBarcode.setBorder(Rectangle.NO_BORDER);
}
page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
cb.addTemplate(page, 1.15f, 0, 0, 1.15f, 70, 0);
Barcode128 code128 = new Barcode128();
code128.setCode(orderNumber);
code128.setFont(null); //remove printed text under the barcode
code128.setBarHeight(80f);
code128.setX(1f);
Image myImage = code128.createImageWithBarcode(cb, null, null);
cellReqNumberBarcode.addElement(myImage);
tableReqNumberBarcode.addCell(cellReqNumberBarcode);
document.add(tableReqNumberBarcode);
The code128.setX(1f); sets the width of the narrowest bar. Set it to a lower value to shrink the barcode.
I solved it by adding setX and setBarHeight()
Barcode128 code128 = new Barcode128();
code128.setCode(GetReqNumByJobNumber(childJobNumbers[labelNumber], eb, ssb));
code128.setFont(null); //null removes the printed text under the barcode
code128.setX(0.6f);
code128.setBarHeight(22);
Image myImage = code128.createImageWithBarcode(cb, null, null);
myImage.setAbsolutePosition(10,700);
myImage.scalePercent(125);
Related
I want to add a variable string to a fixed drawing rectangle using iText 7 - this is a sample code:
try (PdfWriter writer = new PdfWriter("test.pdf");
PdfDocument pdf = new PdfDocument(writer)) {
// Create a page
PdfPage currentPage = pdf.addNewPage(PageSize.A4);
// Create the position rectangle
Rectangle rect = new Rectangle(
75f,
currentPage.getPageSize().getHeight() - 315f - 22f,
75f,
22f
);
// Create the font
PdfFont currentFont = PdfFontFactory.createFont(
"Helvetica",
"Cp1252"
);
// Create the paragraph
Paragraph p = (new Paragraph("Some longer value"))
.setFont(currentFont)
.setFontSize(12f)
.setWidth(75f)
.setHeight(22f)
.setTextAlignment(TextAlignment.LEFT);
// Add the paragraph
(new Canvas(new PdfCanvas(currentPage), pdf, rect))
.add((BlockElement)p);
}
When I run this code, I'll get this exception when the last line is being executed:
Exception in thread "main" java.lang.IllegalArgumentException: fromIndex(0) > toIndex(-1)
at java.base/java.util.AbstractList.subListRangeCheck(AbstractList.java:509)
at java.base/java.util.ArrayList.subList(ArrayList.java:1138)
at com.itextpdf.layout.renderer.ParagraphRenderer.layout(ParagraphRenderer.java:235)
at com.itextpdf.layout.renderer.RootRenderer.addChild(RootRenderer.java:84)
at com.itextpdf.layout.renderer.CanvasRenderer.addChild(CanvasRenderer.java:86)
at com.itextpdf.layout.RootElement.add(RootElement.java:98)
at itext.bug.reproduce.ITextBugReproduce.main(ITextBugReproduce.java:50)
When I replace Some longer value with test, everything works. So it seems adding an overlength string to a small drawing area fails.
The problem is: In real know only the destination drawing area, but I don't know the string which is going to be processed. This leads to my question: How can I draw even an overlength string to the PDF without pre-measuring etc.?
Update: When I expand the paragraph dimensions, I still have the same exception, so I assume its not a problem with the paragraph, but with the canvas which I use to restrict drawing to the destination rectangle (for not overwriting any contents outside of the rectangle).
With a newer iText 7 version (I used 7.0.1 before) and a slightly different code it's working now:
BasicConfigurator.configure();// Satisfy the logger
try (PdfWriter writer = new PdfWriter("test.pdf");
PdfDocument pdf = new PdfDocument(writer)) {
// Create a page
PdfPage currentPage = pdf.addNewPage(PageSize.A4);
// Create the position rectangle
Rectangle rect = new Rectangle(
75f,
currentPage.getPageSize().getHeight() - 315f - 22f,
75f,
22f
);
// Create the font
PdfFont currentFont = PdfFontFactory.createFont(
"Helvetica",
"Cp1252"
);
// Create the paragraph
Paragraph p = (new Paragraph("Some longer value"))
.setFont(currentFont)
.setFontSize(12f)
.setWidth(75f)
.setHeight(22f)
.setTextAlignment(TextAlignment.LEFT);
// Override the renderer
p.setNextRenderer(new ParagraphRenderer(p){
#Override
public List initElementAreas(LayoutArea area) {
List list = new ArrayList();
list.add(rect);
return list;
}
});
// Add the paragraph
(new Canvas(new PdfCanvas(currentPage), rect))
.add((BlockElement)p);
I am generate Barcode128 with library iText-2.1.3. This is code which I am using:
private void createBarcode(String kodDokumentu, String idSadowka, String projekt) throws IOException, DocumentException
{
File barcodePdf = new File(pathToPdf);
Files.deleteIfExists(barcodePdf.toPath());
Document document = new Document();
Rectangle size = new Rectangle(151,60);
document.setMargins(5, 1, -6, 0);
document.setPageSize(size);
FileOutputStream fos = new FileOutputStream(pathToPdf);
PdfWriter writer = PdfWriter.getInstance(document, fos);
document.open();
PdfContentByte cb = writer.getDirectContent();
Barcode barcode128 = new Barcode128();
barcode128.setBarHeight(40);
barcode128.setX(1.04f);
barcode128.setCode("VL#"+kodDokumentu.toUpperCase());
barcode128.setCodeType(Barcode.CODE128);
Image code128Image = barcode128.createImageWithBarcode(cb, null, null);
Font code = new Font(FontFamily.TIMES_ROMAN, 8, Font.NORMAL, BaseColor.BLACK);
Paragraph p = new Paragraph("ID: "+idSadowka+", Projekt: "+projekt.substring(0, 2), code);
document.add(p);
document.add(code128Image);
document.close();
fos.close();
}
I want to achive as small h (take a look at image) as it is possible, best if h=0.01 because I want to save more place for ID: xxxxx, Projekt: xx to make it bigger and easier to read by human.
First (bottom barcode) I used font size 8, then (upper barcode) I tried to change font size to 10 but when I did it h is bigger than previous. I know that font size is connected with gap between barcode and text above it but is it possible to use bigger font size and set this gap really small?
Not sure if it's available in the version of iText you use, but on iText 5 at least, you have the option to set the "spacing after" on Paragraphs. It would be exactly what you need, i.e. you specify a fixed space under the paragraph, and any elements you add to the document after that paragraph, will go under that space.
p.setSpacingAfter(x)
Where x being the space you need, in user units or "points".
I need to make a PDF page that looks something like this:
I'm having problems to make two columns that fit on a small sized page.
This is my code:
public void createSizedPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.setMargins(5,5,5,5);
Rectangle one = new Rectangle(290,100);
one.setBackgroundColor(Color.YELLOW);
document.setPageSize(one);
document.open();
Paragraph consigneeName = new Paragraph("Ahmed");
Paragraph address = new Paragraph("Casa ST 121");
String codeBL = "14785236987541";
PdfContentByte cb = writer.getDirectContent();
Barcode128 code128 = new Barcode128();
code128.setBaseline(9);
code128.setSize(9);
code128.setCode(codeBL);
code128.setCodeType(Barcode128.CODE128);
Image code128Image = code128.createImageWithBarcode(cb, null, null);
Paragraph right = new Paragraph();
right.add(consigneeName);
right.add(address);
right.add(code128Image);
Chunk glue = new Chunk(new VerticalPositionMark());
Paragraph p = new Paragraph();
p.add(right);
p.add(new Chunk(glue));
p.add(code128Image);
document.add(p);
document.close();
}
One way to solve your problem, would be to create a template PDF with AcroForm fields. You could create a nice design manually, and then fill out the form programmatically by putting data (text, bar codes) at the appropriate places defined by the fields that act as placeholders.
Another way, is to create the PDF from scratch, which is the approach you seem to have taken, looking at your code.
Your question isn't entirely clear, in the sense that you share your code, but you don't explain the problem you are experiencing. As I already commented:
are you unable to scale images? are you unable to define a smaller
font size? are you unable to create a table with specific dimension?
You say I'm having problems to make two columns that fits in a small
sized page but you forgot to describe the problems.
You didn't give an answer to those questions, and that makes it very hard for someone to answer your question. The only thing a Stack Overflow reader could do, is to do your work in your place. That's not what Stack Overflow is for.
Moreover, the answer to your question is so trivial that it is hard for a Stack Overflow reader to understand why you posted a question.
You say you need to add data (text and bar codes) in two columns, you are actually saying that you want to create a table. This is an example of such a table:
If you look at the SmallTable example, you can see how it's built.
You want a PDF that measures 290 by 100 user units, with a margin of 5 user units on each side. This means that you have space for a table measuring 280 by 90 user units. Looking at your screen shot, I'd say that you have a column of 160 user units with and a column of 120 user units. I'd also say that you have three rows of 30 user units high each.
OK, then why don't you create a table based on those dimensions?
public void createPdf(String dest) throws IOException, DocumentException {
Rectangle small = new Rectangle(290,100);
Font smallfont = new Font(FontFamily.HELVETICA, 10);
Document document = new Document(small, 5, 5, 5, 5);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(2);
table.setTotalWidth(new float[]{ 160, 120 });
table.setLockedWidth(true);
PdfContentByte cb = writer.getDirectContent();
// first row
PdfPCell cell = new PdfPCell(new Phrase("Some text here"));
cell.setFixedHeight(30);
cell.setBorder(Rectangle.NO_BORDER);
cell.setColspan(2);
table.addCell(cell);
// second row
cell = new PdfPCell(new Phrase("Some more text", smallfont));
cell.setFixedHeight(30);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setBorder(Rectangle.NO_BORDER);
table.addCell(cell);
Barcode128 code128 = new Barcode128();
code128.setCode("14785236987541");
code128.setCodeType(Barcode128.CODE128);
Image code128Image = code128.createImageWithBarcode(cb, null, null);
cell = new PdfPCell(code128Image, true);
cell.setBorder(Rectangle.NO_BORDER);
cell.setFixedHeight(30);
table.addCell(cell);
// third row
table.addCell(cell);
cell = new PdfPCell(new Phrase("and something else here", smallfont));
cell.setBorder(Rectangle.NO_BORDER);
cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
table.addCell(cell);
document.add(table);
document.close();
}
In this example,
you learn how to change the font of the content in a cell,
you learn how to change horizontal and vertical alignment,
you learn how to scale a bar code so that it fits into a cell,
...
All of this functionality is explained in the official documentation. As I said before: you didn't explain the nature of your problem. What wasn't clear in the documentation for you? What is your question?
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.
I have two parts to my java project.
I need to populate the fields of a pdf
I need to add a table below the populated section on the blank area of the page (and this table needs to be able to rollover to the next page).
I am able to do these things separately (populate the pdf and create a table). But I cannot effectively merge them. I have tried doing a doc.add(table) which will result in the table being on the next page of the pdf, which I don't want.
I essentially just need to be able to specify where the table starts on the page (so it wouldn't overlap the existing content) and then stamp the table onto the existing pdf.
My other option if this doesn't work is trying to add fields to the original pdf that will be filled by the table contents (so it will instead be a field-based table).
Any suggestions?
EDIT:
I'm new to iText and have not used columntext before, but I'm trying to test it out in the following code but the table is not being displayed. I looked at other columntext examples and I have not seen exactly where the columntext is added back into the pdf.
//CREATE FILLED FORM PDF
PdfReader reader = new PdfReader(sourcePath);
PdfStamper pdfStamper = new PdfStamper(reader, new FileOutputStream(destPath));
pdfStamper.setFormFlattening(true);
AcroFields form = pdfStamper.getAcroFields();
form.setField("ID", "99999");
form.setField("ADDR1", "425 Test Street");
form.setField("ADDR2", "Test, WA 91334");
form.setField("PHNBR", "(999)999-9999");
form.setField("NAME", "John Smith");
//CREATE TABLE
PdfPTable table = new PdfPTable(3);
Font bfBold12 = new Font(FontFamily.HELVETICA, 12, Font.BOLD, new BaseColor(0, 0, 0));
insertCell(table, "Table", Element.ALIGN_CENTER, 1, bfBold12);
table.completeRow();
ColumnText column = new ColumnText(pdfStamper.getOverContent(1));
column.addElement(table);
pdfStamper.close();
reader.close();
Please take a look at the AddExtraTable example. It's a simplification of the AddExtraPage example written in answer to the question How to continue field output on a second page?
That question is almost an exact duplicate of your question, with as only difference the fact that your requirement is easier to achieve.
I simplified the code like this:
public void manipulatePdf(String src, String dest) throws DocumentException, IOException {
PdfReader reader = new PdfReader(src);
Rectangle pagesize = reader.getPageSize(1);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
AcroFields form = stamper.getAcroFields();
form.setField("Name", "Jennifer");
form.setField("Company", "iText's next customer");
form.setField("Country", "No Man's Land");
PdfPTable table = new PdfPTable(2);
table.addCell("#");
table.addCell("description");
table.setHeaderRows(1);
table.setWidths(new int[]{ 1, 15 });
for (int i = 1; i <= 150; i++) {
table.addCell(String.valueOf(i));
table.addCell("test " + i);
}
ColumnText column = new ColumnText(stamper.getOverContent(1));
Rectangle rectPage1 = new Rectangle(36, 36, 559, 540);
column.setSimpleColumn(rectPage1);
column.addElement(table);
int pagecount = 1;
Rectangle rectPage2 = new Rectangle(36, 36, 559, 806);
int status = column.go();
while (ColumnText.hasMoreText(status)) {
status = triggerNewPage(stamper, pagesize, column, rectPage2, ++pagecount);
}
stamper.setFormFlattening(true);
stamper.close();
reader.close();
}
public int triggerNewPage(PdfStamper stamper, Rectangle pagesize, ColumnText column, Rectangle rect, int pagecount) throws DocumentException {
stamper.insertPage(pagecount, pagesize);
PdfContentByte canvas = stamper.getOverContent(pagecount);
column.setCanvas(canvas);
column.setSimpleColumn(rect);
return column.go();
}
As you can see, the main differences are:
We create a rectPage1 for the first page and a rectPage2 for page 2 and all pages that follow. That's because we don't need a full page on the first page.
We don't need to load a PdfImportedPage, instead we're just adding blank pages of the same size as the first page.
Possible improvements: I hardcoded the Rectangle instances. It goes without saying that rect1Page depends on the location of your original form. I also hardcoded rect2Page. If I had more time, I would calculate rect2Page based on the pagesize value.
See the following questions and answers of the official FAQ:
How to add a table on a form (and maybe insert a new page)?
How to continue field output on a second page?