2014-02-28 70 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