Spacing/Leading PdfPCell's elements - c#

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.

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!

Italic inline word with Interop.Word

I've starting learning C#, mostly for the purpose of MS Word automation. Using Interop.Word, how can I add a line with words "one two three" with two being italic? The closest I can get is something like this:
//text with some italic words.
para.Range.Text = "one ";
Console.WriteLine(para.Range.Start);
Console.WriteLine(para.Range.End);
// <some magic methods that end the last range and start a new one in place>
para.Range.Text = "two";
para.Range.Font.Italic = 1;
Console.WriteLine(para.Range.Start);
Console.WriteLine(para.Range.End);
// <some magic methods that end the last range and start a new one in place>
para.Range.Text = " three";
Console.WriteLine(para.Range.Start);
Console.WriteLine(para.Range.End);
para.Range.InsertParagraphAfter();
As for the method I need, I tried many things, but none of them worked. The MSDN documentation is very hard to read and omit many important details.
EDIT: I finally made it worked, by creating a new range object for every word. This is about as ugly as I could imagine but as least it works:
Word.Range rng = word_doc.Range(para.Range.End - 1, para.Range.End);
rng.Text = "one ";
Console.WriteLine(rng.Start);
Console.WriteLine(rng.End);
rng = word_doc.Range(rng.End - 1, rng.End);
rng.Text = "two";
rng.Font.Italic = 1;
Console.WriteLine(rng.Start);
Console.WriteLine(rng.End);
rng = word_doc.Range(rng.End - 1, rng.End);
rng.Text = " three";
rng.Font.Italic = 0;
Console.WriteLine(rng.Start);
Console.WriteLine(rng.End);
para.Range.InsertParagraphAfter();
This is the closest I could get, the main issue with this code I made for you is that it doesn't add the text back inline, but instead adds a new line for each word it finds. Hopefully this code gives you some ideas on how to best programmatically create word documents!
Document extendedDocument = Globals.Factory.GetVstoObject(Globals.ThisAddIn.Application.ActiveDocument);
Word.Selection currentSelection = Globals.ThisAddIn.Application.Selection;
Word.Paragraph para;
para = extendedDocument.Content.Paragraphs.Add(ref oMissing);
para.Range.SetRange(currentSelection.Range.Start, currentSelection.Range.End);
string string1 = "one two three";
string split1 = " ";
string match1 = "two";
string[] elements = Regex.Split(string1, split1);
foreach (var m in elements)
{
if (m.Equals(match1))
{
para.Range.Text = m + " ";
para.Range.Font.Italic = 1;
}
else
{
para.Range.Text = m + " ";
para.Range.Font.Italic = 0;
}
para.Range.InsertParagraphAfter();
}
Edit: Have a good weekend! I will try to check my SO inbox over the weekend, but I may not reply to any questions till Monday.

how to place two tables side by side using itext sharp

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

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 });
}

itext keep paragraphs together

I have 2 paragraph objects that take up about 2/3 of the page. When I view it in the pdf the start of the 2nd paragraph starts on the 2nd page. Is there a way to start it on 1st page following the 1st paragraph?
PdfPTable rs1 = new PdfPTable(1);
PdfPCell c = new PdfPCell();
c.MinimumHeight = 36f;
Paragraph p = new Paragraph(
"some text to align\n" +
"..." +
"some text to align\n"
);
c.AddElement(p);
rs1.AddCell(c);
PdfPCell c2 = new PdfPCell();
c.MinimumHeight = 36f;
Paragraph p2 = new Paragraph(
"some text to align\n" +
"..." +
"some text to align\n" +
"some text to align\n"
);
p2.KeepTogether = false;
c2.AddElement(p2);
c2.VerticalAlignment = Element.ALIGN_TOP;
rs1.AddCell(c2);
return rs1;
I used PdfPTable.SplitLate = false
The issue isn't with your paragraphs but with your table. iTextSharp tries to not break content across table cells and your current layout appears to do that. Do you need to have a table? Regular paragraphs will just break when a line goes off the viewable area. If you need tables then you'll have to adjust the table's width if you can (rs1.WidthPercentage = 100;) and possibly any padding that you've set up.

Categories