如何使用itext创建多页TOC?
我需要在PDF中创建TOC。它可以是一页或多页,具体取决于PDF中的页数。我了解到可以使用如何使用itext创建多页TOC?,itext,Itext,我需要在PDF中创建TOC。它可以是一页或多页,具体取决于PDF中的页数。我了解到可以使用PdfStamper,pdprotion,pdfarnotation来实现这一点 我目前正在合并多个文档,并为JAVA中的所有文档创建书签和TOC。我已经摆脱了书签,但被困在多页目录 另外,请解释代码的这一行-link=newpdfantation(copy,36,ct.getYLine(),559,y,action);。。。我所理解的是,在单击链接(,36,ct.getYLine(),559,y,)之后,
PdfStamper
,pdprotion
,pdfarnotation
来实现这一点
我目前正在合并多个文档,并为JAVA中的所有文档创建书签和TOC。我已经摆脱了书签,但被困在多页目录
另外,请解释代码的这一行-link=newpdfantation(copy,36,ct.getYLine(),559,y,action);。。。我所理解的是,在单击链接(,36,ct.getYLine(),559,y,)之后,您正在传递页面上矩形的尺寸。。因此,如果页面大小与我们的字母肖像不同,我将面临一个问题,即在点击链接时无法纠正页面的位置
下面是片段-
int tocPages = 1;
Document tocDocument = new Document();
String tocFilename ="toc-filename";
Phrase tocPhrase =
new Phrase("Table of Contents", new Font(Font.FontFamily.HELVETICA, 20, Font.BOLD, BaseColor.BLACK));
PdfWriter writer = PdfWriter.getInstance(tocDocument, new FileOutputStream(tocFilename));
tocDocument.open();
tocDocument.add(new Paragraph(tocPhrase));
PdfReader reader = new PdfReader(tocFilename);
page = copy.getImportedPage(reader, tocPages);
stamp = copy.createPageStamp(page);
float y = 770;
ColumnText ct = new ColumnText(stamp.getOverContent());
ct.setSimpleColumn(36, 36, 559, y);
for (Map.Entry<Integer, String> entry : toc.entrySet()) {
if (y <= 20) {
copy.addPage(page);
copy.newPage(); //(tried with writer.newPage() and tocDocument.newPage(), not working )
page = copy.getImportedPage(reader, ++tocPages);
}
p = new Paragraph(entry.getValue());
p.add(new Chunk(new DottedLineSeparator()));
p.add(String.valueOf(entry.getKey() + 1));
ct.addElement(p);
ct.go();
action = PdfAction.gotoLocalPage("p" + entry.getKey(), false);
link = new PdfAnnotation(copy, 36, ct.getYLine(), 559, y, action);
stamp.addAnnotation(link);
y = ct.getYLine();
}
ct.go();
stamp.alterContents();
copy.addPage(page);
tocDocument.close();
reader.close();
int-tocPages=1;
Document tocDocument=新文档();
字符串tocFilename=“toc filename”;
短语对短语=
新短语(“目录”,新字体(Font.FontFamily.HELVETICA,20,Font.BOLD,BASECLOR.BLACK));
PdfWriter writer=PdfWriter.getInstance(tocDocument,新文件输出流(tocFilename));
tocDocument.open();
添加(新的段落(短语));
PdfReader reader=新的PdfReader(文件名);
page=copy.getImportedPage(读卡器,tocPages);
stamp=copy.createPageStamp(第页);
浮动y=770;
ColumnText ct=新的ColumnText(stamp.getOverContent());
ct.setSimpleColumn(36,36559,y);
for(Map.Entry:toc.entrySet()){
如果(y您已经修改了您的问题,使其成为关于我对的回答中的这一片段的问题
我已经粘贴了完整的片段,因为这一行不能断章取义地解释
在代码段中,我们使用pdfantation
类创建了一个链接注释。链接注释是页面上某个地方的一个区域,单击该区域时会触发一个操作
在这种情况下会触发哪个动作?这就是动作
对象的内容,在这种情况下,它会跳转到由指定目的地定义的本地页面。这与HTML非常相似,HTML中有
创建PdfAnotation
时,始终需要一个PdfWriter
实例。在这种情况下,我们使用名为copy
的PdfCopy
实例合并文档。随着PdfCopy
扩展PdfWriter
,我们可以将copy
实例作为参数传递
最后,我们定义了可点击区域。这始终是一个矩形,使用两个坐标定义:左下角的坐标和右上角的坐标
在上面的代码片段中,我们使用ColumnText
添加段落ColumnText
允许您在添加内容后获取有关当前y
位置的信息。例如,当我们这样做时:
ct.addElement(p);
ct.go();
我们可以这样做以获得当前的Y坐标:
float y = ct.getYLine();
在我们的代码片段中,我们跟踪前面的y
值(添加p
之前的y位置),并使用ct.getYLine()
的当前值来获取当前的y
位置
这样,我可以像这样定义左下角的坐标:
float llx = 36;
float lly = ct.getYLine();
float urx = 559;
float ury = y;
右上角的坐标如下:
float llx = 36;
float lly = ct.getYLine();
float urx = 559;
float ury = y;
这些是在构造链接注释时可以看到的值
我对x
值进行了硬编码。它们基于这样一个事实,即我正在创建一个具有A4大小页面和半英寸页边距的文档。a-4页面的宽度为595个用户单位。左侧,我有36个用户单位的页边距;右侧,我还有36个用户单位的页边距,我必须从页面宽度中减去:595-36=559
如果您有一个格式为字母的页面,则需要调整这些值。但是:最好根据现有页面的MediaBox/CropBox的实际值来计算这些值。这样,当您意外遇到具有不同页面大小的文档时,您的代码会继续工作
在我对这个问题的回答中,你可以阅读更多关于MediaBox和CropBox的信息:有一个例子回答了重复的问题。你还应该解释更多关于这个过程的信息。你需要创建一个大纲树(也称书签)吗也是。您参考了PdfStamper
,但不清楚如果您是从头开始创建文档,为什么需要它。请澄清您是否想要一个准确的答案。让我重复一下:如果您希望得到这个问题的答案,请说明您已经在做什么:您是从头开始创建文档吗?您是否正在尝试创建TOC对于现有文档(如果有,是否有书签)?您是在合并文档吗?您是在用Java还是C#编写代码?请将您的评论表述为一个真实的问题,提供足够的上下文,以便人们知道您的问题是关于什么的。您的问题不是独立的。我在回答中为其他人提供了理解问题所需的上下文。@Kapil如果您是从po开始的话,可能会这样问一个问题,解释你想做什么。你想创建一个TOC,但基于什么?这在你的问题中是绝对不清楚的。坏问题=坏答案。有什么区别?当有多个页面时,什么不起作用?