如何在iTextSharp中创建目录

我需要用页码创建内容表,但我不知道如何。 下一格式:

heading1 ----------------page number subHeading1---------------page number subHeading2---------------page number heading2-----------------page number 

我读了几篇文章而且听不懂。特别是,我的意思是这篇文章,我认为“命名目的地”和“GoTo动作”对我有用,但我不知道它在iTextSharp中是怎么做的。

在我的代码中,我有很少的“章节”和“章节”,我想拿它并创建TOC。 我是如何理解的,我需要使用PdfPageEventHelper和OnChapter。

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

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

在此处输入图像描述

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

在此处输入图像描述

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

 public class TOCEvent extends PdfPageEventHelper { protected List> 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; } } 

我们使用这样的页面事件:

 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> entries = event.getTOC(); Paragraph p; for (SimpleEntry entry : entries) { p = new Paragraph(entry.getKey()); p.add(dottedLine); p.add(String.valueOf(entry.getValue())); document.add(p); } document.close(); } 

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

 TOCEvent event = new TOCEvent(); writer.setPageEvent(event); 

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

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

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

 List> entries = event.getTOC(); 

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

 for (SimpleEntry entry : entries) { p = new Paragraph(entry.getKey()); p.add(dottedLine); p.add(String.valueOf(entry.getValue())); document.add(p); } 

没人能说这很难。 事件类只需少于10行代码。 添加对副标题的支持将添加一些行,但这也不难。 这是建立树结构的问题,并在必要时引入一些缩进。

谢谢你的例子,我需要在C#和多列中使用它,所以我重写了这个例子,如下所示:

 namespace GerarPDF { public class GerarPDF { public const String DEST = "results/example.pdf"; public GerarPDF() { FileInfo file = new FileInfo(String.Concat(AppDomain.CurrentDomain.BaseDirectory, @"/", DEST)); file.Directory.Create(); this.createPdf(file.FullName); } public void createPdf(String dest) { FileStream fs = new FileStream(dest, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); Document document = new Document(PageSize.LETTER); PdfWriter writer = PdfWriter.GetInstance(document, fs); document.Open(); TOCEvent evento = new TOCEvent(); writer.PageEvent = evento; for (int i = 0; i < 10; i++) { String title = "This is title " + i; Chunk c = new Chunk(title, new Font()); c.SetGenericTag(title); document.Add(new Paragraph(c)); for (int j = 0; j < 50; j++) { document.Add(new Paragraph("Line " + j + " of title " + i + " page: " + writer.PageNumber)); } } document.NewPage(); document.Add(new Paragraph("Table of Contents", new Font())); Chunk dottedLine = new Chunk(new DottedLineSeparator()); List entries = evento.getTOC(); MultiColumnText columns = new MultiColumnText(); columns.AddRegularColumns(72, 72 * 7.5f, 24, 2); Paragraph p; for (int i = 0; i < 10; i++) { foreach (PageIndex pageIndex in entries) { Chunk chunk = new Chunk(pageIndex.Text); chunk.SetAction(PdfAction.GotoLocalPage(pageIndex.Name, false)); p = new Paragraph(chunk); p.Add(dottedLine); chunk = new Chunk(pageIndex.Page.ToString()); chunk.SetAction(PdfAction.GotoLocalPage(pageIndex.Name, false)); p.Add(chunk); columns.AddElement(p); } } document.Add(columns); document.Close(); } public class TOCEvent : PdfPageEventHelper { protected int counter = 0; protected List toc = new List(); public override void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, string text) { String name = "dest" + (counter++); int page = writer.PageNumber; toc.Add(new PageIndex() { Text = text, Name = name, Page = page }); writer.DirectContent.LocalDestination(name, new PdfDestination(PdfDestination.FITH, rect.GetTop(0))); } public List getTOC() { return toc; } } } public class PageIndex { public string Text { get; set; } public string Name { get; set; } public int Page { get; set; } } } 

这个snipplet可以是递归的,基本概念是:

 List celdas = new List(); string urlSection=String.empty; var estatus = new Phrase(); estatus.Leading = 25; if (streams != null && streams.Any()) primero = streams.FirstOrDefault(x => x.Id == enlace.Id); if (primero != null) urlSection = primero.UrlSection; //For the code and generate hyperlink: Chunk espacioTab = new Chunk(" " + enlace.Name, baseFontBig ); espacioTab = Visor.Servicios.GeneracionPDF.PDFUtils.GenerarVinculo(" " + enlace.Name, urlSection, baseFontBig); estatus.Add(espacioTab); if (incluirPaginado) { if (primero != null) actualPage = primero.TotalPages; else actualPage = 0; ///This is important, generate dots like "...." to chunk end estatus.Add(new Chunk(new iTextSharp.text.pdf.draw.DottedLineSeparator())); var linkPagina = new Chunk(actualPage.ToString()); linkPagina = Visor.Servicios.GeneracionPDF.PDFUtils.GenerarVinculo(actualPage.ToString(), urlSection, baseFontBig ); estatus.Add(linkPagina); resultado.paginaFinal = actualPage; } //This is for add to your cell or table PdfPCell rightCell = new PdfPCell() { Border = PdfPCell.NO_BORDER, Colspan = 3, PaddingLeft = espacioInicial.Length, ExtraParagraphSpace = 10, }; rightCell.AddElement(estatus); celdas.Add(rightCell); 

并创建一个新方法,这将创建一个超链接,您可以随时调用invoque

 /*Generar Vinculo (create hyperlink)**/ public static Chunk GenerarVinculo(String tituloMostrar, string urlDirecion, iTextSharp.text.Font fuente) { Chunk espacioTab = new Chunk(); try { if (String.IsNullOrEmpty(urlDirecion)) urlDirecion = "Indice de Contenido"; espacioTab = new Chunk(tituloMostrar, fuente); var accion = PdfAction.GotoLocalPage(urlDirecion, false); espacioTab.SetAction(accion); } catch (Exception error) { } return espacioTab; } 

希望帮助某人