创建PDF目录与链接到文本章节

本文关键字:文本 链接 PDF 创建 | 更新日期: 2023-09-27 18:03:42

我创建PDF文档,但我有链接到文本章节的问题。我从这里使用Bruno Lowagie的代码,但它是Java的,我遇到了一些困难。

我是这样做的:

类TOCEvents

public class TOCEvents : PdfPageEventHelper
{
    //protected System.Collections.Generic.List<TitleTOC> toc = new System.Collections.Generic.List<TitleTOC>();
    protected Dictionary<string, int> toc = new Dictionary<string, int>(5);
    public override void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, String text)
    {
        toc.Add(text, writer.PageNumber);
    }
    public Dictionary<string, int> GetTOC()
    {
        return toc;
    }
}
主要

                    for (int i = 0; i < 10; i++)
                {
                    String title = "This is title " + i;
                    Chunk c = new Chunk(title, f14);
                    c.SetGenericTag(title);
                    doc.Add(new Paragraph(c));
                    for (int j = 0; j < 50; j++)
                    {
                        doc.Add(new Paragraph("Line " + j + " of title " + i));
                    }
                }
                doc.NewPage();
                doc.Add(new Paragraph("Table of Contents", f24));
                Chunk dottedLine = new Chunk(new iTextSharp.text.pdf.draw.DottedLineSeparator());
                Dictionary<string, int> entries = ev.GetTOC();
                Paragraph p;
                foreach (KeyValuePair<string, int> entry in entries)
                {
                    Chunk chunk = new Chunk(entry.Key);
                    chunk.SetAction(PdfAction.GotoLocalPage(entry.Key, false));
                    p = new Paragraph(chunk);
                    p.Add(dottedLine);
                    chunk = new Chunk(entry.Value.ToString());
                    chunk.SetAction(PdfAction.GotoLocalPage(entry.Key, false));
                    p.Add(chunk);
                    doc.Add(p);

                }

我有这个问题:

foreach (KeyValuePair<string, int> entry in entries)
                {
                    Chunk chunk = new Chunk(entry.Key);
                    chunk.SetAction(PdfAction.GotoLocalPage(entry.Key, false));
                    p = new Paragraph(chunk);
                    p.Add(dottedLine);
                    chunk = new Chunk(entry.Value.ToString());
                    chunk.SetAction(PdfAction.GotoLocalPage(entry.Key, false));
                    p.Add(chunk);
                    doc.Add(p);

                }

我做错了什么?我不能设置文本章节的链接。我想我用错了Dictionary<string, int>。我哪里错了?

谢谢。

创建PDF目录与链接到文本章节

您正在创建这样的TOC:

| key       | page number |
|-----------|-------------|
| Chapter 1 |    1        |
| Chapter 2 |    5        |
| Chapter 3 |    7        |
| Chapter 4 |    9        |
| Chapter 5 |   10        |

你像这样呈现这个信息:

Chapter 1 ................... 1
Chapter 2 ................... 5
Chapter 3 ................... 7
Chapter 4 ................... 9
Chapter 5 .................. 10

您可以这样做:当您单击TOC中的标题或页码时,您将触发指向名称为Chapter X的命名目的地的链接,其中X是1到5之间的数字。

当你点击那个链接时什么也没有发生,也应该没有发生,因为你没有在任何地方定义任何名称为Chapter X的目的地。

您已经复制了我用Java为您编写的代码,更具体地说是CreateTOC2示例。我写这个例子是基于一个例子,是写在回答你之前的问题如何创建目录在iTextSharp

但是,您忽略了TOCEvent变化的事实:

public class TOCEvent extends PdfPageEventHelper {
    protected int counter = 0;
    protected List<SimpleEntry<String, SimpleEntry<String, Integer>>> toc = new ArrayList<>();
    @Override
    public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) {
        String name = "dest" + (counter++);
        int page = writer.getPageNumber();
        toc.add(new SimpleEntry<String, SimpleEntry<String, Integer>>(text, new SimpleEntry<String, Integer>(name, page)));
        writer.addNamedDestination(name, page, new PdfDestination(PdfDestination.FITH, rect.getTop()));
    }
    public List<SimpleEntry<String, SimpleEntry<String, Integer>>> getTOC() {
        return toc;
    }
}

在这个新的TOCEvent中,我们跟踪counter。每次遇到一个标题,就创建一个新的(唯一的!)名称,计数器上升。

 String name = "dest" + (counter++);

使用这个名称,您必须创建一个命名的目的地。在本例中,我们在特定的Y位置创建一个/FitH(水平对齐)目标:

writer.addNamedDestination(
    name,  // the unique name
    page,  // the current page number where the title is added
    new PdfDestination(        // the destination on that page
        PdfDestination.FITH, rect.getTop()));

您没有添加任何这样的目标,因此您无法链接到文档中的任何命名目标。

在我的示例中,我将唯一名称传递给TOC:
| key       | named destination | page number |
|-----------|-------------------|-------------|
| Chapter 1 |    dest0          |    1        |
| Chapter 2 |    dest1          |    5        |
| Chapter 3 |    dest2          |    7        |
| Chapter 4 |    dest3          |    9        |
| Chapter 5 |    dest4          |   10        |

当我创建TOC时,我使用这些名称,dest0, dest1,…要创建这样的操作:

PdfAction.gotoLocalPage("dest0", false)
PdfAction.gotoLocalPage("dest1", false)
PdfAction.gotoLocalPage("dest2", false)
PdfAction.gotoLocalPage("dest3", false)
PdfAction.gotoLocalPage("dest4", false)

如果使用了错误的值,就会创建如下链接:

PdfAction.gotoLocalPage("Chapter 1", false)
PdfAction.gotoLocalPage("Chapter 2", false)
PdfAction.gotoLocalPage("Chapter 3", false)
PdfAction.gotoLocalPage("Chapter 4", false)
PdfAction.gotoLocalPage("Chapter 5", false)

这永远不能工作,除非你使用Chapter 1, Chapter 2,…作为指定目的地的名称。因为你不能确定这些名字总是唯一的,我认为我的方法是更好的选择。

你的问题的答案我做错了什么?很简单:您正在创建链接,但是您忘记创建目的地。