TOC as first page
tableofcontents
TableOfContents JAVA
JAVA
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2023 Apryse Group NV
Authors: Apryse Software.
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
package com.itextpdf.samples.sandbox.bookmarks;
import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PageLabelNumberingStyle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfOutline;
import com.itextpdf.kernel.pdf.PdfString;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.action.PdfAction;
import com.itextpdf.kernel.pdf.canvas.draw.DottedLine;
import com.itextpdf.kernel.pdf.navigation.PdfDestination;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Tab;
import com.itextpdf.layout.element.TabStop;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.layout.LayoutResult;
import com.itextpdf.layout.properties.TabAlignment;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.renderer.ParagraphRenderer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
public class TableOfContents {
public static final String DEST = "./target/sandbox/bookmarks/table_of_contents.pdf";
public static final String SRC = "./src/main/resources/txt/tree.txt";
public static void main(String args[]) throws Exception {
File file = new File(DEST);
file.getParentFile().mkdirs();
new TableOfContents().manipulatePdf(DEST);
}
public void manipulatePdf(String dest) throws Exception {
PdfFont font = PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN);
PdfFont bold = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD);
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdfDoc);
document
.setTextAlignment(TextAlignment.JUSTIFIED)
.setFont(font)
.setFontSize(11);
List<SimpleEntry<String, SimpleEntry<String, Integer>>> toc = new ArrayList<>();
// Parse text to PDF
createPdfWithOutlines(SRC, document, toc, bold);
// Remove the main title from the table of contents list
toc.remove(0);
// Create table of contents
document.add(new AreaBreak());
Paragraph p = new Paragraph("Table of Contents")
.setFont(bold)
.setDestination("toc");
document.add(p);
List<TabStop> tabStops = new ArrayList<>();
tabStops.add(new TabStop(580, TabAlignment.RIGHT, new DottedLine()));
for (SimpleEntry<String, SimpleEntry<String, Integer>> entry : toc) {
SimpleEntry<String, Integer> text = entry.getValue();
p = new Paragraph()
.addTabStops(tabStops)
.add(text.getKey())
.add(new Tab())
.add(String.valueOf(text.getValue()))
.setAction(PdfAction.createGoTo(entry.getKey()));
document.add(p);
}
// Move the table of contents to the first page
int tocPageNumber = pdfDoc.getNumberOfPages();
pdfDoc.movePage(tocPageNumber, 1);
// Add page labels
pdfDoc.getPage(1).setPageLabel(PageLabelNumberingStyle.UPPERCASE_LETTERS,
null, 1);
pdfDoc.getPage(2).setPageLabel(PageLabelNumberingStyle.DECIMAL_ARABIC_NUMERALS,
null, 1);
document.close();
}
private static void createPdfWithOutlines(String path, Document document,
List<SimpleEntry<String, SimpleEntry<String, Integer>>> toc, PdfFont titleFont) throws Exception {
PdfDocument pdfDocument = document.getPdfDocument();
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
String line;
boolean title = true;
int counter = 0;
PdfOutline outline = null;
while ((line = br.readLine()) != null) {
Paragraph p = new Paragraph(line);
p.setKeepTogether(true);
if (title) {
String name = String.format("title%02d", counter++);
outline = createOutline(outline, pdfDocument, line, name);
SimpleEntry<String, Integer> titlePage = new SimpleEntry(line, pdfDocument.getNumberOfPages());
p
.setFont(titleFont)
.setFontSize(12)
.setKeepWithNext(true)
.setDestination(name)
// Add the current page number to the table of contents list
.setNextRenderer(new UpdatePageRenderer(p, titlePage));
document.add(p);
toc.add(new SimpleEntry(name, titlePage));
title = false;
} else {
p.setFirstLineIndent(36);
if (line.isEmpty()) {
p.setMarginBottom(12);
title = true;
} else {
p.setMarginBottom(0);
}
document.add(p);
}
}
}
}
private static PdfOutline createOutline(PdfOutline outline, PdfDocument pdf, String title, String name) {
if (outline == null) {
outline = pdf.getOutlines(false);
outline = outline.addOutline(title);
outline.addDestination(PdfDestination.makeDestination(new PdfString(name)));
} else {
PdfOutline kid = outline.addOutline(title);
kid.addDestination(PdfDestination.makeDestination(new PdfString(name)));
}
return outline;
}
private static class UpdatePageRenderer extends ParagraphRenderer {
protected SimpleEntry<String, Integer> entry;
public UpdatePageRenderer(Paragraph modelElement, SimpleEntry<String, Integer> entry) {
super(modelElement);
this.entry = entry;
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
entry.setValue(layoutContext.getArea().getPageNumber());
return result;
}
}
}
TableOfContents C#
C#
using System;
using System.Collections.Generic;
using System.IO;
using iText.IO.Font.Constants;
using iText.Kernel.Font;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Action;
using iText.Kernel.Pdf.Canvas.Draw;
using iText.Kernel.Pdf.Navigation;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Layout;
using iText.Layout.Properties;
using iText.Layout.Renderer;
namespace iText.Samples.Sandbox.Bookmarks
{
public class TableOfContents
{
public static readonly String DEST = "results/sandbox/bookmarks/table_of_contents.pdf";
public static readonly String SRC = "../../../resources/text/tree.txt";
public static void Main(string[] args)
{
FileInfo file = new FileInfo(DEST);
file.Directory.Create();
new TableOfContents().ManipulatePdf(DEST);
}
public void ManipulatePdf(String dest)
{
PdfFont font = PdfFontFactory.CreateFont(StandardFonts.TIMES_ROMAN);
PdfFont bold = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD);
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdfDoc);
document
.SetTextAlignment(TextAlignment.JUSTIFIED)
.SetFont(font)
.SetFontSize(11);
List<Pair<String, Pair<String, int>>> toc =
new List<Pair<string, Pair<string, int>>>();
// Parse text to PDF
CreatePdfWithOutlines(SRC, document, toc, bold);
// Remove the main title from the table of contents list
toc.RemoveAt(0);
// Create table of contents
document.Add(new AreaBreak());
Paragraph p = new Paragraph("Table of Contents")
.SetFont(bold)
.SetDestination("toc");
document.Add(p);
List<TabStop> tabStops = new List<TabStop>();
tabStops.Add(new TabStop(580, TabAlignment.RIGHT, new DottedLine()));
foreach (Pair<String, Pair<String, int>> entry in toc)
{
Pair<String, int> text = entry.Value;
p = new Paragraph()
.AddTabStops(tabStops)
.Add(text.Key)
.Add(new Tab())
.Add(text.Value.ToString())
.SetAction(PdfAction.CreateGoTo(entry.Key));
document.Add(p);
}
// Move the table of contents to the first page
int tocPageNumber = pdfDoc.GetNumberOfPages();
pdfDoc.MovePage(tocPageNumber, 1);
// Add page labels
pdfDoc.GetPage(1).SetPageLabel(PageLabelNumberingStyle.UPPERCASE_LETTERS,
null, 1);
pdfDoc.GetPage(2).SetPageLabel(PageLabelNumberingStyle.DECIMAL_ARABIC_NUMERALS,
null, 1);
document.Close();
}
private static void CreatePdfWithOutlines(String path, Document document,
List<Pair<String, Pair<String, int>>> toc, PdfFont titleFont)
{
PdfDocument pdfDocument = document.GetPdfDocument();
using (StreamReader br = new StreamReader(new FileStream(path, FileMode.Open)))
{
String line;
bool title = true;
int counter = 0;
PdfOutline outline = null;
while ((line = br.ReadLine()) != null)
{
Paragraph p = new Paragraph(line);
p.SetKeepTogether(true);
if (title)
{
String name = String.Format("title0{0}", counter++);
outline = CreateOutline(outline, pdfDocument, line, name);
Pair<String, int> titlePage =
new Pair<String, int>(line, pdfDocument.GetNumberOfPages());
p
.SetFont(titleFont)
.SetFontSize(12)
.SetKeepWithNext(true)
.SetDestination(name)
// Add the current page number to the table of contents list
.SetNextRenderer(new UpdatePageRenderer(p, titlePage));
document.Add(p);
toc.Add(new Pair<String, Pair<String, int>>(name, titlePage));
title = false;
}
else
{
p.SetFirstLineIndent(36);
if (line.Equals(""))
{
p.SetMarginBottom(12);
title = true;
}
else
{
p.SetMarginBottom(0);
}
document.Add(p);
}
}
}
}
private static PdfOutline CreateOutline(PdfOutline outline, PdfDocument pdf, String title, String name)
{
if (outline == null)
{
outline = pdf.GetOutlines(false);
outline = outline.AddOutline(title);
outline.AddDestination(PdfDestination.MakeDestination(new PdfString(name)));
}
else
{
PdfOutline kid = outline.AddOutline(title);
kid.AddDestination(PdfDestination.MakeDestination(new PdfString(name)));
}
return outline;
}
private class UpdatePageRenderer : ParagraphRenderer
{
protected Pair<String, int> entry;
public UpdatePageRenderer(Paragraph modelElement, Pair<String, int> entry) :
base(modelElement)
{
this.entry = entry;
}
public override LayoutResult Layout(LayoutContext layoutContext)
{
LayoutResult result = base.Layout(layoutContext);
entry.Value = layoutContext.GetArea().GetPageNumber();
return result;
}
}
private class Pair<T, U>
{
public Pair(T first, U second)
{
this.Key = first;
this.Value = second;
}
public T Key { get; set; }
public U Value { get; set; }
};
}
}
Resources