Displaying page number and total page count in footer

How do you determine the page number and total page count.
I’m importing details via a DataTable which generates over 100 pages so.

I want to place this in a footer.

Here is some sample code (that does not work)
Please advise how to correct if.

Document pdfDoc = new Document();
Page page = pdfDoc.Pages.Add();
var footer = new HeaderFooter();
//This returns ‘Pages 0’ which is incorrect
var footerText = new TextFragment($“Pages {page.Paragraphs.Count}”);
// How do you also calculate the page number???
footer.Paragraphs.Add(footerText);
page.Footer = footer;
pdfDoc.Save(“C:\temp\testfile”);

Many thanks, John

@johntbarton

Thanks for contacting support.

Please note that in order to get correct count of Pages before saving the PDF file, you need to call Document.ProcessParagraphs() method which maps all the elements inside PDF document. After calling suggested method, you will get correct count of pages and in case you still face any issue, please share complete sample code snippet along with sample PDF document, so that we can test the scenario in our environment and address it accordingly.

@johntbarton,
In addition to the above reply of Asad, you can add page number by using PageNumberStamp class, please refer to this help topic: Add Page Number Stamp in a PDF File. The PageCollection instance, allows to retrieve the count of pages. Please refer to this help topic: Get Number of Pages in a PDF File. Kindly let us know in case of any further assistance or questions.

Thank you - ProcessParagraphs() was the answer.

To help others here is a snippit of my code
Document pdfDoc = new Document();
// Do loads of stuff with tables in a single page (section)
pdfDoc.ProcessParagraphs();
TextStamp textStamp = new TextStamp("");
textStamp.HorizontalAlignment = HorizontalAlignment.Right;
textStamp.VerticalAlignment = VerticalAlignment.Bottom;
foreach (Page page in pdfDoc.Pages)
{
textStamp.Value = $“Page {page.Number} of {pdfDoc.Pages.Count}”;
page.AddStamp(textStamp);
}

@johntbarton,

It is nice to hear from you that the problem has been resolved.

1 Like

HI guys, But sometime calling the document.ProcessParagraph() taking too much time if we have more then 20 pages in the pdf.

Is there any alternate to document.ProcessParagraph() which can return the actual page count before saving the document.

And one more interesting thing when I call the page.ProcessParagraph() it is giving Object reference error if page content exceed from one page to another page.

@sadyalajay

Thanks for your inquiry.

In case Document.ProcessParagraphs() method is taking time, you may please try to save document to some memory stream (i.e document.Save(new MemoryStream())) before saving it physically. This way you will also get correct count of pages.

Would you please share the complete sample code snippet, which replicates the mentioned exception. We will test the scenario in our environment and address it accordingly.

Please find the below code snippet, I have used the page.ProcessParagraph() which is throwing error. but if you put the document.ProcessParagraph() that is taking almost:

            Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document();
	pdfDocument.PageInfo.Height = Aspose.Pdf.Generator.PageSize.A4Height;
	pdfDocument.PageInfo.Width = Aspose.Pdf.Generator.PageSize.A4Width;
	pdfDocument.PageInfo.IsLandscape = false;

	StringBuilder htmlBuilder = new StringBuilder();

	for (int i = 0; i <= 500; i++)
	{
		Aspose.Pdf.Page pdfPage = pdfDocument.Pages.Add();
		pdfPage.PageInfo.Margin.Top = 20;
		pdfPage.PageInfo.Margin.Left = 5;
		pdfPage.PageInfo.Margin.Right = 5;
		pdfPage.PageInfo.Margin.Bottom = 20;

		// Add tables and few barcodes
		Aspose.Pdf.Table tableBarCodes = new Aspose.Pdf.Table();
		tableBarCodes.ColumnWidths = "300 300";
		tableBarCodes.IsInLineParagraph = true;
		Aspose.Pdf.Row row = tableBarCodes.Rows.Add();

		Aspose.Pdf.Cell cell = row.Cells.Add();
		cell.Alignment = HorizontalAlignment.Left;
		cell.Paragraphs.Add(BarcodeDOM());

		Aspose.Pdf.Cell cel2 = row.Cells.Add();
		cel2.Alignment = HorizontalAlignment.Right;
		cel2.Paragraphs.Add(MatrixBarCodeDOM());

		pdfPage.Paragraphs.Add(tableBarCodes);

		pdfPage.Paragraphs.Add(BarcodeDOM());
		pdfPage.Paragraphs.Add(MatrixBarCodeDOM());

		htmlBuilder.AppendFormat("<table style='width: 100%;'><tr><td>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</br> It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,</br> and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </td></tr></table>", i);
		pdfPage.Paragraphs.Add(new HtmlFragment(htmlBuilder.ToString()));

		//pdfPage.ProcessParagraphs();
		pdfDocument.ProcessParagraphs();
	}

	using (var streamMemory = new MemoryStream())
	{
		Response.Clear();
		pdfDocument.Save(streamMemory);
		Response.ContentType = "application/pdf";
		Response.AddHeader("content-disposition", string.Format("inline;filename={0}.pdf", "Ajay_barcode_Document"));
		Response.Buffer = true;
		var bytes = streamMemory.ToArray();
		Response.BinaryWrite(bytes);
		Response.End();
	}

I am adding two function which are adding barcode to PDF.

  private Aspose.Pdf.Image BarcodeDOM()
  {
	BarCodeBuilder barcodeBuilder = new BarCodeBuilder();
	barcodeBuilder.CodeText = "My personal barcode";
	barcodeBuilder.SymbologyType = Symbology.Code128;
	System.IO.MemoryStream barcodeMemoryStream = new System.IO.MemoryStream();
	barcodeBuilder.BarCodeImage.Save(barcodeMemoryStream, System.Drawing.Imaging.ImageFormat.Bmp);

	Aspose.Pdf.Image barcodeImage = new Aspose.Pdf.Image();
	barcodeImage.FileType = Aspose.Pdf.ImageFileType.Unknown;
	barcodeImage.ImageScale = 0.5F;
	barcodeImage.FixWidth = 200;
	barcodeImage.FixHeight = 50;

	barcodeImage.ImageStream = barcodeMemoryStream;
	return barcodeImage;
}

private Aspose.Pdf.Image MatrixBarCodeDOM()
{
	BarCodeBuilder matrixBuilder = new BarCodeBuilder();
	matrixBuilder.SymbologyType = Aspose.BarCode.Symbology.DataMatrix;
	matrixBuilder.CodeText = "Matrix bardcode";
	matrixBuilder.CodeLocation = CodeLocation.None;
	System.IO.MemoryStream matrixMemoryStream = new System.IO.MemoryStream();
	matrixBuilder.BarCodeImage.Save(matrixMemoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
	Aspose.Pdf.Image matrixImage = new Aspose.Pdf.Image();
	matrixImage.FileType = Aspose.Pdf.ImageFileType.Unknown;
	matrixImage.ImageScale = 1.2F;
	matrixImage.FixWidth = 50;
	matrixImage.FixHeight = 50;
	matrixImage.ImageStream = matrixMemoryStream;
	matrixImage.HorizontalAlignment = HorizontalAlignment.Left;
	return matrixImage;
}

@sadyalajay

Thanks for sharing the sample code snippet.

I have tested the scenario by using your code snippet and observed that the code took long time to generate PDF. However I was unable to see the need of pdfDocument.ProcessParagraphs() method in the for loop, as you were performing no operations after that call. In case you are performing some functionality due to which you require this method, please share that as well. This way we will be able to test the scenario accordingly.

Furthermore, please note that performance of the API also depends upon the elements and contents, which you are adding inside PDF. More content and elements you add, more the API will take memory and time to process it.

By looking at your code, it seems that you are using older version(s) of the APIs. Please note that it is always recommended to use latest version of the API, because it comes with performance improvements and enhancements. Please use latest versions of Aspose.Pdf for .NET and Aspose.BarCode for .NET and in case you still face any issue, feel free to let us know.

Thanks Asad for your reply.

Yes in footer I want to add html markup,

i have scenario where I am printing multiple invoices with one PDF. So I want to add the footer text only when Invoice lines end. it is working fine. for those invoices which has Invoice Lines/Data less then one page.

If invoice line item Exceed one page count then it is printing footer at each of the pages and overlap the invoice Line item.

So I need the exact page count So I can add the footer where ever lineitems page end. I am adding the screenshot.

2017-11-27_2350-invoice-Overlapping-footer.png (198.3 KB)

@sadyalajay

Thanks for sharing more details of the scenario.

In case you are creating a PDF invoice, which can exceed from more than one page, you can simply call document.ProcessParagraphs() method once, before adding footer at the last page of PDF (I am assuming that lineitems page will be the last page in your scenario). After calling the method, you may determine the last page of PDF by following line of code:

var last_page = document.Pages[document.Pages.Count];

In case my assumptions are different than your actual scenario, please share a sample console application project, which will be able to reproduce the issue you are facing. We will test the scenario in our environment and address it accordingly.

Hi,

See the below code:

            HtmlFragement  fragmentSignatureFooter = new HtmlFragement ("some Html markup")
            HeaderFooter docFooter = new HeaderFooter();
	docFooter.Margin = footerMargin;
	docFooter.Paragraphs.Add(fragmentSignatureFooter);
	pdfDocument.ProcessParagraphs();
	pdfDocument.Pages[pdfDocument.Pages.Count].Footer = docFooter;

So this way you can get the count. but imagine… I am adding each invoice in loop. So let say I have 100 invoice to process. So each time I am calling process paragraph. it taking 3-5 seconds. and it increase gradually as the page count get higher.

So it might took 3 seconds * 100 = 300 seconds (5 minutes ) to process the one pdf who have 100 invoice to print.

So the time is very critical. So that why I was asking is there any other way to get the actual count before saving the document.

@sadyalajay

Thanks for writing back.

Since we did not have sample invoice data, which you are adding inside PDF and which image you have shared, so we have generated a sample PDF by using the code snippet you provided earlier. We are attaching the generated document for your reference. ProcessParagraphsIssueTest.pdf (913.6 KB)

We have tested the code by increasing iteration number to 500 and observed that the program took so long to execute the operation. However, you can check in the shared document that we were unable to notice footnote overlapping issues, which was why we requested you to share a sample application with full code snippet and sample invoice data, so that all issues can be observed in our environment and can be addressed accordingly.

Hi Asad,

I am attaching the the one more report which is also giving the timeout on document.Save() method.

Below is sample code and I am attaching a txt file which has Html markup and read that markup into string and passed that to HtmlFragment class

            string htmlContent = string.Empty;

	Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document();
	pdfDocument.PageInfo.Height = Aspose.Pdf.Generator.PageSize.A4Height;
	pdfDocument.PageInfo.Width = Aspose.Pdf.Generator.PageSize.A4Width;
	pdfDocument.PageInfo.IsLandscape = false;
	pdfDocument.PageInfo.Margin = new Aspose.Pdf.MarginInfo { Top = 11, Left = 15, Right = 15 };

	Aspose.Pdf.Page pdfPage = pdfDocument.Pages.Add();

	string logoPath = Server.MapPath("~/logo/Logo.jpg");

	Aspose.Pdf.Image logoImage = new Aspose.Pdf.Image();
	logoImage.File = logoPath;
	logoImage.FileType = Aspose.Pdf.ImageFileType.Unknown;
	logoImage.FixWidth = 150;
	logoImage.FixHeight = 35;
	logoImage.HorizontalAlignment = Aspose.Pdf.HorizontalAlignment.Left;
	pdfPage.Paragraphs.Add(logoImage);

	htmlContent = File.ReadAllText(Server.MapPath("~/HtmlMarkup-html.txt"));
	Aspose.Pdf.HtmlFragment htmlFragment = new Aspose.Pdf.HtmlFragment(htmlContent);
	pdfPage.Paragraphs.Add(htmlFragment);

	string fileName = "WorkInProgressReport_";
	
	Response.Clear();
	Response.ContentType = "application/pdf";
	pdfDocument.Save(Response, fileName, Aspose.Pdf.ContentDisposition.Inline, new Aspose.Pdf.PdfSaveOptions());
	Response.End();

it is giving timeout on save method. As there is no way to attach the file in the blog I am putting link for html markup file

@sadyalajay,

We have tested your scenario with the latest version 17.12 of Aspose.Pdf for .NET API and unable replicate the time out error in our environment. Please download and try the latest version 17.12 of Aspose.Pdf for .NET API, and then let us know how that goes into your environment.

The old legacy Aspose.Pdf.Generator approach has been removed from the Aspose.Pdf for .NET API. The latest version of the API follows DOM (Document Object Model) approach, as the structure of a PDF file is hierarchical, Aspose.Pdf for .NET API also accesses the elements in the same way. In order to understand the new DOM approach, please go through this help topic: Introduction to the DOM API. This is the complete developer guide of the new DOM approach: Working with Aspose.Pdf.

There is an upload button in the header of the post editor and you can upload the Zip of all files in your post.

Hi Imran,

Thanks for you response. I got the suggestion to upgrade to the latest version each time I struck in any of issue.

We are using Aspose.11.0.0.0, If you have access to this version DLL can you give a try and generate the PDF with above HTML markup.

If it is the issue of this specific version, then we definitely look to upgrade to the latest DLL. But we want to make sure by upgrading this all the timeout error must be gone. because we have already invested lot time & money on this PDF Generation reports.

Please let me know your feedback

@sadyalajay,

You can add reference of Aspose.Pdf library 17.12 from the NuGet because we publish each Aspose for .NET library on NuGet. We have tested your scenario with the latest version 17.12 of Aspose.Pdf for .NET API and can save the output PDF as follows:

[C#]

string dataDir = @"C:\Pdf\test525\";
Document document = new Document();
string htmlContent = string.Empty;

Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document();
pdfDocument.PageInfo.Height = Aspose.Pdf.PageSize.A4.Height;
pdfDocument.PageInfo.Width = Aspose.Pdf.PageSize.A4.Width;
pdfDocument.PageInfo.IsLandscape = false;
pdfDocument.PageInfo.Margin = new Aspose.Pdf.MarginInfo { Top = 11, Left = 15, Right = 15 };

Aspose.Pdf.Page pdfPage = pdfDocument.Pages.Add();
string logoPath = dataDir + "logo.jpg";
Aspose.Pdf.Image logoImage = new Aspose.Pdf.Image();
logoImage.File = logoPath;
logoImage.FileType = Aspose.Pdf.ImageFileType.Unknown;
logoImage.FixWidth = 150;
logoImage.FixHeight = 35;
logoImage.HorizontalAlignment = Aspose.Pdf.HorizontalAlignment.Left;
pdfPage.Paragraphs.Add(logoImage);

htmlContent = File.ReadAllText(dataDir + "AgedReceivablesReport-html.txt");
Aspose.Pdf.HtmlFragment htmlFragment = new Aspose.Pdf.HtmlFragment(htmlContent);
pdfPage.Paragraphs.Add(htmlFragment);

string fileName = string.Empty;

if (!string.IsNullOrEmpty("ComboBoxText"))
    fileName = string.Concat("WorkInProgressReport_", ("ComboBoxText").Replace(',', '_'));
pdfDocument.Save(dataDir + "Output17.12.pdf", SaveFormat.Pdf);

The multiple Save members of the Document class allow to save the output PDF in the memory stream. This is the output PDF: Output17.12.pdf (190.3 KB)

You can get a 30 day temporary license from the purchase portal and its option is available in step 5. You will see a button with caption Get a Temp License in step 5 of the purchase portal. A temporary license is a time-restricted full license that lets you test every aspect of API before renewal or buying it.

Hey Imran,

I have one another issue with HtmlFramgment class it is not recognizing the anchor tag with created PDF.

though text is appearing in blue, But tag is not clickable even though I added the SRC to it. Below is the sample code.

    Aspose.Pdf.HtmlFragment linkHtmlfragment = new Aspose.Pdf.HtmlFragment("<a style ='color:blue' src='https://www.google.com'>Click Me!</a>");
	
	pdfPage.Paragraphs.Add(linkHtmlfragment);

    string fileName = string.Concat("WorkInProgressReport_", "TestPDF");

	Response.Clear();
	Response.ContentType = "application/pdf";
	pdfDocument.Save(Response, fileName, Aspose.Pdf.ContentDisposition.Inline, new Aspose.Pdf.PdfSaveOptions());
	Response.End();

@sadyalajay

Thanks for your inquiry.

Please note that fixes against the issues, reported for older version(s) of the API, are provided in latest version of the API. Which is why we always recommend our customers to use latest version of the API because each new and latest version contains more fixes and improvements.

Now concerning to the Hyperlink related issue, we have tested the scenario with latest version of the API (i.e Aspose.Pdf for .NET 17.12) and were unable to notice the issue. Please check the following code snippet and attached output document for your reference.

Aspose.Pdf.Document pdfDocument = new Document();
var pdfPage = pdfDocument.Pages.Add();
Aspose.Pdf.HtmlFragment linkHtmlfragment = new Aspose.Pdf.HtmlFragment("<a style ='color:blue' href='https://www.google.com'>Click Me!</a>");
linkHtmlfragment.HtmlLoadOptions = new HtmlLoadOptions();
pdfPage.Paragraphs.Add(linkHtmlfragment);

MemoryStream ms = new MemoryStream();
pdfDocument.Save(ms);
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.Charset = "UTF-8";
Response.AddHeader("content-length", ms.Length.ToString());
Response.AddHeader("content-disposition", String.Format("attachment;filename=Hyperlink.pdf", "FileName"));
Response.ContentType = "application/pdf"; Response.BinaryWrite(ms.ToArray());
Response.Flush();
Response.End();

Hyperlink (2).pdf (23.7 KB)

Furthermore, we have also noticed that in your sample HTML string, you were using src attribute instead of href. We have replaced it with href (e.g <a href='http://google.com'>Click Me</a>) and Hyperlink was working in the output PDF document.

Please try to test your scenario with latest version of the API and in case you experience any issue with latest version, please feel free to let us know. We will test the scenario in our environment and address it accordingly.

Hi Asad,

I have tested above with 17.12 , the anchor tag is working fine with one image. but when I added more then one images. the anchor tag stop working.

I am giving the link below for html markup of file and below is the code.

       Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document();
       Aspose.Pdf.Page pdfPage = pdfDocument.Pages.Add();

     string htmlContent = System.IO.File.ReadAllText(Server.MapPath("~/PhotoHtmlMarkup.txt"));
	Aspose.Pdf.HtmlFragment htmlFragment = new Aspose.Pdf.HtmlFragment(htmlContent);
	htmlFragment.HtmlLoadOptions = new Aspose.Pdf.HtmlLoadOptions();
	pdfPage.Paragraphs.Add(htmlFragment);

	string fileName = string.Concat("AlbumTestPDF");

	using (var streamMemory = new MemoryStream())
	{
		Response.Clear();
		pdfDocument.Save(streamMemory);
		pdfDocument.FreeMemory();
		Response.ContentType = "application/pdf";
		Response.AddHeader("content-disposition", string.Format("inline;filename={0}.pdf", fileName));
		Response.Buffer = true;
		var bytes = streamMemory.ToArray();
		Response.BinaryWrite(bytes);
		Response.End();
	}