I'm trying to add a horizontal line on top to divide the header text from the actual values in my pdf file:
Here's my code:
public class StudentList
{
public void PrintStudentList(int gradeParaleloID)
{
StudentRepository repo = new StudentRepository();
var students = repo.FindAllStudents()
.Where(s => s.IDGradeParalelo == gradeParaleloID);
try
{
Document document = new Document(PageSize.LETTER);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\Alumnos.pdf", FileMode.Create));
document.Open();
PdfContentByte cb = writer.DirectContent;
cb.SetLineWidth(2.0f); // Make a bit thicker than 1.0 default
cb.SetGrayStroke(0.95f); // 1 = black, 0 = white
cb.MoveTo(20, 30);
cb.LineTo(400, 30);
cb.Stroke();
PdfPTable table = new PdfPTable(3);
float[] widths = new float[] { 0.6f, 0.75f, 2f };
table.SetWidths(widths);
PdfPCell numeroCell = new PdfPCell(new Phrase("Nro."));
numeroCell.Border = 0;
numeroCell.HorizontalAlignment = 0;
table.AddCell(numeroCell);
PdfPCell codigoCell = new PdfPCell(new Phrase("RUDE"));
codigoCell.Border = 0;
codigoCell.HorizontalAlignment = 0;
table.AddCell(codigoCell);
PdfPCell nombreCell = new PdfPCell(new Phrase("Apellidos y Nombres"));
nombreCell.Border = 0;
nombreCell.HorizontalAlignment = 0;
table.AddCell(nombreCell);
int c = 1;
foreach (var student in students)
{
PdfPCell cell = new PdfPCell(new Phrase(c.ToString()));
cell.Border = 0;
cell.HorizontalAlignment = 0;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(student.Rude.ToString()));
cell.Border = 0;
cell.HorizontalAlignment = 0;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(student.LastNameFather + " " + student.LastNameMother + " " + student.Name));
cell.Border = 0;
cell.HorizontalAlignment = 0;
table.AddCell(cell);
c++;
}
table.SpacingBefore = 20f;
table.SpacingAfter = 30f;
document.Add(table);
document.Close();
}
catch (DocumentException de)
{
Debug.WriteLine(de.Message);
}
catch (IOException ioe)
{
Debug.WriteLine(ioe.Message);
}
}
}
I don't understand why the cb.Stroke() isn't working. Any suggestions?
Drawing with iTextSharp's PdfContentByte class can be a little confusing. The height is actually relative to the bottom, not the top. So the top of the page is not 0f, but instead is actually document.Top, which on your page size of PageSize.LETTER is 726f. So if you want to draw your line 30 units from the top, try:
cb.MoveTo(20, document.Top - 30f);
cb.LineTo(400, document.Top - 30f);
Just curious -- why do it the hard way instead of using table borders? (I noticed you set your borders to 0) Trying to space out lines by hand is the biggest pain. If you ever move content in your PDF around, you'll have to make sure your measurements still work.
Try this:
numeroCell.Border = 0;
numeroCell.BorderColorBottom = new BaseColor(System.Drawing.Color.Black);
numeroCell.BorderWidthBottom = 1f;
codigoCell.Border = 0;
codigoCell.BorderColorBottom = new BaseColor(System.Drawing.Color.Black);
codigoCell.BorderWidthBottom = 1f;
nombreCell.Border = 0;
nombreCell.BorderColorBottom = new BaseColor(System.Drawing.Color.Black);
nombreCell.BorderWidthBottom = 1f;
That should give you a nice solid black line under your header row, no measurements needed:
Related
Need some help here. I'm trying text within a row looks in the same horizontal line as it's corresponding dotted lines
This is the result
And this is the part of my code related to the image:
Font coverHeaderFont = new Font(Font.FontFamily.HELVETICA, 18, Font.BOLD, BaseColor.BLACK);
Font tableContentFont = new Font(Font.FontFamily.HELVETICA, 16, Font.BOLDITALIC, BaseColor.BLACK);
Font textIndexFont = new Font(Font.FontFamily.HELVETICA, 11, Font.BOLD, BaseColor.BLACK);
Font invisibleFont = new Font(Font.FontFamily.HELVETICA, 11, Font.BOLD, BaseColor.WHITE);
Font underText = new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD | Font.ITALIC, BaseColor.BLACK);
//table creation
PdfPTable tblCon = new PdfPTable(3); //3 columns
tblCon.WidthPercentage = 90f; //wide %
tblCon.HorizontalAlignment = 1; //centered
//tblCon.LockedWidth = true;
//relative col widths in proportions - 1/3 and 2/3
float[] widths = new float[] { 4f, 6f, 2f };//{ 6f, 4f, 2f };
tblCon.SetWidths(widths);
//leave a gap before and after the table
tblCon.SpacingBefore = 20f;
tblCon.SpacingAfter = 30f;
//Header Cell
string appHeader = "Applications";
Chunk cAppHeader = new Chunk(appHeader, underText);
// CELLS
PdfPCell cellName = new PdfPCell();
cellName.PaddingTop = 10f;
cellName.VerticalAlignment = PdfPCell.ALIGN_TOP;
cellName.BorderWidth = 1;
cellName.MinimumHeight = 30f;
//cellName.HorizontalAlignment = 0; //0=Left, 1=Center, 2=Right
PdfPCell cellSeparator = new PdfPCell();
cellSeparator.PaddingTop = 10f;
cellSeparator.VerticalAlignment = PdfPCell.ALIGN_TOP;
cellSeparator.BorderWidth = 1;
cellSeparator.MinimumHeight = 20f;
PdfPCell cellPage = new PdfPCell();
cellPage.PaddingTop = 10f;
cellPage.VerticalAlignment = PdfPCell.ALIGN_TOP;
cellPage.BorderWidth = 1;
cellPage.MinimumHeight = 30f;
for (int i = 0; i < listOfDetailsPDF.Count; i++)
{
if (i == 0) //first column, just header
{
cellName.AddElement(new Paragraph(cAppHeader));
cellSeparator.AddElement(new Paragraph(".", invisibleFont));
cellPage.AddElement(new Paragraph("1", invisibleFont));
}
var obj = listOfDetailsPDF[i];
String title = (string)obj.GetType().GetProperty("applicantName").GetValue(obj, null);
Chunk cTitle = new Chunk(title, textIndexFont);
int pNPage = (int)obj.GetType().GetProperty("pdfPages").GetValue(obj, null);
String numberPage = pNPage.ToString();
Chunk cNumPage = new Chunk(numberPage, textIndexFont);
cellName.AddElement(new Paragraph(cTitle));
cellSeparator.AddElement(new Paragraph(dottedLine));
cellPage.AddElement(new Paragraph(cNumPage));
}
tblCon.Rows.Add(new PdfPRow(new PdfPCell[] { cellName, cellSeparator, cellPage }));
I just want: the name with the dotted line with the number page look in the same line in every row.
Thank you
I have used iTextSharp to generate a PDF file.
I have created 6 PdfPTables but it shows only 3.
// Create new PDF document
Document document = new Document(PageSize.A4, 20f, 20f, 20f, 20f);
try {
PdfWriter writer = PdfWriter.GetInstance(document,
new FileStream(filename, FileMode.Create));
document.Open();
int spacing = 0;
for (int i = 0; i <= 6; i++) {
PdfPTable table = new PdfPTable(2);
table.TotalWidth = 144f;
table.LockedWidth = false;
PdfPCell cell = new PdfPCell(new Phrase("This is table" + i));
cell.Colspan = 3;
cell.HorizontalAlignment = 1;
table.AddCell(cell);
table.WriteSelectedRows(0, -1,
document.Left + spacing, document.Top,
writer.DirectContent);
spacing = spacing + 200;
}
}
catch (Exception ex) {}
finally {
document.Close();
ShowPdf(filename);
}
Here I have put the for loop for 6 times but it shows only 3 table.
How can I show all 6 tables? I want to show only 3 table in 1 line after that break to new line and display other 3 tables.
I think the title of your question pretty much sums up the problem actually.
When you use WriteSelectedRows it is your responsibility to provide the X and Y locations to write to and you are drawing outside of the page boundaries. A4 has 595 horizontal units and there's just not enough room. This is 100% valid however most people won't see it. I'm guessing that you want to "wrap" your table to the next line. There's a couple of ways of doing that:
Bigger page size
Switch to something like PageSize.A0 and you should have more room. The page size is just a hint, anyway, print software will scale as needed.
MOD check in loop
This is the little more complicated one but every n tables you reset the x coordinate to the left edge and increase your y by the tallest of the previous row of tables.
int spacing = 0;
//The current Y position
float curY = document.Top;
//Well ask iText how tall each table was and set the tallest to this variable
float lineHeight = 0;
//Maximum number of tables that go on a line
const int maxPerLine = 3;
for (int i = 0; i <= 6; i++) {
PdfPTable table = new PdfPTable(2);
table.TotalWidth = 144f;
table.LockedWidth = false;
PdfPCell cell = new PdfPCell(new Phrase("This is table" + i));
cell.Colspan = 3;
cell.HorizontalAlignment = 1;
table.AddCell(cell);
table.WriteSelectedRows(0, -1,
document.Left + spacing, curY,
writer.DirectContent);
spacing = spacing + 200;
//Set the height to whichever is taller, the last table or this table
lineHeight = Math.Max(lineHeight, table.TotalHeight);
//If we're at the "last" spot in the "row"
if (0 == (i + 1) % maxPerLine) {
//Offset our Y by the tallest table
curY -= lineHeight;
//Reset "row level" variables
spacing = 0;
lineHeight = 0;
}
}
Wrapper table
This is what I really recommend. If you want to "wrap" tables then just use an outer table to hold your inner tables and you get everything for free and you don't have to mess with DirectContent (although you'll probably want to change table borders).
var outerTable = new PdfPTable(3);
outerTable.DefaultCell.Border = PdfPCell.NO_BORDER;
for (int i = 0; i <= 6; i++) {
PdfPTable innerTable = new PdfPTable(2);
innerTable.TotalWidth = 144f;
innerTable.LockedWidth = false;
PdfPCell cell = new PdfPCell(new Phrase("This is table" + i));
cell.Colspan = 3;
cell.HorizontalAlignment = 1;
innerTable.AddCell(cell);
outerTable.AddCell(innerTable);
}
document.Add(outerTable);
I want to add an image next to a table without a newline. I have following code:
iTextSharp.text.Font font = new iTextSharp.text.Font(FontFactory.GetFont("Arial", 8, iTextSharp.text.Font.NORMAL));
iTextSharp.text.Font fontbold = new iTextSharp.text.Font(FontFactory.GetFont("Arial", 8, iTextSharp.text.Font.BOLD));
PdfPTable tkunde = new PdfPTable(1);
tkunde.WidthPercentage = 30;
tkunde.HorizontalAlignment = Element.ALIGN_LEFT;
PdfPCell labkunNavn = new PdfPCell(new Phrase(navnn, fontbold));
labkunNavn.PaddingTop = 2f;
labkunNavn.HorizontalAlignment = Element.ALIGN_LEFT;
labkunNavn.Border = 0;
tkunde.AddCell(labkunNavn);
PdfPCell labkunAdresse = new PdfPCell(new Phrase(adresse, font));
labkunAdresse.PaddingTop = 2f;
labkunAdresse.HorizontalAlignment = Element.ALIGN_LEFT;
labkunAdresse.Border = 0;
tkunde.AddCell(labkunAdresse);
PdfPCell labkunPost = new PdfPCell(new Phrase(postnr + " " + område, font));
labkunPost.PaddingTop = 2f;
labkunPost.HorizontalAlignment = Element.ALIGN_LEFT;
labkunPost.Border = 0;
tkunde.AddCell(labkunPost);
doc.Add(tkunde);
iTextSharp.text.Image png = iTextSharp.text.Image.GetInstance(#"C:\Users\Osman\Desktop\download.jpg");
png.WidthPercentage = 10;
png.ScalePercent(50F);
png.Alignment = Element.ALIGN_RIGHT;
doc.Add(png);
But it adds the image below the table as shown in the figure on following link:
http://postimg.org/image/z9rr0dk5p/4289a76a/
I want the layout to be like this instead:
http://postimg.org/image/3yae8w6q3/42ddcd80/
How do I achieve this ?.
Thanks in advance
I'm attempting to create a PDF from a DataGridView populated from a database.
I have just started trying to learn how to use iTextSharp to accomplish this.
The result of my code is a PDF that will not open. I get an error saying "File cannot be opened"
Here is my code to generate the PDF
void SendToPDF(string heading, string filename)
{
try
{
Document doc = new Document(PageSize.A4.Rotate(), 30, 30, 20, 20);
string myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (!Directory.Exists(myDocs + #"\Production Reports"))
Directory.CreateDirectory(myDocs + #"\Production Reports");
PdfWriter.GetInstance(doc, new FileStream(myDocs + #"\Production Reports\" + filename + ".pdf", FileMode.Append, FileAccess.Write));
iTextSharp.text.Font titleFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 14.0F, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
iTextSharp.text.Font tableFont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 12.0F, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
iTextSharp.text.Font headerfont = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 12.0F, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
PdfPTable table = new PdfPTable(GridView.Columns.Count);
//table.TotalWidth = GridView.Width;
//There are ALWAYS 10 columns
float[] widths = new float[] { GridView.Columns[0].Width, GridView.Columns[1].Width, GridView.Columns[2].Width,
GridView.Columns[3].Width, GridView.Columns[4].Width, GridView.Columns[5].Width,
GridView.Columns[6].Width, GridView.Columns[7].Width, GridView.Columns[8].Width,
GridView.Columns[9].Width };
table.SetWidths(widths);
table.HorizontalAlignment = 1; // 0 - left, 1 - center, 2 - right;
table.SpacingBefore = 2.0F;
PdfPCell cell = null;
doc.Open();
Phrase p = new Phrase(new Chunk(heading, titleFont));
doc.Add(p);
foreach (DataGridViewColumn c in GridView.Columns)
{
cell = new PdfPCell(new Phrase(new Chunk(c.HeaderText, headerfont)));
cell.HorizontalAlignment = PdfPCell.ALIGN_CENTER;
cell.VerticalAlignment = PdfPCell.ALIGN_CENTER;
table.AddCell(cell);
}
if (GridView.Rows.Count > 0)
{
for (int i = 0; i < GridView.Rows.Count - 1; i++)
{
for (int j = 0; j < GridView.Columns.Count - 1; j++)
{
cell = new PdfPCell(new Phrase(GridView.Rows[i].Cells[j].Value.ToString(), tableFont));
cell.HorizontalAlignment = PdfPCell.ALIGN_CENTER;
cell.VerticalAlignment = PdfPCell.ALIGN_CENTER;
table.AddCell(cell);
}
}
}
doc.Add(table);
doc.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace, "Error Generating PDF", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
I'm guessing my problem has to do with setting column widths, but I'm not sure. One time, and only one time..I saw an error when I tried to open the PDF that said "illegal floating point division by 0" or something along those lines.
Any help is greatly appreciated.
It may sound obvious, but your program isn't running and locking the pdf file to its process thus preventing adobe pdf reader from reading it is it?
private void jbtnPdf_Click(object sender, EventArgs e)
{
try
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "All Files | *.* ";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
string path = saveFileDialog.FileName;
Document pdfdoc = new Document(PageSize.A4); // Setting the page size for the PDF
PdfWriter writer = PdfWriter.GetInstance(pdfdoc, new FileStream(path + ".pdf", FileMode.Create)); //Using the PDF Writer class to generate the PDF
writer.PageEvent = new PDFFooter();
// Opening the PDF to write the data from the textbox
PdfPTable table = new PdfPTable(jdgvChild.Columns.Count);
//table.TotalWidth = GridView.Width;
float[] widths = new float[] { jdgvChild.Columns[0].Width, jdgvChild.Columns[1].Width, jdgvChild.Columns[2].Width,
jdgvChild.Columns[3].Width, jdgvChild.Columns[4].Width, jdgvChild.Columns[5].Width,
jdgvChild.Columns[6].Width, jdgvChild.Columns[7].Width};
table.SetWidths(widths);
table.HorizontalAlignment = 1; // 0 - left, 1 - center, 2 - right;
table.SpacingBefore = 2.0F;
PdfPCell cell = null;
pdfdoc.Open();
//doc.Open();
// Phrase p = new Phrase(new Chunk(heading, titleFont));
// doc.Add(p);
foreach (GridViewDataColumn c in jdgvChild.Columns)
{
cell = new PdfPCell(new Phrase(new Chunk(c.HeaderText)));
cell.HorizontalAlignment = PdfPCell.ALIGN_CENTER;
cell.VerticalAlignment = PdfPCell.ALIGN_CENTER;
table.AddCell(cell);
}
if (jdgvChild.Rows.Count > 0)
{
for (int i = 0; i < jdgvChild.Rows.Count; i++)
{
PdfPCell[] objcell = new PdfPCell[jdgvChild.Columns.Count];
for (int j = 0; j < jdgvChild.Columns.Count-1; j++)
{
cell = new PdfPCell(new Phrase(jdgvChild.Rows[i].Cells[j].Value.ToString()));
cell.HorizontalAlignment = PdfPCell.ALIGN_CENTER;
cell.VerticalAlignment = PdfPCell.ALIGN_CENTER;
// table.AddCell(cell);
//lstCells.Add(cell);
objcell[j] = cell;
}
PdfPRow newrow = new PdfPRow(objcell);
table.Rows.Add(newrow);
}
}
pdfdoc.Add(table);
MessageBox.Show("Pdf Generation Successfully.");
pdfdoc.Close();
}
}
catch (Exception ex)
{
MessageBox.Show("Error in pdf Generation.");
}
}
I want to create a PDF file with Icard showing in it.
Following is the code:
iTextSharp.text.Font custFont = new iTextSharp.text.Font() { Size=6f};
int borderSize = 1;
Document IcardDoc = new Document(PageSize.HALFLETTER);
PdfWriter.GetInstance(IcardDoc, Response.OutputStream);
IcardDoc.Open();
PdfPTable icardTable = new PdfPTable(2);
iTextSharp.text.Image logoImage = iTextSharp.text.Image.GetInstance(Server.MapPath("~/images/logo.jpg"));
logoImage.WidthPercentage = 15f;
PdfPCell cell = new PdfPCell(logoImage, false);
cell.PaddingLeft = 10f;
cell.PaddingTop = 10f;
cell.PaddingBottom = 10f;
cell.PaddingRight = 10f;
cell.Colspan = 2;
cell.Border = 0;
cell.HorizontalAlignment = 1;
icardTable.AddCell(cell);
icardTable.AddCell(new PdfPCell(new Phrase("Name:", custFont)) { Border = borderSize });
icardTable.AddCell(new PdfPCell(new Phrase(student.firstname + " " + student.lastname, custFont)) { Border = borderSize });
The print document size will be 8.5 cm in height and 5.4 cm in width.
So need to fit it that way, is there any solution to this because the above code is not fitting the table on page and in proper size?
Any other format will also do like word etc.
figured out the solution :
Document IcardDoc = new Document(new Retangele(200f, 315f),35f,35f,0f,0f);
and adjust the width of the table accordingly:
PdfPTable icardTable = new PdfPTable(2);
icardTable.WidthPercentage = 140f;
to fit table exactly on page, if decrease rectangle width then increase table WidthPercentage and vice versa.
You also need to care of left and right margins defined as 35f in Document class constructor
This worked for me.
var pgSize = new iTextSharp.text.Rectangle(1042, 651);
var doc = new iTextSharp.text.Document(pgSize, 0, 0, 0, 0);