Making editable cells of a table readonly having Scroll Bar with itext - itext

Please find the below code.
public class MakingFieldReadOnly implements PdfPCellEvent {
/** The resulting PDF. */
public static final String RESULT1 = "text_fields.pdf";
/** The resulting PDF. */
public static final String RESULT2 = "text_filled.pdf";
/** The text field index of a TextField that needs to be added to a cell. */
protected int tf;
public static final String CONTENT = "Write any thing so that it exceeds the content limit of the textfield and scroll bar comes. asdadasdasdasdasdasdasdasdasddlfjklfjljdflkjasdfjasdfjsldfjlsdjflsjdfljdflkjsdfljsldfjlsdjflskdfjlskdfjlsdjflskdjflksdjflksdjflkjsdflkjsdfljsdfkljsdlfjlsdjkfasdadasdasdasdasdasdasdasdasddlfjklfjljdflkjasdfjasdfjsldfjlsdjflsjdfljdflkjsdfljsldfjlsdjflskdfjlskdfjlsdjflskdjflksdjflksdjflkjsdflkjsdfljsdfkljsdlfjlsdjkfasdadasdasdasdasdasdasdasdasddlfjklfjljdflkjasdfjasdfjsldfjlsdjflsjdfljdflkjsdfljsldfjlsdjflskdfjlskdfjlsdjflskdjflksdjflksdjflkjsdflkjsdfljsdfkljsdlfjljkf";
/**
* Creates a cell event that will add a text field to a cell.
* #param tf a text field index.
*/
public MakingFieldReadOnly(int tf) {
this.tf = tf;
}
/**
* Manipulates a PDF file src with the file dest as result
* #param src the original PDF
* #param dest the resulting PDF
* #throws IOException
* #throws DocumentException */
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
AcroFields form = stamper.getAcroFields();
form.setField("text1_1", CONTENT);
form.setField("text1_2", CONTENT);
form.setField("text1_3", CONTENT);
form.setField("text1_4", CONTENT);
form.setFieldProperty("text1_1","setfflags",TextField.READ_ONLY , null);
form.setFieldProperty("text1_2","setfflags",TextField.READ_ONLY , null);
form.setFieldProperty("text1_3","setfflags",TextField.READ_ONLY , null);
form.setFieldProperty("text1_4","setfflags",TextField.READ_ONLY , null);
stamper.close();
//reader.close();
}
/**
* Creates a PDF document.
* #param filename the path to the new PDF document
* #throws DocumentException
* #throws IOException
*/
public void createPdf(String filename) throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
PdfWriter.getInstance(document, new FileOutputStream(filename));
// step 3
document.open();
// step 4
PdfPCell cell;
PdfPTable table = new PdfPTable(2);
table.setWidths(new int[]{ 1, 2 });
table.addCell("Name:");
cell = new PdfPCell();
cell.setCellEvent(new MakingFieldReadOnly(1));
cell.setFixedHeight(60);
table.addCell(cell);
table.addCell("Loginname:");
cell = new PdfPCell();
cell.setCellEvent(new MakingFieldReadOnly(2));
cell.setFixedHeight(60);
table.addCell(cell);
table.addCell("Password:");
cell = new PdfPCell();
cell.setCellEvent(new MakingFieldReadOnly(3));
cell.setFixedHeight(60);
table.addCell(cell);
table.addCell("Reason:");
cell = new PdfPCell();
cell.setCellEvent(new MakingFieldReadOnly(4));
cell.setFixedHeight(60);
table.addCell(cell);
document.add(table);
// step 5
document.close();
}
/**
* Creates and adds a text field that will be added to a cell.
* #see com.itextpdf.text.pdf.PdfPCellEvent#cellLayout(com.itextpdf.text.pdf.PdfPCell,
* com.itextpdf.text.Rectangle, com.itextpdf.text.pdf.PdfContentByte[])
*/
public void cellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases) {
PdfWriter writer = canvases[0].getPdfWriter();
TextField text = new TextField(writer, rectangle, String.format("text1_%s",tf));
text.setBackgroundColor(new GrayColor(0.75f));
text.setOptions(TextField.MULTILINE | TextField.REQUIRED);
text.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED);
text.setFontSize(8);
try {
PdfFormField field = text.getTextField();
writer.addAnnotation(field);
}
catch(IOException ioe) {
throw new ExceptionConverter(ioe);
}
catch(DocumentException de) {
throw new ExceptionConverter(de);
}
}
/**
* Main method
* #param args no arguments needed
* #throws IOException
* #throws DocumentException
*/
public static void main(String[] args) throws DocumentException, IOException {
MakingFieldReadOnly example = new MakingFieldReadOnly(0);
example.createPdf(RESULT1);
example.manipulatePdf(RESULT1, RESULT2);
}
}
Please run the above code and generate the document. I have used itext-1.3.jar but same behavior shown with itext-5.3.5.jar.
In the second file named as "text_filled.pdf", I have four pdf cells(fields) in the table. My code is making these editable fields read only but I want scroll bar also(when content exceeds the field limit) as like it is coming for 4th one only, so that user can be able to view whole content without having edit permission.
Could I get read only mode with scroll bar(if content is more than limit of the text field) for each cell of the the table.
I have tried the below code also for making the fields read only.
form.setFieldProperty("text1_1","setfflags",PdfFormField.FF_READ_ONLY , null);
form.setFieldProperty("text1_2","setfflags",PdfFormField.FF_READ_ONLY , null);
form.setFieldProperty("text1_3","setfflags",PdfFormField.FF_READ_ONLY, null);
form.setFieldProperty("text1_4","setfflags",PdfFormField.FF_READ_ONLY , null);
If from these codes can't be done then any other possible solution.

I have tried your example, and I have discovered that the behavior you experience is caused by a bug in Adobe Acrobat / Reader. The bug occurs when the borders of the widget annotations of different text fields overlap.
Once I made sure that there was no overlap between the different fields, the scroll bars appeared.
How did I make sure that there was no overlap? Simply by changing the way the TextField instance created in your cellLayout() method:
Rectangle rect = new Rectangle(
rectangle.getLeft(), rectangle.getTop() - 1,
rectangle.getRight(), rectangle.getBottom() + 1);
TextField text = new TextField(writer, rect, String.format("text1_%s",tf));
Now the rectangles that define the text field no longer overlap, and you no longer experience the Adobe Acrobat / Reader bug.

Related

Header and footer with content, itextpdf

My problem is when I try to add the content in the pdf, my table appears from the beginning and not below the header, my table with content has an incorrect height
The code is something long and I can not upload images, but I have a header and footer with pagination
It looks like it's just adding a space to my table with content but I do not know how to do it, I think my problem is in the summary method
private void addHeader(PdfWriter writer) {
PdfPTable tableHeader = new PdfPTable(2);
try {
// set default
tableHeader.setWidths(new int[] { 2, 24 });
tableHeader.setTotalWidth(527);
tableHeader.setLockedWidth(true);
tableHeader.getDefaultCell().setFixedHeight(40);
tableHeader.getDefaultCell().setBorder(Rectangle.BOTTOM);
tableHeader.getDefaultCell().setBorderColor(BaseColor.LIGHT_GRAY);
// addImage
Image img = Image.getInstance(getClass().getClassLoader().getResource("imgPDF/logo.png"));
tableHeader.addCell(img);
// addText
PdfPCell text = new PdfPCell();
text.setPaddingBottom(15);
text.setPaddingLeft(10);
text.setBorder(Rectangle.BOTTOM);
text.setBorderColor(BaseColor.LIGHT_GRAY);
text.addElement(new Phrase(cve.getId(), new Font(Font.FontFamily.HELVETICA, 13)));
text.addElement(new Phrase("https://myapp.com", new Font(Font.FontFamily.HELVETICA, 10)));
tableHeader.addCell(text);
// write content
tableHeader.writeSelectedRows(0, -1, 34, 803, writer.getDirectContent());
} catch (DocumentException e) {
throw new ExceptionConverter(e);
} catch (MalformedURLException e) {
throw new ExceptionConverter(e);
} catch (IOException e) {
throw new ExceptionConverter(e);
}
private void summary() throws IOException, DocumentException {
PdfPTable table = new PdfPTable(2);
table.setHeaderRows(0);
table.setWidthPercentage(100);
table.setSpacingBefore(15);
table.setTotalWidth(100);
// Add headers
table.addCell(createHeaderCellWithColor("Summary"));
table.addCell(createHeaderCellWithColor("ACCESS"));
table.addCell(createCell("row 1"));
table.addCell(createCell("row 2"));
table.addCell(createCell("row 3"));
PdfPTable table3 = new PdfPTable(3);
PdfPCell cell = new PdfPCell(new Phrase("aaa"));
cell.setColspan(3);
table3.addCell(cell);
table.addCell(createHeaderCellWithColor("IMPACT"));
document.add(table);
With this I largely resolve,
document = new Document (PageSize.A4, 36, 36, 90, 36);
Although I would like to download more content, and that is not so close to the header
Previously had this method with a parameter equal to 15, making the content below the header, this more separate ,,, simply equals the fill
solved with
text.setPaddingBottom(8);

3D Annotation and PdfLayer

Suppose that I have two instances layer1 and layer2 of type com.itextpdf.text.pdf.PdfLayer, with layer1 will be used for an instance of typecom.itextpdf.text.pdf.PdfTemplatethat contains a instance of type com.itextpdf.text.Image and layer2 will be used for a 3D annotation of type com.itextpdf.text.pdf.PdfAnnotation.
The problem: after setting the visibility and activating the area reserved for layer2, I can neither make it(layer2) unvisible nor displaying layer1.
Essential Code:
private Document document;
private PdfWriter writer;
PdfContentByte upperLayer;
Rectangle box;
private PdfLayer view2D;
private PdfLayer view3D;
public static void main(String[] args) throws DocumentException, MalformedURLException, URISyntaxException, IOException
{
LayersWithDiffDimsDemo generator = new LayersWithDiffDimsDemo();
generator.setupResources();
generator.report();
generator.cleanupResources();
}
public void setupResources() throws DocumentException, IOException
{
document = new Document(PageSize.A4);
FileOutputStream outputStream = new FileOutputStream("layers_with_diff_dimensions.pdf");
writer = PdfWriter.getInstance(document, outputStream);
document.open();
upperLayer = writer.getDirectContent();
box = new Rectangle(26.0f, document.getPageSize().getHeight() - 455.0f, 550, document.getPageSize().getHeight() - 210.0f);
box.setBorder(Rectangle.BOX);
box.setBorderWidth(0.5f);
box.setBorderColor(new BaseColor(0xFF, 0x00, 0x00));
document.add(box);
PdfLayer views = PdfLayer.createTitle("Ansichtsmodi", writer);
view2D = new PdfLayer("2D", writer);
view2D.setOn(true);
view3D = new PdfLayer("3D", writer);
view3D.setOn(false);
views.addChild(view3D);
views.addChild(view2D);
ArrayList<PdfLayer> radio = new ArrayList<>();
radio.add(view3D);
radio.add(view2D);
writer.addOCGRadioGroup(radio);
}
public void report() throws URISyntaxException, MalformedURLException, IOException
{
try
{
// Output the dimension drawing
// teapot.jpg is a screen shot of the 3d model
Image imageIn2D = Image.getInstance("teapot.jpg");
imageIn2D.setAbsolutePosition((document.getPageSize().getWidth() - imageIn2D.getWidth()) / 2, 400.0f);
imageIn2D.setLayer(view2D);
upperLayer.addImage(imageIn2D, true);
try {
// The file name that contains the 3D Model
FileInputStream inputStream = new FileInputStream("teapot.u3d");
PdfStream stream3D = new PdfStream(inputStream, writer);
stream3D.put(PdfName.TYPE, new PdfName("3D"));
stream3D.put(PdfName.SUBTYPE, new PdfName("U3D"));
stream3D.flateCompress();
try {
PdfIndirectObject streamObject = writer.addToBody(stream3D);
stream3D.writeLength();
PdfDictionary dict3D = new PdfDictionary();
dict3D.put(PdfName.TYPE, new PdfName("3DView"));
dict3D.put(new PdfName("XN"), new PdfString("Default"));
dict3D.put(new PdfName("IN"), new PdfString("Unnamed"));
dict3D.put(new PdfName("MS"), PdfName.M);
dict3D.put(new PdfName("C2W"), new PdfArray(new float[]{1, 0, 0, 0, 0, -1, 0, 1, 0, 3, -235, 28}));
dict3D.put(PdfName.CO, new PdfNumber(235));
PdfIndirectObject dictObject = writer.addToBody(dict3D);
PdfAnnotation annot = new PdfAnnotation(writer, box);
annot.setLayer(view3D);
annot.put(PdfName.CONTENTS, new PdfString("3D Model"));
annot.put(PdfName.SUBTYPE, new PdfName("3D"));
annot.put(PdfName.TYPE, PdfName.ANNOT);
annot.put(new PdfName("3DD"), streamObject.getIndirectReference());
annot.put(new PdfName("3DV"), dictObject.getIndirectReference());
PdfAppearance ap = upperLayer.createAppearance(box.getWidth(), box.getHeight());
annot.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, ap);
annot.setPage();
upperLayer.addAnnotation(annot, false);
} catch (IOException ex) {
Logger.getLogger(LayersWithDiffDimsDemo.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(LayersWithDiffDimsDemo.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (DocumentException ex)
{
Logger.getLogger(LayersWithDiffDimsDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void cleanupResources()
{
document.close();
}
Thank you for any suggests!
Assuming your viewer is Acrobat or Reader, as long as the 3D annotation is active it's going to be visible. The fact that the annot is associated with a layer, visible or otherwise, won't change that.
Defending my assertion...
Open the file at http://practicalpdf.com/downloads/BrakeAssembly.pdf.
The file has a single 3D Annotation taking up the whole page and is set to activate when clicked. It's deactivated when the file first opens. The 3D annot is also on a layer called "3DAnnot" and the file initial view is set to open in Reader with the layers panel showing. Associating an annotation with a layer is supported in the PDF Specification but there's no way to author it in Acrobat without a plugin or via a library as you are doing.
Notice when you first open the file, the 3D annotation is not active and you can toggle the layer visibility. Notice that the annotation poster visibility is following the layer visibility. Now activate the annot by clicking on it. Now notice that the activated 3D Annot is not affected by the visibility of the layer.
This is because layer visibility only applies to PDF Page content. The poster (appearance) of the 3D annot is the only part of that dictionary that is page content. The 3D viewer runtime is simply projecting into the same rectangle as the annot. While active, the 3D will always display over the page content even if you add a layer on top of the one that holds the 3D annotation.

XMLWorkerHelper loses text not between tags

I've been using XMLWorkerHelper to add formatted text, inputted on pages via a rich text editor, to PDFs. I've noticed that sometimes not all text was rendered in the PDF. Apparently XMLWorkerHelper drops text not between HTML tags.
Is this correct behavior?
I've written a JUnit test case that shows the problem:
public class XMLWorkerTest {
#Test
public void test() throws IOException, DocumentException {
Document document = new Document();
String fileName = "itext_test_" + System.currentTimeMillis() + ".pdf";
PdfWriter.getInstance(document, new FileOutputStream(fileName));
document.open();
Paragraph paragraph = new Paragraph();
String s1 = "not between tags<b>between tags</b>not between tags";
addHtml(paragraph, s1);
// NOT OK: 'not between tags' missing twice
paragraph.add(Chunk.NEWLINE);
String s2 ="<span>" + s1 + "</span>";
addHtml(paragraph, s2);
// OK
document.add(paragraph);
document.close();
}
private void addHtml(final Paragraph paragraph, String html) throws IOException {
XMLWorkerHelper.getInstance().parseXHtml(new ElementHandler() {
#Override
public void add(Writable writable) {
if (writable instanceof WritableElement) {
for (Element element : ((WritableElement) writable).elements()) {
paragraph.add(element);
}
}
}
}, new ByteArrayInputStream(html.getBytes()), Charset.defaultCharset());
}
}
We're using version 5.5.6.
That's the expected behavior. Your html should have a root tag otherwise it's not really html. Just because the text shows in a browser doesn't mean that is well formed.

Horizontal wise add PdfPTable with MultiColumnText in iText

I've a pdf report generated with iText containing a PdfPTable added to MultiColumnText, sometimes becomes so large that it will be split on more than one page.
Currently the MultiColumnText has been divided by two columns and MultiColumnText fills the PdfPTable vertically Like:
Page-1
+--+--+
|T1|T5|
+--+--+
|T2|T6|
+--+--+
|T3|T7|
+--+--+
|T4|T8|
+--+--+
Page-2
+---+---+
|T9 |T13|
+---+---+
|T10|T14|
+---+---+
|T11|T15|
+---+---+
|T12|T16|
+---+---+
....I want to make this:
Page-1
+--+--+
|T1|T2|
+--+--+
|T3|T4|
+--+--+
|T5|T6|
+--+--+
|T7|T8|
+--+--+
Page-2
+---+---+
|T9 |T10|
+---+---+
|T11|T12|
+---+---+
|T13|T14|
+---+---+
|T15|T16|
+---+---+
The code is:
/**
* Initializes the fonts and collections.
* Creates a PDF document.
*
* #param from as a Date
* #param to as a Date
* #param weeklyComplianceMap as a Map for print weekly compliance
* #param monthlyComplianceMap as a Map for print monthly compliance
* #param calLogList as a List for calculate the add event
* #param locale Locale in case you want to create a Calendar in another language
* #throws DocumentException, IOException, ParseException
* #return ByteArrayOutputStream of PDF output
*/
public ByteArrayOutputStream createPdf(Date from, Date to, Map<String, Integer> weeklyComplianceMap,
Map<String, Double> monthlyComplianceMap, List<InjectionLogInfo> calLogList, Locale locale)
throws DocumentException, ParseException, IOException {
calendar = new GregorianCalendar();
calendar.setTime(from);
BaseFont bf_normal = BaseFont.createFont(
"C:/Windows/Fonts/arial.ttf", BaseFont.WINANSI,
BaseFont.EMBEDDED);
small = new Font(bf_normal, 8);
normal = new Font(bf_normal, 11);
BaseFont bf_bold = BaseFont.createFont(
"C:/Windows/Fonts/arialbd.ttf", BaseFont.WINANSI,
BaseFont.EMBEDDED);
smallBold = new Font(bf_bold, 10);
normalBold = new Font(bf_bold, 12);
bigBold = new Font(bf_bold, 14);
document = new Document(PageSize.A4, 20, 20, 40, 30);
baos = new ByteArrayOutputStream();
writer = PdfWriter.getInstance(document, baos);
ResourceBundle rb = ResourceBundle.getBundle("com.resources.messages", locale);
Paragraph hText = new Paragraph(rb.getString("lbl.calendar.view"), bigBold);
hText.setAlignment(Element.ALIGN_CENTER);
Chunk c1 = new Chunk(rb.getString("lbl.document.generated") + " ", normal);
Chunk c2 = new Chunk(fdf.format(new Date()), normal);
Chunk c3 = new Chunk(" " + rb.getString("lbl.at") + " ", normal);
Chunk c4 = new Chunk(tdf.format(new Date()), normal);
Chunk c5 = new Chunk(new VerticalPositionMark(), 500f, false);
Chunk c6 = new Chunk(rb.getString("lbl.page") + " ", normal);
Phrase fText = new Phrase();
fText.add(c1);fText.add(c2);fText.add(c3);
fText.add(c4);fText.add(c5);fText.add(c6);
HeaderFooter header = new HeaderFooter(hText, false);
HeaderFooter footer = new HeaderFooter(fText, true);
document.setHeader(header);
document.setFooter(footer);
document.open();
document.leftMargin();
mct = new MultiColumnText();
mct.addRegularColumns(document.left(), document.right(), 20, 2);
mct.setRunDirection(PdfWriter.RUN_DIRECTION_LTR);
for (int month = 0; month < monthsBetween(from, to, Calendar.MONTH); month++) {
// create a table with 8 columns
float[] colsWidth = {35f, 35f, 35f, 35f, 35f, 35f, 35f, 50f};
table = new PdfPTable(colsWidth);
table.setWidthPercentage(100);
// add the name of the month
table.getDefaultCell().setBackgroundColor(Color.WHITE);
table.addCell(getMonthCell(calendar, locale));
Double monAdh = monthlyComplianceMap.get(mdf.format(calendar.getTime()));
table.addCell(getMonthlyAdherence(monAdherence));
// add the name of the days
String[] days = getDayNames();
for (String day : days) {
table.addCell(getDayNamesCell(day, locale));
}
int day = 1;
int position = 2;
int dayofWeek = calendar.get(Calendar.DAY_OF_WEEK);
int daysinMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
// add empty cells
int rc = 0;
while (position != dayofWeek) {
rc++;
position = (position % 7) + 1;
table.addCell("");
}
// add cells for each day
while (day <= daysinMonth) {
calendar = new GregorianCalendar(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), day++);
table.addCell(getDayCell(calLogList, calendar, locale));
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
rc++;
String week = (calendar.get(Calendar.WEEK_OF_YEAR)-1) + ", " + calendar.get(Calendar.YEAR);
if (null != weeklyComplianceMap) {
wa = weeklyComplianceMap.get(week);
table.addCell(getDayAdherenceCell(weekAdherence));
} else {
String weekAdherence = "0%";
table.addCell(getDayAdherenceCell(weekAdherence));
}
}
}
if (9 < rc)
table.setSpacingAfter(20);
else
table.setSpacingAfter(40);
// complete the table
table.completeRow();
// add the table to MultiColumnText object
mct.addElement(table);
// increment the day by 1
calendar.add(Calendar.DATE, 1);
}
document.add(mct);
document.newPage();
document.close();
return baos;
}
/**
* Creates a PdfPCell with the name of the month
*
* #param calendar a date
* #param locale a locale
* #return a PdfPCell with rowspan 7, containing the name of the month
*/
public PdfPCell getMonthCell(Calendar calendar, Locale locale) {
PdfPCell cell = new PdfPCell();
cell.setColspan(7);
cell.setMinimumHeight(30);
cell.setBackgroundColor(Color.GRAY);
Paragraph p = new Paragraph(String.format(locale, "%1$tB %1$tY", calendar), normalBold);
p.setAlignment(Element.ALIGN_LEFT);
cell.addElement(p);
return cell;
}
/**
* Creates a PdfPCell for a month
*
* #param string adherence of a month
* #return a PdfPCell
*/
private PdfPCell getMonthlyAdherence(String adherence) {
PdfPCell cell = new PdfPCell();
cell.setMinimumHeight(35);
//cell.setBorderColorLeft(Color.GRAY);
cell.setBackgroundColor(Color.GRAY);
Paragraph p = new Paragraph(adherence, smallBold);
p.setAlignment(Element.ALIGN_RIGHT);
cell.addElement(p);
return cell;
}
/**
* Creates a PdfPCell with the name of the day
*
* #param day name of a day
* #param locale a locale
* #return a PdfPCell, containing the name of the day
*/
public PdfPCell getDayNamesCell(String day, Locale locale) {
PdfPCell cell = new PdfPCell();
cell.setPadding(3);
cell.setBackgroundColor(Color.LIGHT_GRAY);
Paragraph p = new Paragraph(day, smallBold);
p.setAlignment(Element.ALIGN_CENTER);
cell.addElement(p);
return cell;
}
/**
* Creates a PdfPCell for a specific day
*
* #param calendar a date
* #param locale a locale
* #return a PdfPCell
*/
public PdfPCell getDayCell(List<InjectionLogInfo> calLogList, Calendar calendar, Locale locale) {
PdfPCell cell = new PdfPCell();
cell.setPadding(3);
// set the content in the language of the locale
Chunk chunk = new Chunk(String.format(locale, "%1$te", calendar), small);
// a paragraph with the day
Paragraph p = new Paragraph(chunk);
p.setAlignment(Element.ALIGN_CENTER);
cell.addElement(p);
return cell;
}
/**
* Creates a PdfPCell for a week
*
* #param string adherence of a week
* #return a PdfPCell
*/
public PdfPCell getDayAdherenceCell(String adherence) {
PdfPCell cell = new PdfPCell();
cell.setPadding(3);
// set the adherence for each week
Chunk chunk = new Chunk(adherence, small);
// a paragraph with the adherence
Paragraph p = new Paragraph(chunk);
p.setAlignment(Element.ALIGN_CENTER);
cell.addElement(p);
return cell;
}
/**
* Retrieves a Day Names for a single week
*
* #return a String array of day names
*/
public String[] getDayNames() {
DateFormatSymbols symbols = new DateFormatSymbols();
String[] dayNames = symbols.getShortWeekdays();
List<String> stringList = new ArrayList<String>();
for (String string : dayNames) {
if (string != null && string.length() > 0) {
stringList.add(string);
}
}
if (stringList.size() > 0) {
String one = stringList.get(0);
stringList.remove(0);
stringList.add(one);
stringList.add("%");
}
dayNames = stringList.toArray(new String[stringList.size()]);
return dayNames;
}
I stuck with this so any help is very appreciated.
Thanks.
I think you are using new PdfPtable(1) per MultiColumnText. change it to new PdfPtable(2) to get 2 columns table per 1 MultiColumnText.

How to insert blank lines in PDF?

I am creating a PDF using iText. I want to insert blank lines between paragraphs and tables.
How can I achieve this?
You can trigger a newline by inserting Chunk.NEWLINE into your document. Here's an example.
public static void main(String args[]) {
try {
// create a new document
Document document = new Document( PageSize.A4, 20, 20, 20, 20 );
PdfWriter.getInstance( document, new FileOutputStream( "HelloWorld.pdf" ) );
document.open();
document.add( new Paragraph( "Hello, World!" ) );
document.add( new Paragraph( "Hello, World!" ) );
// add a couple of blank lines
document.add( Chunk.NEWLINE );
document.add( Chunk.NEWLINE );
// add one more line with text
document.add( new Paragraph( "Hello, World!" ) );
document.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
Below is a screen shot showing part of the PDF that the code above produces.
And to insert blank line between tables you can use these both methods
table.setSpacingBefore();
table.setSpacingAfter();
You can use "\n" in Paragraph
document.add(new Paragraph("\n\n"));
You can try a blank phrase:
document.add(new Phrase("\n"));
You can add Blank Line throw PdfContentByte class in itextPdf. As shown below:
package com.pdf.test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class Ranvijay {
public static final String RESULT = "d:/printReport.pdf";
public void createPdf(String filename) throws Exception {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(filename));
document.open();
Font bold = new Font(Font.FontFamily.HELVETICA, 8f, Font.BOLD);
Font normal = new Font(Font.FontFamily.HELVETICA, 8f, Font.NORMAL);
PdfPTable tabletmp = new PdfPTable(1);
tabletmp.getDefaultCell().setBorder(Rectangle.NO_BORDER);
tabletmp.setWidthPercentage(100);
PdfPTable table = new PdfPTable(2);
float[] colWidths = { 45, 55 };
table.setWidths(colWidths);
String imageUrl = "http://ssl.gstatic.com/s2/oz/images/logo/2x/googleplus_color_33-99ce54a16a32f6edc61a3e709eb61d31.png";
Image image2 = Image.getInstance(new URL(imageUrl));
image2.setWidthPercentage(60);
table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
table.getDefaultCell().setVerticalAlignment(Element.ALIGN_TOP);
PdfPCell cell = new PdfPCell();
cell.setBorder(Rectangle.NO_BORDER);
cell.addElement(image2);
table.addCell(cell);
String email = "ranvijay9286#gmail.com";
String collectionDate = "09/09/09";
Chunk chunk1 = new Chunk("Date: ", normal);
Phrase ph1 = new Phrase(chunk1);
Chunk chunk2 = new Chunk(collectionDate, bold);
Phrase ph2 = new Phrase(chunk2);
Chunk chunk3 = new Chunk("\nEmail: ", normal);
Phrase ph3 = new Phrase(chunk3);
Chunk chunk4 = new Chunk(email, bold);
Phrase ph4 = new Phrase(chunk4);
Paragraph ph = new Paragraph();
ph.add(ph1);
ph.add(ph2);
ph.add(ph3);
ph.add(ph4);
table.addCell(ph);
tabletmp.addCell(table);
PdfContentByte canvas = writer.getDirectContent();
canvas.saveState();
canvas.setLineWidth((float) 10 / 10);
canvas.moveTo(40, 806 - (5 * 10));
canvas.lineTo(555, 806 - (5 * 10));
canvas.stroke();
document.add(tabletmp);
canvas.restoreState();
PdfPTable tabletmp1 = new PdfPTable(1);
tabletmp1.getDefaultCell().setBorder(Rectangle.NO_BORDER);
tabletmp1.setWidthPercentage(100);
document.add(tabletmp1);
document.close();
}
/**
* Main method.
*
* #param args
* no arguments needed
* #throws DocumentException
* #throws IOException
*/
public static void main(String[] args) throws Exception {
new Ranvijay().createPdf(RESULT);
System.out.println("Done Please check........");
}
}
document.add(new Paragraph(""))
It is ineffective above,must add a blank string, like this:
document.add(new Paragraph(" "));
You can add empty line ;
Paragraph p = new Paragraph();
// add one empty line
addEmptyLine(p, 1);
// add 3 empty line
addEmptyLine(p, 3);
private static void addEmptyLine(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
You can also use
document.add(new Paragraph());
document.add(new Paragraph());
before seperator if you are using either it is fine.
Instead of using:
document.add( Chunk.NEWLINE );
use this:
document.add(new Paragraph(""));
it makes small space
directly use
paragraph.add("\n");
to add an empty line.
I posted this in another question, but I find using tables with iTextSharp offers a great level of precision.
document.Add(BlankLineDoc(16));
public static PdfPTable BlankLineDoc(int height)
{
var table = new PdfPTable(1) {WidthPercentage = 100};
table = BlankLineTable(table, height);
return table;
}
public static PdfPTable BlankLineTable(PdfPTable table, int height, int border = Rectangle.NO_BORDER)
{
var cell = new PdfPCell(new Phrase(" "))
{
Border = border,
Colspan = table.NumberOfColumns,
FixedHeight = height
};
table.AddCell(cell);
return table;
}
BlankLineTable can be used directly when working with tables
I had to add blank lines after a table and I manage it adding many divs as I need it with a css style with padding-top set it up, like this. I've used a template engine (underscore) to loop through the number of lines I need to add.
<% var maxRow = 30; var pos = items.models.length; %>
<% for( pos; pos < maxRow; pos++ ){ %>
<div class="blankRow"></div>
<% }; %>
My css file:
.blankRow:{ padding-top: 15px;}