当前位置: 首页 > 面试题库 >

如何使用iText生成目录“ TOC”?

荆钱明
2023-03-14
问题内容

我创建了一个带有Chapters 的文档。

如何生成此文档的目录?

它看起来应该像这样:

TOC:
Chapter 1                        3
Chapter 2                        4
Chapter 3                        6
Chapter 4                        9
Chapter 5                       10

问题答案:

通过使用PdfTemplates 可以实现。PdfTemplates是一种可以稍后填充的占位符。

来自Bruno的提示更新:

要在开始时在目录中生成,您需要为目录中的所有页码放置一些占位符。PdfTemplate你收集的那些Map。然后,将Chapters
添加到文档中时,可以填充这些占位符。

此示例显示如何:

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();

        }
    }
}

生成的PDF如下所示:
TableOfContents.pdf



 类似资料:
  • 我的版本:jkd11 我尝试了下面的代码,但抛出了Docx4JException,但github演示就是这样https://github.com/plutext/docx4j/blob/docx4j-parent-11.1.0/docx4j-samples-docx4j/src/main/java/org/docx4j/samples/TocAdd.java

  • 问题内容: 我在使用Python生成html文档时遇到了一些问题。我正在尝试创建目录树的HTML列表。这是我到目前为止所拥有的: 如果只有根目录,一级子目录和文件,这似乎很好。但是,添加另一级子目录会导致出现问题(因为我认为关闭标记在最后输入的次数不足)。但是我很难理解它。 如果无法通过这种方式完成操作,是否有更简单的方法可以执行?我正在使用Flask,但是对模板的经验不足,所以也许我缺少了一些东

  • 在阅读的API时,我错过了很多函数。首先,它建议使用for循环从stream转到。而且我忽略了一个事实,即不是。 如何在Java8中从生成?

  • 1. 前言 目录是文章内容的整体索引,是文章结构的最直观表现形式。 Markdown 为生成目录提供了快捷方式,大大降低了文章目录的编排复杂度。 环境说明: 考虑到 Markdown 工具之间的不兼容,有的内容直接从页面复制粘贴到本地不会正常显示,大家学习时自己动手写是肯定没问题的。本节所有实例代码及演示效果均使用 Typora 工具完成。 「TOC」是 Markdown 扩展语法,Typora

  • 我想用外部资源(jpg、css)从html创建pdf。 这是用于生成pdf File对象的代码,带有Flie Saucer和itext: 不幸的是,所有与https链接的资源都被忽略,而超文本传输协议资源运行良好。 编辑: 我扩展了iTextureAgent以拦截https调用资源,但出现了以下错误: 太阳安全供应商。证书路径。SunCertPathBuilderException:无法找到请求目

  • 请修改配置文件caches\configs\system.php中 'html_root' => '/html',//生成静态文件路径 为 'html_root' => '',//生成静态文件路径