我需要在PDF中创建一个页面内容的页面。我将用PDF创建阅读书签。
使用iText:
tmp = SimpleBookmark.getBookmark (reader);
使用此PDF进行测试:
返回此MAP:
[{Action = GoTo, Named = __ WKANCHOR_2, Title = Secretariat Teste0}, {Action = GoTo, Named = __ WKANCHOR_4, Title = Secretariat TestBook1}, {Action = GoTo, Named = __ WKANCHOR_6, Title = Secretariat Test2}, {Action = GoTo , Named = __ WKANCHOR_8 ...
没有页码。
如何显示带有标题和页码的表格内容?
我想表明这一点:
答案 0 :(得分:3)
请阅读此问题的答案:Java: Reading PDF bookmark names with itext
它解释了如何使用SimpleBookmark
方法获取大纲树的标题(这是"书签"在PDF规范中调用的方式)。
public void inspectPdf(String filename) throws IOException, DocumentException {
PdfReader reader = new PdfReader(filename);
List<HashMap<String,Object>> bookmarks = SimpleBookmark.getBookmark(reader);
for (int i = 0; i < bookmarks.size(); i++){
showTitle(bookmarks.get(i));
}
reader.close();
}
public void showTitle(HashMap<String, Object> bm) {
System.out.println((String)bm.get("Title"));
List<HashMap<String,Object>> kids = (List<HashMap<String,Object>>)bm.get("Kids");
if (kids != null) {
for (int i = 0; i < kids.size(); i++) {
showTitle(kids.get(i));
}
}
}
然后阅读这个问题的答案:Set inherit Zoom(action property) to bookmark in the pdf file
您会发现HashMap<String, Object>
不包含带有密钥"Title"
的条目,但它也可以包含密钥为"Page"
的条目。当书签指向页面时就是这种情况。该值将是显式目标。它将包含页码,Fit
,FitH
,FitB
,XYZ
等值,后跟一些标记位置的参数。
如果您查看CreateOutlineTree示例,您会发现您还可以将书签解压缩为XML文件:
public void createXml(String src, String dest) throws IOException {
PdfReader reader = new PdfReader(src);
List<HashMap<String, Object>> list = SimpleBookmark.getBookmark(reader);
SimpleBookmark.exportToXML(list,
new FileOutputStream(dest), "ISO8859-1", true);
reader.close();
}
这是我写的关于iText的书的截图,它会向您显示书签条目中您可以期待的键:
从该表中可以看出,链接也可以表示为命名目标。在这种情况下,您不会获得页码,而是获得名称。要获取页码,您需要提取命名目标列表。此列表将为您提供与指定目标对应的显式目标。
书中也解释了这一点,以及official documentation。
获得标题和页码后(使用基于上述指针编写的代码检索),您可以使用PdfStamper
和insertPage()
方法将页面插入PDF文件。您可以使用ColumnText
将TOC放在这些页面上,也可以为TOC创建单独的PDF并将其与原始页面合并。请参阅How to add a cover/PDF in a existing iText document以了解有关这两种技术的更多信息。
您也将受益于此示例:Create Index File(TOC) for merged pdf using itext library in java
对于标题和页码之间的虚线,使用分隔符完成,更具体地说是虚线分隔符。您应首先阅读此问题:iTextSharp - Is it possible to set a different alignment in the same cell for text
然后阅读此问题:How to Generate Table-of-Figures Dot Leaders in a PdfPCell for the Last Line of Wrapped Text(或此问题It is possible with itext 5 which at the end of a paragraph justified the remaining space is filled with scripts?)
请注意,您的问题实际上是偏离主题的。它被称为&#34;家庭作业&#34;题。它邀请人们在你的地方做你的工作。既然你拥有了所需的所有元素,那么你应该能够自己完成这项工作。如果你没有成功,你应该写一个关于Stack Overflow问题的主题。这是一个问题,您可以在其中展示您尝试过的内容并解释您遇到的技术问题。
<强>更新强>
您与以下大纲树共享了一个文档:
如您所见,书签是使用命名目的地定义的,例如/__WKANCHOR_2
,/__WKANCHOR_4
等。从/
字符可以看出,名称存储为PDF名称对象(PDF 1.1),而不是PDF字符串对象(自1.2起)。最新的PDF标准建议使用PDF字符串对象而不是PDF名称对象,您可能需要请求PDF生成软件的供应商更新软件以满足最新PDF标准的建议。
尽管如此,我们可以轻松获得与这些指定目的地相对应的显式目的地。它们存储在根词典的/Dests
条目中:
当您查看目的地的方式时,您会看到另一个应报告给wkhtmltopdf的问题。让我们来看看ISO标准告诉我们的目标语法:
页码的概念在PDF中并不存在。使用页面字典描述页面,页面编号从页面树中页面的位置派生。页面树中遇到的第一个页面是第1页,遇到的第二个页面是第2页,依此类推。
在您的示例中,解释目标的定义如下:[9/XYZ 30.2400000 524.179999 0]
,[9/XYZ 30.2400000 231.379999 0]
,依此类推。
这是错误的。 ISO标准规定数组中的第一个值需要是间接引用。间接引用的格式为9 0 R
,而不是9
。我查看了文档的结构,我看到wkhtmltopdf使用页码 - 1而不是间接引用。如果我查看/__WKANCHOR_2
,则会引用[0/XYZ 30.240000 781.459999 0]
并且0
应该指向第1页。由于Adobe Reader容忍糟糕的软件,因此这适用于Adobe Reader,但作为文件如果违反ISO-32000,iText不知道如何处理这些误导性目的地,至少,便利班SimpleNamedDEstination
不知道如何处理它。
幸运的是,iText是一个非常通用的库,可以让您深入了解PDF。在这种情况下,我们只需要更深层次。我们可以使用以下方法代替SimpleNamedDestination.getNamedDestination(reader, true)
:
HashMap<String, PdfObject> names = reader.getNamedDestinationFromNames();
for (Map.Entry<String, PdfObject> entry: names.entrySet()) {
System.out.print(entry.getKey());
System.out.print(": p");
PdfArray arr = (PdfArray)entry.getValue();
System.out.println(arr.getAsNumber(0).intValue() + 1);
}
reader.close();
此方法的输出为:
__WKANCHOR_w: p7
__WKANCHOR_y: p7
__WKANCHOR_2: p1
__WKANCHOR_4: p1
__WKANCHOR_16: p9
__WKANCHOR_14: p8
__WKANCHOR_18: p9
__WKANCHOR_1s: p13
__WKANCHOR_a: p2
__WKANCHOR_1q: p13
__WKANCHOR_1o: p12
__WKANCHOR_12: p8
__WKANCHOR_1m: p12
__WKANCHOR_e: p3
__WKANCHOR_10: p7
__WKANCHOR_1k: p12
__WKANCHOR_c: p3
__WKANCHOR_1i: p11
__WKANCHOR_i: p4
__WKANCHOR_8: p2
__WKANCHOR_g: p3
__WKANCHOR_1g: p11
__WKANCHOR_6: p1
__WKANCHOR_1e: p10
__WKANCHOR_m: p5
__WKANCHOR_1c: p10
__WKANCHOR_k: p4
__WKANCHOR_q: p5
__WKANCHOR_1a: p9
__WKANCHOR_o: p5
__WKANCHOR_u: p6
__WKANCHOR_s: p6
如果我们检查__WKANCHOR_2
,我们会看到它正确指向第1页。我检查了大纲中的最后一个链接,它指向名为__WKANCHOR_1s
的命名目的地,确实:应该链接至第13页。
你的问题是一个垃圾垃圾进出的明显例子&#34;问题。您的工具生成的PDF违反了ISO的ISO标准,因此您将失去足够的时间来弄清楚哪些错误。但更糟糕的是:你让我因为别人的过错而浪费时间。