如何在iTextSharp中创建目录

Nao*_*iss 5 c# pdf itext

我需要用页码创建目录,但是我不知道如何。下一种格式:

heading1 ----------------page number  
  subHeading1---------------page number
  subHeading2---------------page number  
heading2-----------------page number  
Run Code Online (Sandbox Code Playgroud)

我读了几篇文章,听不懂。特别是,我的意思是说这篇文章,我认为“命名目的地”和“ GoTo操作”对我很有用,但我不知道如何在iTextSharp中使用它。

在我的代码中,我有一些“章节”和“部分”,并且我想采用它并创建一个目录。我了解我需要使用PdfPageEventHelper和OnChapter。

Bru*_*gie 5

你可能已经按名字自己实现了这个,但为了完整起见,我自己做了一个小例子。

请看一下CreateTOC示例。它创建一个带有一些随机文本的 PDF:

在此处输入图片说明

您可以清楚地看到标题和标题下的内容。添加完所有内容后,我们开始一个新页面,并添加一个目录:

在此处输入图片说明

目录由一系列键值对组成,其中键是标题,值是页码。我们在页面事件中创建此列表:

public class TOCEvent extends PdfPageEventHelper {

    protected List<SimpleEntry<String, Integer>> toc = new ArrayList<>();

    @Override
    public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) {
        toc.add(new SimpleEntry(text, writer.getPageNumber()));
    }

    public List getTOC() {
        return toc;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们像这样使用这个页面事件:

public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
    TOCEvent event = new TOCEvent();
    writer.setPageEvent(event);
    document.open();
    for (int i = 0; i < 10; i++) {
        String title = "This is title " + i;
        Chunk c = new Chunk(title, titleFont);
        c.setGenericTag(title);
        document.add(new Paragraph(c));
        for (int j = 0; j < 50; j++) {
            document.add(new Paragraph("Line " + j + " of title " + i));
        }
    }
    document.newPage();
    document.add(new Paragraph("Table of Contents", titleFont));
    Chunk dottedLine = new Chunk(new DottedLineSeparator());
    List<SimpleEntry<String, Integer>> entries = event.getTOC();
    Paragraph p;
    for (SimpleEntry<String, Integer> entry : entries) {
        p = new Paragraph(entry.getKey());
        p.add(dottedLine);
        p.add(String.valueOf(entry.getValue()));
        document.add(p);
    }
    document.close();
}
Run Code Online (Sandbox Code Playgroud)

首先,我们创建事件的一个实例,并将其声明给作者:

TOCEvent event = new TOCEvent();
writer.setPageEvent(event);
Run Code Online (Sandbox Code Playgroud)

我们使用setGenericTag()以下标记标题:

String title = "This is title " + i;
Chunk c = new Chunk(title, titleFont);
c.setGenericTag(title);
document.add(new Paragraph(c));
Run Code Online (Sandbox Code Playgroud)

添加完内容后,我们将获得所有条目:

List<SimpleEntry<String, Integer>> entries = event.getTOC();
Run Code Online (Sandbox Code Playgroud)

我们遍历这个列表并Paragraph为每个条目组成一个:

for (SimpleEntry<String, Integer> entry : entries) {
    p = new Paragraph(entry.getKey());
    p.add(dottedLine);
    p.add(String.valueOf(entry.getValue()));
    document.add(p);
}
Run Code Online (Sandbox Code Playgroud)

没有人可以争辩说这是困难的。事件类只需要不到 10 行代码。添加对副标题的支持将添加一些行,但这也不难。这是构建树结构并在必要时引入一些缩进的问题。