how to place two tables side by side using itext sharp - c#

I have to create a pdf file with two tables. and these two table should place horizontally in the document .I have tried out like this ,
var doc1 = new Document(PageSize.A4);
PdfWriter.GetInstance(doc1, new FileStream(path + "/" + pdf_name + "", FileMode.Create));
doc1.Open();
var table1 = new PdfPTable(1); //table1
table1.HorizontalAlignment = Element.ALIGN_LEFT;
table1.SpacingBefore = 50;
table1.DefaultCell.Border = 1;
table1.WidthPercentage = 40;
PdfPCell cell = new PdfPCell(new Phrase(student_name, boldTableFont));
// cell.Border = 1;
// cell.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
cell.HorizontalAlignment = Element.ALIGN_CENTER;
table1.AddCell(cell);
doc1.Add(table1);
var table2= new PdfPTable(1); //table2
table2.DefaultCell.Border = 1;
table2.HorizontalAlignment = 2;
table2.SpacingBefore = 50;
table2.WidthPercentage = 40;
PdfPCell cell21 = new PdfPCell(new Phrase("success", body));
cell21.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
table2.AddCell(cell21);
doc1.Add(table2);
doc1.Close();
but the second table is not come on the right side of table1 with spacingbefore=50. Please help me for finding out the problem

You may need to look at updating your layout to use columns (see here for more details):
http://www.mikesdotnetting.com/Article/89/iTextSharp-Page-Layout-with-Columns
Without seeing more about your layout it's hard to say which column based layout is best.
Alternatively you could absolutely position your tables and write them that way.
As a third option (which is very much like an old html page), you could nest tables like this:
PdfPTable outer = new PdfPTable(2);
outer.AddCell(table1);
outer.AddCell(table2);
document.Add(outer);

The answer that Paddy said helped me a lot.
First I created the 2 tables the way I wanted.
Then I used Paddy's 3rd example, my code looked like this:
// Tabela para os trajetos de ida
var tablePercursosIda = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
foreach (var item in Content.itinerarios)
{
foreach (var percurso in item.percursos.ida)
{
tablePercursosIda.AddCell(new Cell()
.Add(new Paragraph(
new Text(percurso.logradouroNome)
)
.SetTextAlignment(TextAlignment.CENTER)
.SetBold()
)
).SetFontSize(10);
}
}
// Tabela para os trajetos de volta
var tablePercursosVolta = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
foreach (var item in Content.itinerarios)
{
foreach (var percurso in item.percursos.volta)
{
tablePercursosVolta.AddCell(new Cell()
.Add(new Paragraph(
new Text(percurso.logradouroNome)
)
.SetTextAlignment(TextAlignment.CENTER)
.SetBold()
)
).SetFontSize(10);
}
}
// Tabela aninhada
var tableAninhada = new Table(UnitValue.CreatePercentArray(2)).UseAllAvailableWidth();
tableAninhada.AddCell(tablePercursosIda);
tableAninhada.AddCell(tablePercursosVolta);
table.SetHorizontalAlignment(HorizontalAlignment.CENTER);
Report.Document.Add(table);
Report.Document.Add(tableAninhada);
The result below, I will need to improve the layout, but it was as I needed
Result

Related

How to sum the values of all rows in a column that has been dynamically generated?

Good Morning Fellow Coders,
I am trying to Sum all values in each row of a specific Column called SubTotal
SubTotal needs to sum from the LineTotal of every row, but the rows are generated dynamically and on a button click event. I will link my code down below and a screen shot and maybe one of you can help me:
EDIT: - I have tried all the "Solutions" below but each time i try to add that to my page it makes it that my PDF has no pages, i have tried doing my own research too, to no avail as those also make it that my pdf has no pages
tried these:-
(1)int sum = Convert.ToInt32(dt.Compute("SUM(Salary)", string.Empty));
(2)DataTable dt= dataSet.Tables["YourTableName"];
object lineTotalInputSum ;
lineTotalInputSum = dt.Compute("Sum("YourColumnName")", string.Empty);
(3)var subTotal= rows.Sum(row => row.Field<double>("LineTotal"));
i am not saying any of you are wrong, i am saying that i am not sure how to implement these suggestions into my code and keep the rest working, if you could give me a simple explanation i will do my best to make it work, feel free to ask for any additional code that i have not provided
------END EDIT--------
foreach (DataRow dataRow in dt.Rows)
{
//Adding dt.Rows to Strings for Use in iTextSharp
string lineNumberInput = dataRow[1].ToString();
string itemCodeInput = dataRow[12].ToString();
string itemNameInput = dataRow[13].ToString();
string QtyInput = dataRow[14].ToString();
string UnitPriceInput = dataRow[15].ToString();
//string Discount = dt.Rows[0][""].ToString();
string lineTotalInput = dataRow[16].ToString();
string wasReturnedInput = dataRow[17].ToString();
//Implementing strings in iTextSharp
var Cell_LineNumberList = new PdfPCell(new
Phrase(lineNumberInput, tablefont));
var Cell_ItemCodelist = new PdfPCell(new
Phrase(itemCodeInput, tablefont));
var Cell_ItemNamelist = new PdfPCell(new
Phrase(itemNameInput, tablefont));
var Cell_Qtylist = new PdfPCell(new Phrase(QtyInput,
tablefont));
var Cell_UnitPricelist = new PdfPCell(new
Phrase(UnitPriceInput, tablefont));
var Cell_Discountlist = new PdfPCell(new
Phrase("None", tablefont));
var Cell_LineTotallist = new PdfPCell(new
Phrase(lineTotalInput, tablefont));
var Cell_WasReturnedlist = new PdfPCell(new
Phrase(wasReturnedInput, tablefont));
//Aligning all the cells
Cell_LineNumberList.HorizontalAlignment =
Element.ALIGN_CENTER;
Cell_ItemCodelist.HorizontalAlignment =
Element.ALIGN_CENTER;
Cell_ItemNamelist.HorizontalAlignment =
Element.ALIGN_CENTER;
Cell_Qtylist.HorizontalAlignment =
Element.ALIGN_CENTER;
Cell_UnitPricelist.HorizontalAlignment =
Element.ALIGN_CENTER;
Cell_Discountlist.HorizontalAlignment =
Element.ALIGN_CENTER;
Cell_LineTotallist.HorizontalAlignment =
Element.ALIGN_CENTER;
Cell_WasReturnedlist.HorizontalAlignment =
Element.ALIGN_CENTER;
//adding the cells to the table
t.AddCell(Cell_LineNumberList);
t.AddCell(Cell_ItemCodelist);
t.AddCell(Cell_ItemNamelist);
t.AddCell(Cell_Qtylist);
t.AddCell(Cell_UnitPricelist);
t.AddCell(Cell_Discountlist);
t.AddCell(Cell_LineTotallist);
t.AddCell(Cell_WasReturnedlist);
}
Below you will find a screen shot of the column I want to sum in red and the value(from where the values come) column in green * these are all dynamically generated*
If you can just show me how to store it in a var then i can take it from there
and thank you in advance.
I am not quite sure how your DataTable looks like but you use the Compute method to get the sum of the column that you want:
DataTable dt= dataSet.Tables["YourTableName"];
object lineTotalInputSum ;
lineTotalInputSum = dt.Compute("Sum("YourColumnName")", string.Empty);
Try using the LINQ on the "Line Total" Column outside your foreach loop as follows
var subTotal= rows.Sum(row => row.Field<double>("LineTotal"));
or as you are processing row by row, use a old school method of having a variable and adding the row values to it.
Hope this helps!

Aspose pdf table

i have added a table with two rows and two columns and set border to all cells. but it shows the border only for first column
Sample code is shown below
var tableestdet = new Table
{
ColumnWidths = "120,120",
Margin = new MarginInfo { Top = 40, Left = 10 },
DefaultCellBorder = new BorderInfo((int)BorderSide.All, 1F),
};
tableestdet.DefaultCellTextInfo = new TextInfo { Alignment = AlignmentType.Center };
var estdet1 = tableestdet.Rows.Add();
estdet1.DefaultRowCellPadding = new MarginInfo { Top = 5, Bottom = 5 };
var req=estdet1.Cells.Add("Requested By:");
var estde=estdet1.Cells.Add("Entered By:");
var estdet2 = tableestdet.Rows.Add();
estdet2.DefaultCellTextInfo = new TextInfo
{
FontSize = 8,
Alignment = AlignmentType.Center
};
estdet2.DefaultRowCellPadding = new MarginInfo { Top = 5, Bottom = 5 };
estdet2.Cells.Add(Requestedby);
estdet2.Cells.Add(CustomerName);
sec1.Paragraphs.Add(tableestdet);
We have noticed that you are working with an outdated version of the API so please upgrade to Aspose.PDF for .NET 19.2 which is latest available version of the API as it includes more features and bug fixes. You may use below code snippet to add a table on page of PDF document, while setting borders for all cells.
// Load source PDF document
Aspose.Pdf.Document document = new Aspose.Pdf.Document();
// Add a page to the document
Page page = document.Pages.Add();
// Initializes a new instance of the Table
Aspose.Pdf.Table table = new Aspose.Pdf.Table();
// Set the table border color as LightGray
table.Border = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.All, .5f, Aspose.Pdf.Color.FromRgb(System.Drawing.Color.LightGray));
// Set the border for table cells
table.DefaultCellBorder = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.All, .5f, Aspose.Pdf.Color.FromRgb(System.Drawing.Color.LightGray));
// Create a loop to add 10 rows
for (int row_count = 1; row_count <= 10; row_count++)
{
// Add row to table
Aspose.Pdf.Row row = table.Rows.Add();
// Add table cells
row.Cells.Add("Column (" + row_count + ", 1)");
row.Cells.Add("Column (" + row_count + ", 2)");
}
// Add table object to first page of input document
page.Paragraphs.Add(table);
// Save updated document containing table object
document.Save(dataDir + "Table_19.2.pdf");
Generated PDF document has been attached for your kind reference Table19.2.pdf. Please feel free to let us know if you need any further assistance.
PS: I work with Aspose as Developer Evangelist.

iTextSharp - How can I iterate tables side by side in C# winforms?

I have a book library and I want to print library labels for them. When you select books from GridControl and click Print Labels button, the program creates labels on a pdf file like this:
private void btnQRPrintLabels_Click(object sender, EventArgs e)
{
// These are books' ids. Normally, these are retrieved from GridControl element.
var books_ids = new List<int>() {1, 2, 5, 6, 7, 12};
// I don't use PanelControl. But in the future, maybe I can use it later.
CreateLabels(books_ids, panelControl1);
}
And here is the contents of CreateLabels method:
public void CreateLabels(List<int> books_ids, PanelControl p)
{
var doc = new Document(PageSize.A4, 10, 10, 10, 10);
var m = new SaveFileDialog
{
Filter = #"PDF File Format|*.pdf",
FileName = "Labels.pdf"
};
if (m.ShowDialog() != DialogResult.OK) return;
var file = new FileStream(m.FileName, FileMode.Create);
wr = PdfWriter.GetInstance(doc, file);
doc.Open();
cb = wr.DirectContent;
wr.PageEvent = this;
// Labels are created from this method.
Labels(doc, books_ids);
doc.Close();
}
Finally, the contents of Labels method:
protected void Labels(Document doc, List<int> books_ids)
{
var i = 1;
foreach (var book_id in books_ids)
{
var alignment = (i % 2 != 0) ? Element.ALIGN_LEFT : Element.ALIGN_RIGHT;
// Book's informations are retrieved from Linq Connect Model.
var _connection = new LinqtoSQLiteDataContext();
var book = _connection.books.SingleOrDefault(b_no => b_no.id == book_id);
// Outer table to get rounded corner...
var table = new PdfPTable(1) { WidthPercentage = 48, HorizontalAlignment = alignment };
// Inner table: First cell for QR code and second cell for book's informations.
var inner_table = new PdfPTable(2) { WidthPercentage = 100 };
inner_table.DefaultCell.Border = Rectangle.NO_BORDER;
var inner_measurements = new[] { 40f, 60f };
inner_table.SetWidths(inner_measurements);
// Generate QR code in the `Tools` class, `GenerateQR` method.
System.Drawing.Image image = Tools.GenerateQR(100, 100, book?.isbn);
var pdfImage = iTextSharp.text.Image.GetInstance(image, System.Drawing.Imaging.ImageFormat.Jpeg);
var qr = iTextSharp.text.Image.GetInstance(pdfImage);
var a = new PdfPCell(qr) { Border = Rectangle.NO_BORDER };
var b = new PdfPCell(new Phrase(book?.name, font_normal)) { Border = Rectangle.NO_BORDER };
inner_table.AddCell(a);
inner_table.AddCell(b);
var s = new PdfPCell(inner_table)
{
CellEvent = new RoundRectangle(),
Border = Rectangle.NO_BORDER,
Padding = 2,
HorizontalAlignment = Element.ALIGN_LEFT
};
table.AddCell(s);
doc.Add(table);
i++;
}
}
These codes bring me labels like this:
But I want to get labels like this:
Because if I manage getting labels side by side, I print it to computer labels easily. Here is the computer label that I want to print to on it:
How can I iterate tables side by side?
Use one outer Table with
new PdfPTable(2) { WidthPercentage = 100 }
Then add all your inner tables to this one and at last add the outer table to the document. This way there is NO need to use that toggeling left/right alignment.
:edit:
var table = new PdfPTable(2) { WidthPercentage = 100 };
foreach (var book_id in books_ids)
{
// Book's informations are retrieved from Linq Connect Model.
var _connection = new LinqtoSQLiteDataContext();
var book = _connection.books.SingleOrDefault(b_no => b_no.id == book_id);
// Outer table to get rounded corner...
// Inner table: First cell for QR code and second cell for book's informations.
var inner_table = new PdfPTable(2) { WidthPercentage = 100 };
inner_table.DefaultCell.Border = Rectangle.NO_BORDER;
var inner_measurements = new[] { 40f, 60f };
inner_table.SetWidths(inner_measurements);
// Generate QR code in the `Tools` class, `GenerateQR` method.
System.Drawing.Image image = Tools.GenerateQR(100, 100, book?.isbn);
var pdfImage = iTextSharp.text.Image.GetInstance(image, System.Drawing.Imaging.ImageFormat.Jpeg);
var qr = iTextSharp.text.Image.GetInstance(pdfImage);
var a = new PdfPCell(qr) { Border = Rectangle.NO_BORDER };
var b = new PdfPCell(new Phrase(book?.name, font_normal)) { Border = Rectangle.NO_BORDER };
inner_table.AddCell(a);
inner_table.AddCell(b);
PdfPCell labelCell = new PdfPCell(inner_table)
{
CellEvent = new RoundRectangle(),
Border = Rectangle.NO_BORDER,
Padding = 2,
HorizontalAlignment = Element.ALIGN_LEFT
};
table.AddCell(labelCell);
}
doc.Add(table);
Just add page-level table (2 columns, 6 rows) and place each label into individual cell in this page-level table.

Spacing/Leading PdfPCell's elements

Is it possible to add space between the elements of a cell (rows) in C#?
I'm creating a pdf in visual studio 2012 and wanted to set some space between the rows. I have something like this:
PdfPTable cellTable = new PdfPTable(1);
PdfPCell cell= new PdfPCell();
for(i=0; i < 5; i++)
{
var titleChunk = new Chunk(tittle[i], body);
var descriptionChunk = new Chunk(" " description[i], body2);
var phrase = new Phrase(titleChunk);
phrase.Add(descriptionChunk);
cell.AddElement(phrase);
}
cellTable.AddCell(cell);
OK, I've made you an example named LeadingInCell:
PdfPCell cell = new PdfPCell();
Paragraph p;
p = new Paragraph(16, "paragraph 1: leading 16");
cell.addElement(p);
p = new Paragraph(32, "paragraph 2: leading 32");
cell.addElement(p);
p = new Paragraph(10, "paragraph 3: leading 10");
cell.addElement(p);
p = new Paragraph(18, "paragraph 4: leading 18");
cell.addElement(p);
p = new Paragraph(40, "paragraph 5: leading 40");
cell.addElement(p);
As you can see in leading_in_cell.pdf, you define the space between the lines using the first parameter of the Paragraph constructor. I've used different values to demonstrate how it works. The third paragraph sticks to the second one, because the leading of the third paragraph is only 10 pt. There's plenty of space between the fourth and the fifth paragraph, because the leading of the fifth paragraph is 40 pt.

Fill PDFP Table Cell with Dots

I have a PDFP Table and I want to have it laid out like so:
Item1 ............ $10.00
Item1123123 ...... $50.00
Item3 ............ $75.00
This is what I have so far:
var tableFont = FontFactory.GetFont(FontFactory.HELVETICA, 7);
var items = from p in ctx.quote_server_totals
where p.item_id == id
&& p.name != "total"
&& p.type != "totals"
select p;
foreach (var innerItem in items)
{
detailsTable.AddCell(new Phrase(innerItem.type == "discount" ? "ADJUSTMENT -" + innerItem.name : innerItem.name, tableFont));
detailsTable.AddCell(new Phrase(".......................................................", tableFont));
detailsTable.AddCell(new Phrase(Convert.ToDecimal(innerItem.value).ToString("c"), tableFont));
}
document.Add(detailsTable);
As can see, the only way I've been able to get the dots to extend is by manually entering them; however, this obviously won't work because the the first column's width will be different every time I run this code. Is there a way I can accomplish this? Thanks.
Please download chapter 2 of my book and search for DottedLineSeparator. This separator class will draw a dotted line between two parts of a Paragraph (as shown in the figures in the book). You can find the C# version of the Java book samples here.
If you can use a fixed-width font such as FontFactory.COURIER your task will be a lot easier.
//Our main font
var tableFont = FontFactory.GetFont(FontFactory.COURIER, 20);
//Will hold the shortname from the database
string itemShortName;
//Will hold the long name which includes the periods
string itemNameFull;
//Maximum number of characters that will fit into the cell
int maxLineLength = 23;
//Our table
var t = new PdfPTable(new float[] { 75, 25 });
for (var i = 1; i < 10000; i+=100) {
//Get our item name from "the database"
itemShortName = "Item " + i.ToString();
//Add dots based on the length
itemNameFull = itemShortName + ' ' + new String('.', maxLineLength - itemShortName.Length + 1);
//Add the two cells
t.AddCell(new PdfPCell(new Phrase(itemNameFull, tableFont)) { Border = PdfPCell.NO_BORDER });
t.AddCell(new PdfPCell(new Phrase(25.ToString("c"), tableFont)) { Border = PdfPCell.NO_BORDER });
}

Categories