我用一些Chapter
創建了一個文檔。如何使用iText生成目錄「TOC」?
如何爲此文檔生成目錄?
它應該是這樣的:
TOC:
Chapter 1 3
Chapter 2 4
Chapter 3 6
Chapter 4 9
Chapter 5 10
我用一些Chapter
創建了一個文檔。如何使用iText生成目錄「TOC」?
如何爲此文檔生成目錄?
它應該是這樣的:
TOC:
Chapter 1 3
Chapter 2 4
Chapter 3 6
Chapter 4 9
Chapter 5 10
這可以通過使用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
由基督教施耐德答案似乎有點複雜。我也會使用頁面事件,但我會使用onChapter()
方法創建章節標題和頁碼列表。如果您還需要Section
標題,請使用onSection()
方法跟蹤這些部分。
一旦你有了這個列表,在文檔的末尾創建TOC。如果你想把TOC移到前面,請閱讀我對這個問題的回答:PDF Page re-ordering using itext
這就像一個魅力! TOC中的搖擺甚至可以鏈接到實際的章節。我怎樣才能在頁碼上加上類似的鏈接?我嘗試在onChapter和onSection方法中的模板上設置PdfAction.gotoLocalPage,但那不起作用... –