创建包含文本章节链接的 PDF Table 目录
Create PDF Table of Contents with links to chapter of text
我在创建 PDF 文档时遇到文本章节链接的问题。
我使用 here 的 Bruno Lowagie 代码,但它是 Java,我遇到了一些困难。
我是这样做的:
class 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>
。我哪里错了?
谢谢。
您正在创建这样的目录:
| 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
您这样做的方式是,当您单击目录中的标题或页码时,您会触发 link 到名称为 Chapter X
的指定目的地,其中 X 是从 1 到 5 的数字。
单击 link 时没有任何反应,也不应该发生任何反应,因为您尚未在任何地方定义名称为 Chapter X
的任何目的地。
您复制了我在 Java 中为您编写的代码,更具体地说是 CreateTOC2 example. I wrote this example based on an example that was written in answer to your previous question How to create Table Of Contents in 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()));
您没有添加任何此类目的地,因此您不能 link 到文档中的任何命名目的地。
在我的示例中,我将唯一名称传递给目录:
| 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)
您使用了错误的值,您创建的 link 是这样的:
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
、... 作为您指定目的地的名称。由于您无法确定这些名称将始终是唯一的,因此我认为我的方法是更好的选择。
您的问题我做错了什么?的答案很简单:您正在创建 link,但您忘记创建目的地。
我在创建 PDF 文档时遇到文本章节链接的问题。 我使用 here 的 Bruno Lowagie 代码,但它是 Java,我遇到了一些困难。
我是这样做的:
class 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>
。我哪里错了?
谢谢。
您正在创建这样的目录:
| 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
您这样做的方式是,当您单击目录中的标题或页码时,您会触发 link 到名称为 Chapter X
的指定目的地,其中 X 是从 1 到 5 的数字。
单击 link 时没有任何反应,也不应该发生任何反应,因为您尚未在任何地方定义名称为 Chapter X
的任何目的地。
您复制了我在 Java 中为您编写的代码,更具体地说是 CreateTOC2 example. I wrote this example based on an example that was written in answer to your previous question How to create Table Of Contents in 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()));
您没有添加任何此类目的地,因此您不能 link 到文档中的任何命名目的地。
在我的示例中,我将唯一名称传递给目录:
| 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)
您使用了错误的值,您创建的 link 是这样的:
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
、... 作为您指定目的地的名称。由于您无法确定这些名称将始终是唯一的,因此我认为我的方法是更好的选择。
您的问题我做错了什么?的答案很简单:您正在创建 link,但您忘记创建目的地。