Unable to left-align nested tables inside a cell - itext

the following code does produce the table and the nested table.
However, the nested table is always aligned in the middle.
I have no clue how to achieve horizontal alignment properly.
The following method is simply looping through a list.
when it's a simple question, I will add an TextField.
if it's a question containing multiple answers, i will inject a nested table with the checkboxes and the values.
private PdfPTable CreateQuestionTable(RLQuestionRecordList questions)
{
PdfPCell cell;
PdfPTable table = new PdfPTable(2);
//table.SetWidths(new int[]{ 50, 50 });
table.WidthPercentage = 100;
table.SpacingBefore = 20;
table.SpacingAfter = 20;
table.DefaultCell.HorizontalAlignment = Element.ALIGN_LEFT;
foreach (RCQuestionRecord q in questions)
{
//add question to the table
cell = new PdfPCell(new Phrase(q.ssSTQuestion.ssName, _Normal));
cell.Border = Rectangle.NO_BORDER;
cell.Padding = 5.0f;
table.AddCell(cell);
//add answer to the table.
//add generate time we don;t know where the table will be,
//hence textfields will be generated after the pdf has been generated..
if (q.ssSTQuestion.ssListOfAnswers.Length > 0)
{
// we have radiobuttons, so we add a table inside the cell
cell = new PdfPCell();
cell.Border = Rectangle.NO_BORDER;
cell.Padding = 5.0f;
//we cannot align the table to the left in the cell for some weird reason...
cell.HorizontalAlignment = Element.ALIGN_LEFT;
cell.AddElement(CreateCheckboxTable(q));
table.AddCell(cell);
}
else
{
// we have simple textfield, so add that to the cell
cell = new PdfPCell();
cell.Border = Rectangle.NO_BORDER;
cell.Padding = 5.0f;
cell.HorizontalAlignment = Element.ALIGN_LEFT;
//simple textfield
cell.CellEvent = new OOMTextField(string.Format("question_{0}", q.ssSTQuestion.ssQuestionId), q.ssSTQuestion.ssLength, q.ssSTQuestion.ssValue, bf);
table.AddCell(cell);
}
}
return table;
}
This is the nested table I want to insert into the cell above.
/// <summary>
///
/// </summary>
/// <param name="question"></param>
/// <returns></returns>
private PdfPTable CreateCheckboxTable(RCQuestionRecord question)
{
PdfPCell cell;
int numCells = question.ssSTQuestion.ssListOfAnswers.Length;
PdfPTable table = new PdfPTable(numCells);
float[] widths = new float[numCells];
int currentColumn = 0;
//table.SetWidths(new int[]{ 50, 50 });
foreach (RCAnswerRecord a in question.ssSTQuestion.ssListOfAnswers) {
//checkbox
cell = new PdfPCell(new Phrase(a.ssSTAnswer.ssLabel, _Normal));
cell.Border = Rectangle.NO_BORDER;
cell.Padding = 0.0f;
cell.PaddingLeft = 20.0f;
cell.HorizontalAlignment = Element.ALIGN_LEFT;
cell.VerticalAlignment = Element.ALIGN_CENTER;
cell.CellEvent = new OOMCheckBox(string.Format("question_{0}", question.ssSTQuestion.ssQuestionId), a.ssSTAnswer.ssIsSelected, a.ssSTAnswer.ssLabel, bf);
//checkbox
table.AddCell(cell);
widths[currentColumn++] = 20.0f + bf.GetWidthPoint(a.ssSTAnswer.ssLabel, 11);
}
table.SetTotalWidth(widths);
table.LockedWidth = true;
table.SpacingBefore = 0;
return table;
}
What am I missing to align the nested tables totally to the left inside the cell?

Please take a look at the PDF document named nested_tables_aligned.pdf:
The outer table in this example has three columns and one row. Each cell in this outer table contains an inner table. The first inner table is left aligned, the second one is center aligned, the third one is right aligned.
This PDF was created with the Java example named NestedTablesAligned:
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document(PageSize.A4.rotate());
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
float[] columnWidths = {200f, 200f, 200f};
PdfPTable table = new PdfPTable(columnWidths);
table.setTotalWidth(600f);
table.setLockedWidth(true);
buildNestedTables(table);
document.add(table);
document.close();
}
private void buildNestedTables(PdfPTable outerTable) {
PdfPTable innerTable1 = new PdfPTable(1);
innerTable1.setTotalWidth(100f);
innerTable1.setLockedWidth(true);
innerTable1.setHorizontalAlignment(Element.ALIGN_LEFT);
innerTable1.addCell("Cell 1");
innerTable1.addCell("Cell 2");
outerTable.addCell(innerTable1);
PdfPTable innerTable2 = new PdfPTable(2);
innerTable2.setTotalWidth(100f);
innerTable2.setLockedWidth(true);
innerTable2.setHorizontalAlignment(Element.ALIGN_CENTER);
innerTable2.addCell("Cell 3");
innerTable2.addCell("Cell 4");
outerTable.addCell(innerTable2);
PdfPTable innerTable3 = new PdfPTable(2);
innerTable3.setTotalWidth(100f);
innerTable3.setLockedWidth(true);
innerTable3.setHorizontalAlignment(Element.ALIGN_RIGHT);
innerTable3.addCell("Cell 5");
innerTable3.addCell("Cell 6");
outerTable.addCell(innerTable3);
}
As you can see, I define the alignment of the table at the level of the table, not at the level of the cell. The sample principle applies to iTextSharp. In you C# example, you define the aligned for the PdfPCell instead of for the PdfPTable. Change this and your problem will be solved.

Related

Itext Table Row , Table Header , Table cell

I have a requirement to generated the PDF using itext in java
Need to generate the table with 3 rows and 2 columns , able to create the table.
Country Langugage
USA English
Canada French
When I was trying to read the pdf VIA NVDA Desktop App , the table is not reading the cells properly , say when I want to focus the pointer on Canada , it should the Country - Canada
Following is the code
public class Test {
public static final String CSS = "tr { text-align: center; } th { background-color: lightgreen; padding: 3px; } td {background-color: lightblue; padding: 3px; }";
public static void main(String sunil[])
{
String pFileName = "Test.pdf";
String pFilePath = "C:/local/home/dna/pushlive/" + pFileName;
try {
FileOutputStream baosPDF = new FileOutputStream(pFilePath);
com.itextpdf.text.Rectangle pageSize = new com.itextpdf.text.Rectangle(1836, 2376);
com.itextpdf.text.Document document = new com.itextpdf.text.Document(pageSize, 36, 36, 36, 36);
PdfWriter writer = PdfWriter.getInstance(document, baosPDF);
writer.setTagged();
document.open();
PdfPTable bannerTable = new PdfPTable(4);
document.add(createFirstTable());
document.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static PdfPTable createFirstTable() {
// a table with three columns
PdfPTable table = new PdfPTable(2);
// the cell object
PdfPCell cell;
// we add a cell with colspan 3
//create header cell for first row
// now we add a cell with rowspan 2
//add metadata for each cell in the body.
// we add the four remaining cells with addCell()
cell = new PdfPCell(new Phrase("Country"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("Language"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("USA"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("English"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("Canada"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("French"));
table.addCell(cell);
//set header row for the table
table.setHeaderRows(1);
return table;
}

Duplicate Fields using itextsharp

I have this code to create TextFields
public void MssCreateTextField(byte[] ssPdf, RCRectangleRecord ssRectangle, string ssName, int ssFontSize, string ssValue, int ssPage, out byte[] ssPdfOut, bool ssIsMultiline) {
PdfReader reader = new PdfReader(ssPdf);
ssPdfOut = null;
var output = new MemoryStream();
var stamper = new PdfStamper(reader, output);
/*TextField tField = new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)ssRectangle.ssSTRectangle.ssllx, (float)ssRectangle.ssSTRectangle.sslly, (float)ssRectangle.ssSTRectangle.ssurx, (float)ssRectangle.ssSTRectangle.ssury), ssName);
if (ssValue!="")
tField.Text = ssValue;
if (ssIsMultiline)
tField.Options = TextField.MULTILINE;
tField.FontSize = ssFontSize;*/
PdfFormField tField = PdfFormField.CreateTextField(stamper.Writer, ssIsMultiline, false, 50);
tField.FieldName = ssName;
tField.SetWidget(new iTextSharp.text.Rectangle((float)ssRectangle.ssSTRectangle.ssllx, (float)ssRectangle.ssSTRectangle.sslly, (float)ssRectangle.ssSTRectangle.ssurx, (float)ssRectangle.ssSTRectangle.ssury), PdfAnnotation.HIGHLIGHT_TOGGLE);
stamper.FormFlattening = false;
stamper.AddAnnotation(tField, ssPage);
stamper.Close();
reader.Close();
ssPdfOut = output.ToArray();
}
As you can see i have some code commented as an alternative but the two different ways are producing the same result.
What i am trying to achieve is create two textfields with the same name to when editing one it edits the others two. This two codes do that (in the browsers and pdfescape site) excepting in the adobe acrobat reader. In the acrobat reader i get just the first field visible and the others hidden i dont know why...
If you want to add two text field visualizations which represent the same content, you have to add them as two widgets of the same field and not two distinct fields, e.g. like this:
public void CreateDoubleTextField(byte[] ssPdf, Rectangle ssRectangle1, Rectangle ssRectangle2, string ssName, int ssFontSize, string ssValue, int ssPage, out byte[] ssPdfOut, bool ssIsMultiline)
{
PdfReader reader = new PdfReader(ssPdf);
ssPdfOut = null;
var output = new MemoryStream();
var stamper = new PdfStamper(reader, output);
PdfFormField tField = PdfFormField.CreateTextField(stamper.Writer, ssIsMultiline, false, 50);
tField.FieldName = ssName;
PdfFormField widget1 = PdfFormField.CreateEmpty(stamper.Writer);
widget1.SetWidget(ssRectangle1, PdfAnnotation.HIGHLIGHT_TOGGLE);
PdfFormField widget2 = PdfFormField.CreateEmpty(stamper.Writer);
widget2.SetWidget(ssRectangle2, PdfAnnotation.HIGHLIGHT_TOGGLE);
tField.AddKid(widget1);
tField.AddKid(widget2);
stamper.FormFlattening = false;
stamper.AddAnnotation(tField, ssPage);
stamper.Close();
reader.Close();
ssPdfOut = output.ToArray();
}
(As I don't have that RCRectangleRecord, I use the iTextSharp Rectangle class as argument.)
This gives you two field visualizations in Adobe Acrobat Reader; after editing one of them and switching focus (e.g. clicking somewhere outside that visualization), the other visualization duplicates the content.
Now i have this and i can create two fields when the list has more than one Rectangle but for some reason i dont know how the two fields appears without the name!!
PdfReader reader = new PdfReader(ssPdf);
ssPdfOut = null;
var output = new MemoryStream();
var stamper = new PdfStamper(reader, output);
TextField tField;
if (ssRectangle.Count==1){
tField= new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)ssRectangle[0].ssSTRectangle.ssllx, (float)ssRectangle[0].ssSTRectangle.sslly, (float)ssRectangle[0].ssSTRectangle.ssurx, (float)ssRectangle[0].ssSTRectangle.ssury), ssName);
if (ssValue!="")
tField.Text = ssValue;
if (ssIsMultiline)
tField.Options = TextField.MULTILINE;
tField.FontSize = ssFontSize;
tField.FieldName = ssName;
stamper.AddAnnotation(tField.GetTextField(), ssPage);
}
else
{
PdfFormField PtField = PdfFormField.CreateTextField(stamper.Writer, ssIsMultiline, false, 250);
PtField.Name=ssName;
foreach (RCRectangleRecord item in ssRectangle)
{
/*
tField=new TextField(stamper.Writer, new iTextSharp.text.Rectangle((float)ssRectangle[0].ssSTRectangle.ssllx, (float)ssRectangle[0].ssSTRectangle.sslly, (float)ssRectangle[0].ssSTRectangle.ssurx, (float)ssRectangle[0].ssSTRectangle.ssury), ssName);
tField.FieldName = ssName;
PtField.AddKid(tField.GetTextField());*/
PdfFormField widget = PdfFormField.CreateEmpty(stamper.Writer);
widget.SetWidget(new Rectangle((float)item.ssSTRectangle.ssllx, (float)item.ssSTRectangle.sslly, (float)item.ssSTRectangle.ssurx, (float)item.ssSTRectangle.ssury), PdfAnnotation.HIGHLIGHT_TOGGLE);
widget.Name = ssName;
PtField.AddKid(widget);
}
stamper.AddAnnotation(PtField, ssPage);
}
stamper.FormFlattening = false;
stamper.Close();
reader.Close();
ssPdfOut = output.ToArray();

Eclipse Plugin display data as table

I'm writing an Eclipse plugin that calls a program and will display the resulting data an a table in a view.
I have successfully gotten data from the call, but have not been able to display it.
here is my code (edited for brevity)
static Vector results ;
/**
* the command has been executed, so extract extract the needed information
* from the application context.
*/
public Object execute(ExecutionEvent event) throws ExecutionException {
try{
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
IWorkbenchPage pg = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage();
ObjectWhereUsedInputDialog gtid = new ObjectWhereUsedInputDialog(window.getShell());
ArrayList<Object> input = gtid.openDialog();
CallProgram callPrg = new CallProgram();
String callPCML = "callPcml";
int idx = (input.size()-1);
AS400 as400 = (AS400) input.get(idx);
input.remove(idx);
results = callPrg.callProgram(as400, input);
ObjectWhereUsedResultTableView dlg = new ObjectWhereUsedResultTableView(results);
public void createPartControl(Composite parent) {
Table myTable = new Table (parent, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL );
myTable.setHeaderVisible (true);
myTable.setLinesVisible (true);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
gridData.heightHint = 200;
myTable.setLayoutData(data);
String[] titles = getColumns(myTable);
for (int i=0; i<titles.length; i++) {
TableColumn column = new TableColumn (myTable, SWT.NONE);
column.setText (titles [i]);
}
if(data!=null){System.out.println("datag "+data.size());};
createTable(myTable, data);
for (int i=0; i<titles.length; i++) {
myTable.getColumn (i).pack ();
}
parent.layout(true);
parent.pack();
}
TableRow[] createTable(Table myTable, Vector<String> dataLines){
String[] columns = this.getColumns(myTable);
for (int i=0; i<columns.length; i++) {
TableColumn column = new TableColumn (myTable, SWT.NONE);
column.setText (columns[i]);
}
int dSize = dataLines==null||dataLines.isEmpty()?0:dataLines.size();
for(int i = 0;i<dSize;i++){
String[] elements = dataLines.get(i).split(",");
TableItem item = new TableItem (myTable, SWT.NONE);
for(int j = 0;j<elements.length;j++){
String itemStr = elements[j].isEmpty()?" ":elements[j];
item.setText(j,itemStr);
}
}
To show a view you must use IWorkbenchPage.showView:
ObjectWhereUsedResultTableView view = (ObjectWhereUsedResultTableView)pg.showView("the view id");
This will construct the view part using a no-argument public constructor:
public ObjectWhereUsedResultTableView()
{
...
}
You cannot pass arguments to the constructor.
To set data in the view you must add an extra method which you call after showing the view:
view.setData(data);
where setData is a method you write that updates the table with the data.
Note: You might find TableViewer easier to use than Table.

Render each PdfPCell on new page

I need to render each cell values in a new page.
I am using the following code :
List<string> values = getValues(); // getValues() method returns a list of strings
Document doc = new Document();
....
PdfPTable table = new PdfPTable(1);
foreach(var s in values)
{
table.AddCell(s);
doc.NewPage();
}
...
But I am getting the output in a single page.
Add a one-cell table on each page:
List<string> values = getValues(); // getValues() method returns a list of strings
Document doc = new Document();
....
foreach(var s in values)
{
PdfPTable table = new PdfPTable(1);
table.AddCell(s);
doc.add(table);
doc.NewPage();
}
...

iTextSharp line separator disappears with PdfPageEventHelper

I'm producing PDF reports using the iTextSharp library. I have a paragraph as title with a line underneath.
When I add an PdfPageEventHelper class as PageEventListener to my writer which handles the background and page numbering on each page, the line disappears. I think it's about the alignment of the background and the line so the line is behind the background but I can't seem to arrange it in front.
Document code:
using (Document doc = new Document())
{
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=IVIPS_report.pdf");
doc.SetPageSize(PageSize.A4.Rotate());
doc.SetMargins(36f, 36f, 36f, 70f);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
bckgr = Image.GetInstance(Request.MapPath(PDF_BACKGROUND_LANDSCAPE_PATH));
bckgr.Alignment = Image.UNDERLYING;
bckgr.SetAbsolutePosition(0, 0);
bckgr.ScaleToFit(doc.PageSize);
PdfWriter writer = PdfWriter.GetInstance(doc, Response.OutputStream);
MyPdfPageEventHelpPageNo PdfPageEvent = new MyPdfPageEventHelpPageNo();
writer.PageEvent = PdfPageEvent;
doc.Open();
Font title = new Font(Font.FontFamily.HELVETICA, 16f, Font.BOLD, BaseColor.DARK_GRAY);
Paragraph p = new Paragraph("Overzicht chauffeurs", title);
p.Alignment = Element.ALIGN_LEFT;
LineSeparator line = new LineSeparator(1f, 100f, BaseColor.DARK_GRAY, Element.ALIGN_CENTER, -27f);
doc.Add(p);
doc.Add(line);
}
PdfPageEvent code:
public class MyPdfPageEventHelpPageNo : iTextSharp.text.pdf.PdfPageEventHelper
{
public override void OnEndPage(PdfWriter writer, Document document)
{
document.Add(bckgr);
Font fFooter = new Font(Font.FontFamily.HELVETICA, 9f, Font.NORMAL, BaseColor.GRAY);
Rectangle page = document.PageSize;
PdfPTable pageFooter = new PdfPTable(1);
pageFooter.TotalWidth = page.Width;
Phrase pagenr = new Phrase("Gegenereerd op " + DateTime.Now.ToString("dd/MM/yyyy") + " - Pagina " + document.PageNumber, fFooter);
PdfPCell c = new PdfPCell(pagenr);
c.Border = Rectangle.NO_BORDER;
c.VerticalAlignment = Element.ALIGN_BOTTOM;
c.HorizontalAlignment = Element.ALIGN_CENTER;
pageFooter.AddCell(c);
pageFooter.WriteSelectedRows(0, -1, 0, 25, writer.DirectContent);
}
}