创建PDF目录与链接到文本章节
本文关键字:文本 链接 PDF 创建 | 更新日期: 2023-09-27 18:03:42
我创建PDF文档,但我有链接到文本章节的问题。我从这里使用Bruno Lowagie的代码,但它是Java的,我遇到了一些困难。
我是这样做的:
类TOCEventspublic 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>
。我哪里错了?
谢谢。
您正在创建这样的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
,…作为指定目的地的名称。因为你不能确定这些名字总是唯一的,我认为我的方法是更好的选择。
你的问题的答案我做错了什么?很简单:您正在创建链接,但是您忘记创建目的地。