Aspose Pdf for .NET TOC Dynamically

I’m creating a pdf document with aspose pdf generator for .Net. As my data is very large i don’t know how much pages it will be. So on creating TOC the destination page number is unknown for me.So is there any way to create TOC dynamically…?

@AkhilAkku

Thanks for contacting support.

In order to get correct PageCount, you can call Document.ProcessParagraphs method, after which you will get correct count of pages. After calling the suggested method, all inserted content inside PDF will be mapped and you will be able to create TOC with correct count of pages.Please check following sample code snippet, which will demonstrate the usage of this method.

Document doc = new Document();
var page = doc.Pages.Add();
Table table = new Table();

Row Header = new Row();
Header.Cells.Add("header");
Header.Cells.Add("header");
table.Rows.Add(Header);
            
Row r = new Row();
r.Cells.Add("Cell");
r.Cells.Add("Cell");
int i = 0;
while (i < 80)
{
 table.Rows.Add(r);
 i++;
}
table.RepeatingRowsCount = 1;
page.Paragraphs.Add(table);

int countbefore = doc.Pages.Count;
doc.ProcessParagraphs();
int countafter = doc.Pages.Count;

doc.Save(dataDir + "PageBreakTable.pdf");

PageCount.png (1.0 KB)

In case of any further assistance, please feel free to let us know.

Thanks for the quick reply. But I have some doubts…
Can we use doc.ProcessParagraphs() mutiple times as I have multiple tables rendering with large html stuffs…? And get the current page number as doc.Pages.Count …?

@AkhilAkku

Thanks for writing back.

You may use Document.ProcessParagraphs() method multiple times while inserting content into PDF, which causes auto page generation when content length is larger. OR you may simply call this method after all content is added to PDF and before adding TOC, so that you can get correct count of pages.

In case you face any issue, please share your sample code snippet along with sample PDF document, so that we can test the scenario in our environment and address it accordingly.

I will share my sample code which i have tried… My requirement is to have all headings in the loop to be in the TOC.

Document myDocument = new Document();
Page page = myDocument.Pages.Add();
page.SetPageSize(PageSize.A4.Width, PageSize.A4.Height);

Aspose.Pdf.MarginInfo margin = new Aspose.Pdf.MarginInfo();
margin.Top = 5f;
margin.Left = 5f;
margin.Right = 5f;
margin.Bottom = 5f;


Table titleTable = new Table();
titleTable.HorizontalAlignment = HorizontalAlignment.Center;
titleTable.ColumnAdjustment = ColumnAdjustment.AutoFitToContent;
page.Paragraphs.Add(titleTable);
titleTable.DefaultCellBorder = new BorderInfo(BorderSide.All, 0);
titleTable.Border = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.All, 0);
titleTable.DefaultCellPadding = margin;
Aspose.Pdf.Row row1 = titleTable.Rows.Add();
row1.Cells.Add();
HtmlFragment mytext = new HtmlFragment("<p style='text-align:center;font-size:44;'><b>Test Heading</b></p>");
row1.Cells[0].Paragraphs.Add(mytext);
row1.Cells[0].IsWordWrapped = false;

for (int i = 1; i < 6; i++)
{
  TextFragment heading = new TextFragment("Heading :" + i);
  var toc = new TOCAspose();
  toc.Key = heading.Text;
  toc.PageNumber = myDocument.Pages.Count+1;
  TocList.Add(toc);
  page.Paragraphs.Add(heading);
  HtmlFragment tableData = new HtmlFragment("<p style='text-align:center;font-size:25;'><b>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. 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, and more recently with </b></p>");
   Table sampleTable = new Table();
                 
   sampleTable.ColumnAdjustment = ColumnAdjustment.AutoFitToContent;
   sampleTable.Border= new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.All, 1);
   page.Paragraphs.Add(sampleTable);

   Aspose.Pdf.Row samplerow1 = sampleTable.Rows.Add();
   samplerow1.Cells.Add().Paragraphs.Add(tableData);
   myDocument.ProcessParagraphs();
   int currentPage = myDocument.Pages.Count;
 }


 TextStamp textStamp = new TextStamp("");
 textStamp.HorizontalAlignment = HorizontalAlignment.Center;
 textStamp.VerticalAlignment = VerticalAlignment.Bottom;
 foreach (Page pages in myDocument.Pages)
 {
                    textStamp.Value = "Page " + pages.Number +" of " + myDocument.Pages.Count;
                    pages.AddStamp(textStamp);
 }
myDocument.Save("Final Report.pdf");

After all im facing another issue that some of the tables are overlapped at the end of the page. Did I missed anything…?? And could you please help me to create a TOC for this. I will attach the sample PDF document of the above code.Final report (20).pdf (119.3 KB)

@AkhilAkku

Thanks for sharing sample code snippet.

Please check following code snippet, where I have added TOC in the PDF dynamically, while creating it. For your reference, I have attached and output PDF document as well.

Document myDocument = new Document();
Page page = myDocument.Pages.Add();
page.SetPageSize(PageSize.A4.Width, PageSize.A4.Height);

Aspose.Pdf.MarginInfo margin = new Aspose.Pdf.MarginInfo();
margin.Top = 5f;
margin.Left = 5f;
margin.Right = 5f;
margin.Bottom = 5f;


Table titleTable = new Table();
titleTable.HorizontalAlignment = HorizontalAlignment.Center;
titleTable.ColumnAdjustment = ColumnAdjustment.AutoFitToContent;
page.Paragraphs.Add(titleTable);
titleTable.DefaultCellBorder = new BorderInfo(BorderSide.All, 0);
titleTable.Border = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.All, 0);
titleTable.DefaultCellPadding = margin;
Aspose.Pdf.Row row1 = titleTable.Rows.Add();
row1.Cells.Add();
HtmlFragment mytext = new HtmlFragment("<p style='text-align:center;font-size:44;'><b>Test Heading</b></p>");
row1.Cells[0].Paragraphs.Add(mytext);
row1.Cells[0].IsWordWrapped = false;
List<string> Titles = new List<string>();
for (int i = 1; i < 6; i++)
{
  string title = "Heading :" + i;
  Titles.Add(title);
  Heading heading = new Heading(1);
  heading.Text = title;
  page.Paragraphs.Add(heading);
  HtmlFragment tableData = new HtmlFragment("<p style='text-align:center;font-size:25;'><b>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. 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, and more recently with </b></p>");
  Table sampleTable = new Table();

  sampleTable.ColumnAdjustment = ColumnAdjustment.AutoFitToContent;
  sampleTable.Border = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.All, 1);
  page.Paragraphs.Add(sampleTable);

 Aspose.Pdf.Row samplerow1 = sampleTable.Rows.Add();
 samplerow1.Cells.Add().Paragraphs.Add(tableData);
}

myDocument.ProcessParagraphs();

Aspose.Pdf.Page tocPage = myDocument.Pages.Insert(1);

// Create object to represent TOC information 
TocInfo tocInfo = new TocInfo();
TextFragment toctitle = new TextFragment("Table Of Contents");
toctitle.TextState.FontSize = 20;
toctitle.TextState.FontStyle = FontStyles.Bold;

// Set the title for TOC 
tocInfo.Title = toctitle;
tocPage.TocInfo = tocInfo;

for (int i = 0; i < Titles.Count; i++)
{
 // Create Heading object 
 Aspose.Pdf.Heading heading2 = new Aspose.Pdf.Heading(1);
 TextSegment segment2 = new TextSegment();
 heading2.TocPage = tocPage;
 heading2.Segments.Add(segment2);

 TextFragmentAbsorber tfa = new TextFragmentAbsorber(Titles[i]);
 myDocument.Pages.Accept(tfa);

 heading2.DestinationPage = tfa.TextFragments[1].Page;
 heading2.Top = tfa.TextFragments[1].Page.Rect.Height;
 segment2.Text = Titles[i];
 tocPage.Paragraphs.Add(heading2);
}

TextStamp textStamp = new TextStamp("");
textStamp.HorizontalAlignment = HorizontalAlignment.Center;
textStamp.VerticalAlignment = VerticalAlignment.Bottom;
foreach (Page pages in myDocument.Pages)
{
 textStamp.Value = "Page " + pages.Number + " of " + myDocument.Pages.Count;
 pages.AddStamp(textStamp);
}
myDocument.Save(dataDir + "Final Report.pdf");

Final Report.pdf (49.9 KB)

In case of any further assistance, please feel free to contact us.