I have a PDfTable like below, my problem is if Phrase text too big than it makes blank line between header and phrase. How can I bound together so if phrase text too big for one page than fit what ever text you can on the same page with headers and rest of the phrase text you can start with new page.
problem:
.............................
. header1 : header2 :header3: Page1 // here I want to fit the phrase as much as can if phrase needs new page than put rest of the text on the next page
. :
. phrase too big to fit here:
............................:
.............................
. phrase starts here . Page2
. .
.............................
code:
private String WritePDF(DataTable dt)
{
String fileName = "";
//Creating iTextSharp Table from the DataTable data
PdfPTable pdfTable = new PdfPTable(m_PDFColumnCount);
pdfTable.DefaultCell.Padding = 1;
pdfTable.WidthPercentage = 100;
pdfTable.HorizontalAlignment = Element.ALIGN_JUSTIFIED;
pdfTable.DefaultCell.BackgroundColor = new iTextSharp.text.BaseColor(194, 214, 155);
//pdfTable.DefaultCell.BorderWidth = 1;
this.BuildPDFHeader(pdfTable, "DATE");
this.BuildPDFHeader(pdfTable, "TIME");
this.BuildPDFHeader(pdfTable, "RESULT");
this.BuildPDFHeader(pdfTable, "FULLNAME");
this.BuildPDFHeader(pdfTable, "REGARDING");
//Adding DataRow
for (int intIndex = 0; intIndex < dt.Rows.Count; intIndex++)
{
dt.Rows[intIndex]["details"] = getplaintext(dt.Rows[intIndex]["details"].ToString());
pdfTable.AddCell(dt.Rows[intIndex]["date"].ToString());
pdfTable.AddCell(dt.Rows[intIndex]["time"].ToString());
pdfTable.AddCell(dt.Rows[intIndex]["result"].ToString());
pdfTable.AddCell(dt.Rows[intIndex]["fullname"].ToString());
pdfTable.AddCell(dt.Rows[intIndex]["regarding"].ToString());
PdfPCell cell = new PdfPCell(new Phrase(dt.Rows[intIndex]["details"].ToString()));
cell.BackgroundColor = new iTextSharp.text.BaseColor(227, 234, 235);
cell.Colspan = 5;
pdfTable.AddCell(cell);
}
//String folderPath = ConfigurationManager.AppSettings["Path"].ToString();
String folderPath = "C:\\PDFs\\";
fileName = String.Format("{0}{1}{2}",folderPath, dt.Rows[0]["id"].ToString(),".pdf" );
//Exporting to PDF
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate ))
{
Document pdfDoc = new Document(PageSize.A4, 20, 20, 20, 20);
PdfWriter.GetInstance(pdfDoc, stream);
pdfDoc.Open();
pdfDoc.Add(pdfTable);
pdfDoc.Close();
stream.Close();
}
return fileName;
}
private void BuildPDFHeader( PdfPTable pdfTable, String strText)
{
PdfPCell cell = new PdfPCell(new Phrase(strText));
cell.BackgroundColor = new iTextSharp.text.BaseColor(51, 102,102);
pdfTable.AddCell(cell);
}
Introduce the following line right after you define the table:
pdfTable.SplitLate = false;
This will split rows early. In you case, the rows are split only if a row takes up the space of an entire page.
Related
I have exported data from database to a datagridview and then to a pdf file and I want to delete one column in this file because it is a photo - I get only type of it in a cell (System.Byte[]).
I've tried to make my column invisible in datagridview but it didn't worked. It didn't have any impact on a pdf file, only column in datagridview had become hidden.
BaseFont bf = BaseFont.CreateFont(BaseFont.TIMES_ROMAN,
BaseFont.CP1250, BaseFont.EMBEDDED);
PdfPTable pdfTable = new PdfPTable(dgv.Columns.Count);
pdfTable.DefaultCell.Padding = 3;
pdfTable.WidthPercentage = 100;
pdfTable.HorizontalAlignment = Element.ALIGN_LEFT;
pdfTable.DefaultCell.BorderWidth = 1;
iTextSharp.text.Font text = new iTextSharp.text.Font(bf,10,iTextSharp.text.Font.NORMAL);
//Add header
foreach(DataGridViewColumn column in dgv.Columns)
{
PdfPCell cell = new PdfPCell(new Phrase(column.HeaderText, text));
cell.BackgroundColor = new iTextSharp.text.BaseColor(240, 240, 240);
pdfTable.AddCell(cell);
}
//add datarow
foreach(DataGridViewRow row in dgv.Rows)
{
foreach(DataGridViewCell cell in row.Cells)
{
//dgv.Columns[7].Visible = false;
pdfTable.AddCell(new Phrase(cell.Value.ToString(), text));
}
}
var savefiledialoge = new SaveFileDialog();
savefiledialoge.FileName = filename;
savefiledialoge.DefaultExt = ".pdf";
if(savefiledialoge.ShowDialog()==DialogResult.OK)
{
using(FileStream stream = new FileStream(savefiledialoge.FileName,FileMode.Create))
{
Document pdfdoc = new Document(PageSize.A4,10f,10f,10f,0f);
PdfWriter.GetInstance(pdfdoc, stream);
pdfdoc.Open();
pdfdoc.Add(pdfTable);
pdfdoc.Close();
stream.Close();
}
}
That's because even if you're making it invisible you still getting it in the loop
so you just need to make a condition in your loop to check if the column is visible or not
like this :
foreach(DataGridViewColumn column in dgv.Columns)
{
if (!column.Visible) continue;
PdfPCell cell = new PdfPCell(new Phrase(column.HeaderText, text));
cell.BackgroundColor = new iTextSharp.text.BaseColor(240, 240, 240);
pdfTable.AddCell(cell);
}
//add datarow
foreach(DataGridViewRow row in dgv.Rows)
{
foreach(DataGridViewCell cell in row.Cells)
{
if (!dgv.Columns[cell.ColumnIndex].Visible) continue;
//dgv.Columns[7].Visible = false;
pdfTable.AddCell(new Phrase(cell.Value.ToString(), text));
}
}
and now you can make your column to visible and it won't appear in the pdf file
I have a template PDF that contains form data that is a constant height. Under that data, I need to add a table that has a dynamic height. This table may only be one line, and one row, or it may contain 1000 lines and/or 1-1000 rows.
This is the Code that I have that works fine, except, the table will not span to a new page if it is to large.
private void InsertCurrentNeightborsOlder(string FileName)
{
//Create new PDF document
Document document = new Document(PageSize.LETTER, 20f, 20f, 0f, 20f);
iTextSharp.text.Font fntTableFontHdr = FontFactory.GetFont("Times New Roman", 8, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
iTextSharp.text.Font fntTableFont = FontFactory.GetFont("Times New Roman", 8, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
try {
PdfWriter.GetInstance(document, new FileStream(FileName, FileMode.Create));
PdfPTable nTbl = new PdfPTable(5);
// Build the header
PdfPCell CellOneHdr = new PdfPCell(new Phrase("Name", fntTableFontHdr));
nTbl.AddCell(CellOneHdr);
PdfPCell CellTwoHdr = new PdfPCell(new Phrase("Address", fntTableFontHdr));
CellTwoHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellTwoHdr);
PdfPCell CellTreeHdr = new PdfPCell(new Phrase("Phone #", fntTableFontHdr));
CellTreeHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellTreeHdr);
PdfPCell CellFouHdr = new PdfPCell(new Phrase("Method", fntTableFontHdr));
CellFouHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellFouHdr);
PdfPCell CellFivHdr = new PdfPCell(new Phrase("Comments", fntTableFontHdr));
nTbl.AddCell(CellFivHdr);
//create column sizes
float[] rows = {
100f,
100f,
70f,
100f,
100f
};
//set row width
nTbl.SetTotalWidth(rows);
nTbl.CompleteRow();
// Add the Cells to the data table
if (ReportDataSet.Tables("CurrentNeighbors").Rows.Count > 0) {
foreach (DataRow r in ReportDataSet.Tables("CurrentNeighbors").Rows) {
nTbl.AddCell(new Paragraph(r("FullName").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("Address").ToString, fntTableFont));
PdfPCell cell = new PdfPCell(new Paragraph(r("PhoneNumber").ToString, fntTableFont));
cell.HorizontalAlignment = 1;
nTbl.AddCell(cell);
// nTbl.AddCell(New Paragraph(r("PhoneNumber").ToString, fntTableFont))
nTbl.AddCell(new Paragraph(r("ContactMethod").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("Comments").ToString, fntTableFont));
}
} else {
nTbl.AddCell(new Paragraph("Nothing Entered", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
}
document.Open();
nTbl.HeaderRows = 1;
nTbl.SplitLate = false;
document.Add(nTbl);
} catch (Exception ex) {
} finally {
document.Close();
}
}
The "FileName" Parameter passed contains the location of the original file that I want to add the table to.
Is it even possible to do, and if so, what am I missing?
EDIT:
Here is another function that I tried (Using the Stamper). I may be way off on this one too, but that is what I am attempting to find out:
private void InsertCurrentNeightbors(string FileName)
{
// This is the Temporary File that we are working with. This file already has data in it
string oldFile = FileName;
// Create a new Temporary file that we can write to
string newFile = My.Computer.FileSystem.GetTempFileName();
iTextSharp.text.pdf.PdfReader reader = null;
iTextSharp.text.pdf.PdfStamper stamper = null;
iTextSharp.text.pdf.PdfContentByte cb = null;
iTextSharp.text.Rectangle rect = null;
int pageCount = 0;
try {
reader = new iTextSharp.text.pdf.PdfReader(oldFile);
rect = reader.GetPageSizeWithRotation(1);
stamper = new iTextSharp.text.pdf.PdfStamper(reader, new System.IO.FileStream(newFile, System.IO.FileMode.Create));
iTextSharp.text.Font fntTableFontHdr = FontFactory.GetFont("Times New Roman", 8, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
iTextSharp.text.Font fntTableFont = FontFactory.GetFont("Times New Roman", 8, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
cb = stamper.GetOverContent(1);
dynamic ct = new ColumnText(cb);
ct.Canvas = stamper.GetOverContent(reader.NumberOfPages + 1);
ct.Alignment = Element.ALIGN_LEFT;
ct.SetSimpleColumn(70, 36, PageSize.A4.Width - 36, PageSize.A4.Height - 300);
PdfPTable nTbl = new PdfPTable(5);
// Build the header
PdfPCell CellOneHdr = new PdfPCell(new Phrase("Name", fntTableFontHdr));
nTbl.AddCell(CellOneHdr);
PdfPCell CellTwoHdr = new PdfPCell(new Phrase("Address", fntTableFontHdr));
CellTwoHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellTwoHdr);
PdfPCell CellTreeHdr = new PdfPCell(new Phrase("Phone #", fntTableFontHdr));
CellTreeHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellTreeHdr);
PdfPCell CellFouHdr = new PdfPCell(new Phrase("Method", fntTableFontHdr));
CellFouHdr.HorizontalAlignment = Element.ALIGN_CENTER;
nTbl.AddCell(CellFouHdr);
PdfPCell CellFivHdr = new PdfPCell(new Phrase("Comments", fntTableFontHdr));
nTbl.AddCell(CellFivHdr);
//create column sizes
float[] rows = {
100f,
100f,
70f,
100f,
100f
};
//set row width
nTbl.SetTotalWidth(rows);
nTbl.CompleteRow();
// Add the Cells to the data table
if (ReportDataSet.Tables("CurrentNeighbors").Rows.Count > 0) {
foreach (DataRow r in ReportDataSet.Tables("CurrentNeighbors").Rows) {
nTbl.AddCell(new Paragraph(r("FullName").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("Address").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("PhoneNumber").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("ContactMethod").ToString, fntTableFont));
nTbl.AddCell(new Paragraph(r("Comments").ToString, fntTableFont));
}
} else {
nTbl.AddCell(new Paragraph("Nothing Entered", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
nTbl.AddCell(new Paragraph(" ", fntTableFont));
}
nTbl.SplitLate() = false;
nTbl.WriteSelectedRows(0, 25, 85, 490, stamper.GetOverContent(reader.NumberOfPages));
stamper.Close();
reader.Close();
ct.Go();
// Now that the new temp file has been written, we need to delete the old temp file
// and rename the new temp file to the old temp file name
// Delete Old Temp file
My.Computer.FileSystem.DeleteFile(FileName);
// Rename the new temp file to the old temp file
My.Computer.FileSystem.RenameFile(newFile, System.IO.Path.GetFileName(FileName));
} catch (Exception ex) {
throw ex;
}
}
I did try the link that you provided, but it did not work as expected. All āIā was able to do is repeat the source page 100 times onto the destination page. I know that it was all to do with my interpretation of the source code, and the conversion, but this is what I got:
private void manipulatePdf(string src, string dest)
{
try {
// Read the template file into the reader variable
PdfReader reader = new PdfReader(src);
// Get the page side of the template file
iTextSharp.text.Rectangle pagesize = reader.GetPageSize(1);
// Create a Stamper for the destination file
PdfStamper stamper = new PdfStamper(reader, new System.IO.FileStream(dest, System.IO.FileMode.Create));
// Create a new Paragraph
Paragraph p = new Paragraph();
// Add Text into the new paragraph
p.Add(new Chunk("Hello "));
p.Add(new Chunk("World"));
// Declare your AcroFields so we can get the last field's position
AcroFields form = stamper.AcroFields();
// Get the Last AcroField's Position
Rectangle rect = form.GetFieldPositions("MethodOfVerification")(0).position;
int status = 0;
PdfImportedPage newPage = null;
ColumnText column = new ColumnText(stamper.GetOverContent(1));
column.SetSimpleColumn(rect);
int pagecount = 1;
// Add's 100 Items
int i = 0;
while (i < 100) {
i += 1;
// Creates a new paragraph object
column.AddElement(new Paragraph("Hello " + i.ToString));
// Adds the paragraph object to the column
column.AddElement(p);
// Draw content of column
status = column.Go();
if (ColumnText.HasMoreText(status)) {
// Creates a new page and stamps the Source PDF into the Destination PDF
newPage = loadPage(newPage, reader, stamper);
triggerNewPage(stamper, pagesize, newPage, column, rect, System.Threading.Interlocked.Increment(pagecount));
}
}
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
} catch (Exception ex) {
}
}
public PdfImportedPage loadPage(PdfImportedPage page, PdfReader reader, PdfStamper stamper)
{
if (page == null) {
return stamper.GetImportedPage(reader, 1);
}
return page;
}
public void triggerNewPage(PdfStamper stamper, Rectangle pagesize, PdfImportedPage page, ColumnText column, Rectangle rect, int pagecount)
{
stamper.InsertPage(pagecount, pagesize);
PdfContentByte canvas = stamper.GetOverContent(pagecount);
canvas.AddTemplate(page, 0, 0);
// column.setCanvas(canvas)
column.Canvas() = canvas;
column.SetSimpleColumn(rect);
column.Go();
}
I don't know if this helps but I've ported and slightly modified Bruno sample code to a C# version. The first block (file_1) creates a sample file and stores the last known coordinate so that we can resume with a table later. The second block (file_2) then uses a PdfStamper and a ColumnText to start the table and continuously adds pages until the table fits. The code itself, especially the second block, has comments that better explain things.
You should be able to re-work the first block to your form's logic to get the coordinates (it seems like you've got that part down) and then just use the second block with your local table.
//Working folder
var exportFolder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "SO_17589177");
System.IO.Directory.CreateDirectory(exportFolder);
//File 1 is our "template" file, File 2 is our final file
var file_1 = System.IO.Path.Combine(exportFolder, "file_1.pdf");
var file_2 = System.IO.Path.Combine(exportFolder, "file_2.pdf");
//Will hold a rectangle based on the last known coordinates
iTextSharp.text.Rectangle tableRectStart;
using (var fs = new FileStream(file_1, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
for (var i = 0; i < 10; i++) {
doc.Add(new Paragraph("Hello world"));
}
//Store our coordinates for later
tableRectStart = new iTextSharp.text.Rectangle(doc.Left, doc.Bottom, doc.Right, writer.GetVerticalPosition(false));
doc.Close();
}
}
}
using (var r = new PdfReader(file_1)) {
using (var fs = new FileStream(file_2, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (var stamper = new PdfStamper(r, fs)) {
//We want to target the last page of the previous PDF
int pageNumber = r.NumberOfPages;
//Store the last page's size which is what we'll use for new pages later
var docRect = r.GetPageSize(pageNumber);
//Create a giant table
var t = new PdfPTable(2);
for (var i = 0; i < 1000; i++) {
t.AddCell(String.Format("This is cell {0}", i));
}
//Create our stamper bound to the last page of our source document
var ct = new ColumnText(stamper.GetOverContent(pageNumber));
//Add our table to the stamper
ct.AddElement(t);
//Set the drawing area for the table
ct.SetSimpleColumn(tableRectStart);
//Infinite loop below that is responsible for breaking itself out
//Might want to add guards in case content gets too big and always overflows
while (true) {
//Draw the text and pass the status back to a helper
//method that tells us if there's more text to be drawn
if (! ColumnText.HasMoreText(ct.Go())) {
//If there isn't any more text then exit the infinite loop
break;
}
//Reset our rectangle to the document's rectangle
tableRectStart = docRect;
//Increment the current page number (which we need to keep track of)
//and insert a new page
stamper.InsertPage(++pageNumber, docRect);
//Tell the ColumnText to draw on a new page
ct.Canvas = stamper.GetOverContent(pageNumber);
//Reset the drawing canvas area
//TODO: Include some margin logic here probably
ct.SetSimpleColumn(docRect);
}
}
}
}
In my project I am using MVC4,C# and itextsharp to generate pdf from html. I need to insert header with a logo and template name, and footer with paging (page number/Total number of pages). I am done the the footer, I have used this code to add footer to the pdf file:
public static byte[] AddPageNumbers(byte[] pdf)
{
MemoryStream ms = new MemoryStream();
ms.Write(pdf, 0, pdf.Length);
// we create a reader for a certain document
PdfReader reader = new PdfReader(pdf);
// we retrieve the total number of pages
int n = reader.NumberOfPages;
// we retrieve the size of the first page
Rectangle psize = reader.GetPageSize(1);
// step 1: creation of a document-object
Document document = new Document(psize, 50, 50, 50, 50);
// step 2: we create a writer that listens to the document
PdfWriter writer = PdfWriter.GetInstance(document, ms);
// step 3: we open the document
document.Open();
// step 4: we add content
PdfContentByte cb = writer.DirectContent;
int p = 0;
Console.WriteLine("There are " + n + " pages in the document.");
for (int page = 1; page <= reader.NumberOfPages; page++)
{
document.NewPage();
p++;
PdfImportedPage importedPage = writer.GetImportedPage(reader, page);
cb.AddTemplate(importedPage, 0, 0);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.BeginText();
cb.SetFontAndSize(bf, 10);
cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, +p + "/" + n, 44, 7, 0);
cb.EndText();
}
// step 5: we close the document
document.Close();
return ms.ToArray();
}
}
if you need any explanation about this code please let me know.
I tried to use the same method for header but my site logo is overriding the existing content of the pdf page. Then i tried to use this code but no luck :(
public _events(string TemplateName,string ImgUrl)
{
this.TempName = TemplateName;
this.ImageUrl = ImgUrl;
}
private string TempName = string.Empty;
private string ImageUrl = string.Empty;
public override void OnEndPage(PdfWriter writer, Document doc)
{
//Paragraph footer = new Paragraph("THANK YOU ", FontFactory.GetFont(FontFactory.TIMES, 10, iTextSharp.text.Font.NORMAL));
Paragraph header = new Paragraph("Template Name:" + TempName + " " +DateTime.UtcNow, FontFactory.GetFont(FontFactory.TIMES, 10, iTextSharp.text.Font.NORMAL));
//adding image (logo)
string imageURL = HttpContext.Current.Server.MapPath("~/Content/images.jpg");
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imageURL);
//Resize image depend upon your need
jpg.ScaleToFit(140f, 120f);
//Give space before image
jpg.SpacingBefore = 10f;
//Give some space after the image
jpg.SpacingAfter = 1f;
jpg.Alignment = Element.ALIGN_LEFT;
header.Alignment = Element.ALIGN_TOP;
PdfPTable headerTbl = new PdfPTable(1);
headerTbl.TotalWidth = 400;
headerTbl.HorizontalAlignment = Element.ALIGN_CENTER;
PdfPCell cell11 = new PdfPCell(header);
PdfPCell cell2 = new PdfPCell(jpg);
cell2.Border = 0;
cell11.Border = 0;
cell11.PaddingLeft = 10;
cell2.PaddingLeft = 10;
headerTbl.AddCell(cell11);
headerTbl.AddCell(cell2);
headerTbl.WriteSelectedRows(0, -1, doc.LeftMargin, doc.PageSize.Height - 10, writer.DirectContent);
}
}
here is my Action method to which is returning the pdf file as response. and i have used this class in it. apologies may be I should post this in beginning of my question.
[HttpGet]
[HandleException]
public ActionResult GenerateLeadProposalPDF()
{
TempData.Keep();
long LeadId = Convert.ToInt64(TempData["Leadid"]);
long EstimateId = Convert.ToInt64(TempData["Estimateid"]);
long ProposalTemplateId = Convert.ToInt64(TempData["ProposalTemplateId"]);
Guid SubscriberId = SessionManagement.LoggedInUser.SubscriberId;
var data = this._LeadEstimateAPIController.GetLeadProposalDetails(LeadId, EstimateId, ProposalTemplateId, SubscriberId);
System.Text.StringBuilder strBody = new System.Text.StringBuilder("");
string SubscriberProjectBody = this.ControllerContext.RenderRazorViewToString(ViewData, TempData, "~/Areas/Subscriber/Views/Shared/_GenerateProposalTemplate.cshtml", data);
string Header = this.ControllerContext.RenderRazorViewToString(ViewData, TempData, "~/Areas/Subscriber/Views/Shared/_HeaderGenerateProposals.cshtml", data);
string styleCss = System.IO.File.ReadAllText(Server.MapPath("~/ProposalDoc_CSS.txt"));
strBody.Append(#"<html><head><title></title> </head>");
strBody.Append(#"<body lang=EN-US style='tab-interval:.5in'>");
// strBody.Append(Header);
strBody.Append(SubscriberProjectBody);
strBody.Append(#"</body></html>");
String htmlText = strBody.ToString();
Document document3 = new Document(PageSize.A4, 36, 36, 36, 36);
_events e = new _events(data.objProposalLeadDetailsModel.ProposalFullName,"test");
string filePath = HostingEnvironment.MapPath("~/");
filePath = filePath + "pdf-.pdf";
var stream=new FileStream(filePath, FileMode.Create);
var objPdfWriter= PdfWriter.GetInstance(document3, stream);
document3.Open();
objPdfWriter.PageEvent = e;
iTextSharp.text.html.simpleparser.HTMLWorker hw = new iTextSharp.text.html.simpleparser.HTMLWorker(document3);
hw.Parse(new StringReader(htmlText));
document3.Close();
var result = System.IO.File.ReadAllBytes(filePath);
var abd = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var streamArray = ReadFully(abd);
var streamFile = AddPageNumbers(streamArray);
// Response.End();
string contentType = "application/pdf";
return File(streamFile, contentType, "LeadProposal.pdf");
}
I have searched a lot over google, my pdf looks like this
Any suggestion or help will be appreciated, Please help me, thanks in advance :)
after some changes in the _events class I got what I want, but may be its not the right way to do it, but for now its working for me :)
public class _events : PdfPageEventHelper
{
public _events(string TemplateName,string ImgUrl)
{
this.TempName = TemplateName;
this.ImageUrl = ImgUrl;
}
private string TempName = string.Empty;
private string ImageUrl = string.Empty;
public override void OnEndPage(PdfWriter writer, Document doc)
{
Paragraph PTempName = new Paragraph("Template Name:" + TempName, FontFactory.GetFont(FontFactory.TIMES, 10, iTextSharp.text.Font.NORMAL));
Paragraph PDate = new Paragraph(DateTime.UtcNow.ToShortDateString(), FontFactory.GetFont(FontFactory.TIMES, 10, iTextSharp.text.Font.NORMAL));
//adding image (logo)
string imageURL = "http://108.168.203.227/PoologicApp/Content/Bootstrap/images/logo.png";//HttpContext.Current.Server.MapPath("~/Content/images.jpg");
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imageURL);
//Resize image depend upon your need
jpg.ScaleToFit(70f, 120f);
//Give space before image
//jpg.SpacingBefore = 10f;
//Give some space after the image
jpg.SpacingAfter = 1f;
jpg.Alignment = Element.ALIGN_TOP;
PTempName.Alignment = Element.ALIGN_TOP;
PDate.Alignment = Element.ALIGN_TOP;
PdfPTable headerTbl = new PdfPTable(3);
headerTbl.TotalWidth = 600;
headerTbl.HorizontalAlignment = Element.ALIGN_TOP;
PdfPCell cell11 = new PdfPCell(PTempName);
PdfPCell cell3 = new PdfPCell(PDate);
PdfPCell cell2 = new PdfPCell(jpg);
cell2.Border = 0;
cell11.Border = 0;
cell3.Border = 0;
cell11.PaddingLeft = 10;
cell3.PaddingLeft = 10;
cell2.PaddingLeft = 10;
headerTbl.AddCell(cell11);
headerTbl.AddCell(cell3);
headerTbl.AddCell(cell2);
headerTbl.WriteSelectedRows(0, -1, doc.LeftMargin, doc.PageSize.Height - 4, writer.DirectContent);
}
}
now my pdf looks like this :
I want to convert the data of datagridview into PDF file . For Example if i press button1 i should get the datagridview data as pdf.
How can I do this?
Please use iTextSharp for this.
There are different libraries to accomplish this
1.iTextSharp
2.PDFSharp
3.SharpPDF
Hope this helps
How to Export data as PDF format?
Below code is for export grid view data to PDF format
public void ExportToPdf(DataTable ExDataTable) //Datatable
{
//Here set page size as A4
Document pdfDoc = new Document(PageSize.A4, 10, 10, 10, 10);
try
{
PdfWriter.GetInstance(pdfDoc, System.Web.HttpContext.Current.Response.OutputStream);
pdfDoc.Open();
//Set Font Properties for PDF File
Font fnt = FontFactory.GetFont("Times New Roman", 12);
DataTable dt = ExDataTable;
if (dt != null)
{
PdfPTable PdfTable = new PdfPTable(dt.Columns.Count);
PdfPCell PdfPCell = null;
//Here we create PDF file tables
for (int rows = 0; rows < dt.Rows.Count; rows++)
{
if (rows == 0)
{
for (int column = 0; column < dt.Columns.Count; column++)
{
PdfPCell = new PdfPCell(new Phrase(new Chunk(dt.Columns[column].ColumnName.ToString(), fnt)));
PdfTable.AddCell(PdfPCell);
}
}
for (int column = 0; column < dt.Columns.Count; column++)
{
PdfPCell = new PdfPCell(new Phrase(new Chunk(dt.Rows[rows][column].ToString(), fnt)));
PdfTable.AddCell(PdfPCell);
}
}
// Finally Add pdf table to the document
pdfDoc.Add(PdfTable);
}
pdfDoc.Close();
Response.ContentType = "application/pdf";
//Set default file Name as current datetime
Response.AddHeader("content-disposition", "attachment; filename=" + DateTime.Now.ToString("yyyyMMdd") + ".pdf");
System.Web.HttpContext.Current.Response.Write(pdfDoc);
Response.Flush();
Response.End();
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
}
I have three static PdfPTable methods that are called from the main method used to create a PDF document.
In each method I use PdfPCells' to add data and structure to the tables, so the first PdfPTable method would be to create the header for every page the second is to create the body of the that page and the third is to create the footer for every page. Then the table are added to the PdfPDocument after they are called in the main method
I have tried to use table.HeaderRows = 1 to add a header to every page but when added to the PdfPTable method for the header, it removes everything in that table. When I add it to the the PdfPTable for the body it moves the content on the second page to the bottom of the first page and copies the content of the first page to the second.
//table method for call header
PdfPTable table = CreateTable(textUpperData/*, document, writer*/);
document.Add(table);
//table method call for body
table = CreateTable1(imgInfoData, posData, sizeData, document);
document.Add(table);
//table method call for footer
table = CreateTable2(textLowerData);
document.Add(table);
document.Close();
//header table static method
private static PdfPTable CreateTable(List<KeyValuePair<string, string>> textUpper/*, Document document, PdfWriter writer*/)
{
//SiteDB sitedb = new SiteDB();
//sitedb.GetEmailText();
iTextSharp.text.Font headerFont = FontFactory.GetFont("Time New Roman", 14, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
iTextSharp.text.Font bodyFont = FontFactory.GetFont("Time New Roman", 10, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
PdfPTable table = new PdfPTable(3);
table.HorizontalAlignment = Element.ALIGN_CENTER;
table.WidthPercentage = 100;
table.TotalWidth = 597.6f;
table.LockedWidth = true;
table.SetWidths(new float[] { 1, 2, 1 });
iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance("C:\\Users\\User\\Documents\\Images\\image0.tiff");
logo.ScaleToFit(150, 235);
logo.SetAbsolutePosition(595.2f - 150f, 0);
PdfPCell logoCell = new PdfPCell(logo);
logoCell.HorizontalAlignment = Element.ALIGN_JUSTIFIED;
logoCell.Border = iTextSharp.text.Rectangle.NO_BORDER;
table.AddCell(logoCell);
Chunk logoChunk = new Chunk(System.Environment.NewLine);
Phrase logoPhrase = new Phrase(logoChunk);
//Chunk headerChunk = new Chunk(sitedb.header_lit.ToString() + System.Environment.NewLine, headerFont);
//Phrase headerPhrase = new Phrase(headerChunk);
Chunk headerChunk = new Chunk(textUpper[0].Key.ToString() + System.Environment.NewLine, headerFont);
Phrase headerPhrase = new Phrase(headerChunk);
//Chunk bodyChunk = new Chunk(sitedb.body_lit.ToString() + System.Environment.NewLine, bodyFont);
//Phrase bodyPhrase = new Phrase(bodyChunk);
Chunk bodyChunk = new Chunk(textUpper[0].Value.ToString() + System.Environment.NewLine, bodyFont);
Phrase bodyPhrase = new Phrase(bodyChunk);
Paragraph paragraph = new Paragraph();
paragraph.Alignment = Element.ALIGN_MIDDLE;
paragraph.Alignment = Element.ALIGN_TOP;
paragraph.Add(headerPhrase);
paragraph.Add(bodyPhrase);
PdfPCell headerBodyCell = new PdfPCell(paragraph);
headerBodyCell.HorizontalAlignment = Element.ALIGN_JUSTIFIED;
headerBodyCell.VerticalAlignment = Element.ALIGN_TOP;
headerBodyCell.Colspan = 2;
headerBodyCell.PaddingLeft = 5f;
headerBodyCell.PaddingRight = 5f;
headerBodyCell.PaddingTop = 8f;
headerBodyCell.Border = iTextSharp.text.Rectangle.NO_BORDER;
table.AddCell(headerBodyCell);
return table;
}
Well it seems that headers cannot be added to every new page in a pdf which is built from multiple tables, only single tables with cells!
I will most likely create a method that keeps adding a particular table for every new page!