2014-02-28 71 views

回答

11

这可以通过使用PdfTemplate秒。 PdfTemplate s是一种占位符,您可以随后填写。

更新与布鲁诺提示:

要在TOC产生之初,你需要把一些占位符在TOC中的所有页码。您在Map收集的那些PdfTemplate。然后,当您将Chapter添加到文档中时,您可以填充这些占位符。

这个例子说明了如何:生成的PDF

public class Main extends PdfPageEventHelper 
{ 
    private final Document     document; 
    private final PdfWriter    writer; 
    private final BaseFont     baseFont  = BaseFont.createFont(); 
    private final Font      chapterFont = FontFactory.getFont(FontFactory.HELVETICA, 24, Font.NORMAL); 

    // table to store placeholder for all chapters and sections 
    private final Map<String, PdfTemplate> tocPlaceholder = new HashMap<>(); 

    // store the chapters and sections with their title here. 
    private final Map<String, Integer>  pageByTitle = new HashMap<>(); 

    public static void main(final String[] args) throws Exception 
    { 
     final Main main = new Main(); 

     main.document.add(new Paragraph("This is an example to generate a TOC.")); 
     main.createTOC(10); 
     main.createChapters(10); 
     main.document.close(); 
    } 

    public Main() throws Exception 
    { 
     this.document = new Document(PageSize.A6); 
     this.writer = PdfWriter.getInstance(this.document, new FileOutputStream("text.pdf")); 
     this.writer.setPageEvent(this); 
     this.document.open(); 
    } 

    @Override 
    public void onChapter(final PdfWriter writer, final Document document, final float paragraphPosition, final Paragraph title) 
    { 
     this.pageByTitle.put(title.getContent(), writer.getPageNumber()); 
    } 

    @Override 
    public void onSection(final PdfWriter writer, final Document document, final float paragraphPosition, final int depth, final Paragraph title) 
    { 
     this.pageByTitle.put(title.getContent(), writer.getPageNumber()); 
    } 

    private void createTOC(final int count) throws DocumentException 
    { 
     // add a small introduction chapter the shouldn't be counted. 
     final Chapter intro = new Chapter(new Paragraph("This is TOC ", this.chapterFont), 0); 
     intro.setNumberDepth(0); 
     this.document.add(intro); 

     for (int i = 1; i < count + 1; i++) 
     { 
      // Write "Chapter i" 
      final String title = "Chapter " + i; 
      final Chunk chunk = new Chunk(title).setLocalGoto(title); 
      this.document.add(new Paragraph(chunk)); 

      // Add a placeholder for the page reference 
      this.document.add(new VerticalPositionMark() { 
       @Override 
       public void draw(final PdfContentByte canvas, final float llx, final float lly, final float urx, final float ury, final float y) 
       { 
        final PdfTemplate createTemplate = canvas.createTemplate(50, 50); 
        Main.this.tocPlaceholder.put(title, createTemplate); 

        canvas.addTemplate(createTemplate, urx - 50, y); 
       } 
      }); 
     } 
    } 

    private void createChapters(final int count) throws DocumentException 
    { 
     for (int i = 1; i < count + 1; i++) 
     { 
      // append the chapter 
      final String title = "Chapter " + i; 
      final Chunk chunk = new Chunk(title, this.chapterFont).setLocalDestination(title); 
      final Chapter chapter = new Chapter(new Paragraph(chunk), i); 
      chapter.setNumberDepth(0); 

      chapter.addSection("Foobar1"); 
      chapter.addSection("Foobar2"); 
      this.document.add(chapter); 

      // When we wrote the chapter, we now the pagenumber 
      final PdfTemplate template = this.tocPlaceholder.get(title); 
      template.beginText(); 
      template.setFontAndSize(this.baseFont, 12); 
      template.setTextMatrix(50 - this.baseFont.getWidthPoint(String.valueOf(this.writer.getPageNumber()), 12), 0); 
      template.showText(String.valueOf(this.writer.getPageNumber())); 
      template.endText(); 

     } 
    } 
} 

看起来是这样的: TableOfContents.pdf

+0

这就像一个魅力! TOC中的摇摆甚至可以链接到实际的章节。我怎样才能在页码上加上类似的链接?我尝试在onChapter和onSection方法中的模板上设置PdfAction.gotoLocalPage,但那不起作用... –

2

由基督教施耐德答案似乎有点复杂。我也会使用页面事件,但我会使用onChapter()方法创建章节标题和页码列表。如果您还需要Section标题,请使用onSection()方法跟踪这些部分。

一旦你有了这个列表,在文档的末尾创建TOC。如果你想把TOC移到前面,请阅读我对这个问题的回答:PDF Page re-ordering using itext