使用iText
,我们可以轻松更改链接的缩放级别。甚至有一块code为GoTo
目的地类型执行此操作。如需便利,请在下面找到。
PdfReader reader = new PdfReader(src);
PdfDictionary page = reader.getPageN(11);
PdfArray annots = page.getAsArray(PdfName.ANNOTS);
for (int i = 0; i < annots.size(); i++) {
PdfDictionary annotation = annots.getAsDict(i);
if (PdfName.LINK.equals(annotation.getAsName(PdfName.SUBTYPE))) {
PdfArray d = annotation.getAsArray(PdfName.DEST);
if (d != null && d.size() == 5 && PdfName.XYZ.equals(d.getAsName(1)))
d.set(4, new PdfNumber(0));
}
}
该代码仅处理PDF文件中找到的目标类型之一。我有兴趣在其他类型的目的地中更改缩放(如果有人想知道,它们会在32000-1中列出)。具体来说,我想将每个目的地更改为GoTo
类型并指定我自己的坐标。我希望左坐标与要跳转的页面的页面高度相同。要做到这一点,我显然需要页码。我怎么得到它?
到目前为止我做了什么?
指令PdfArray d = annotation.getAsArray(PdfName.DEST)
给出了一个数组,其第一个(基于0)元素是页面引用,而不是页面编号,因为Bruno Lowagie在他的iText in Action, 2nd edition, p. 202). The array looks like this:
[1931 0 R,/ XYZ,0,677,0中解释]`。我无法找到正确的命令来获取我自己的页码。因此,这篇文章。
答案 0 :(得分:3)
According to this: https://developers.itextpdf.com/fr/node/1750
The first example is an array with two elements 8 0 R and /Fit. The second example is an array with four elements 6 0 R, /XYZ, 0, 806 and 0. You need the first element. It doesn't give you the page number (because there is no such thing as page numbers), but it gives you a reference to the /Page object. Based on that reference, you can deduce the page number by looping over the page tree and comparing the object number of a specific page with the object number in the destination.
And than you can go recursively to extract page number, like this: Extract page number from PDF file
Hope, you find it's helpful. Good luck!
答案 1 :(得分:2)
我希望左坐标与要跳转的页面的页面高度相同。要做到这一点,我显然需要页码。我怎么得到它?
您需要页码的假设是错误的。 PdfReader
实用程序方法主要基于页码工作,是的,但这些方法并不多。因此,如果您对某些低级数据访问没问题,则不需要页码。
以下是您的代码,其中包含用于检索裁剪框(定义左,底,右和首页坐标)的附加代码,一次直接来自目标中的对象引用,一次通过页码。
PdfReader reader = new PdfReader(src);
PdfDictionary page = reader.getPageN(11);
PdfArray annots = page.getAsArray(PdfName.ANNOTS);
for (int i = 0; i < annots.size(); i++) {
PdfDictionary annotation = annots.getAsDict(i);
if (PdfName.LINK.equals(annotation.getAsName(PdfName.SUBTYPE))) {
PdfArray d = annotation.getAsArray(PdfName.DEST);
if (d == null) { // in case the link has not a Dest but instead a GoTo action
PdfDictionary action = annotation.getAsDict(PdfName.A);
if (action != null)
d = action.getAsArray(PdfName.D);
}
if (d != null && d.size() > 0) {
System.out.println("Next destination -");
PdfIndirectReference pageReference = d.getAsIndirectObject(0);
// Work with target dictionary directly
PdfDictionary pageDict = d.getAsDict(0);
PdfArray boxArray = pageDict.getAsArray(PdfName.CROPBOX);
if (boxArray == null) {
boxArray = pageDict.getAsArray(PdfName.MEDIABOX);
}
Rectangle box = PdfReader.getNormalizedRectangle(boxArray);
System.out.printf("* Target page object %s has cropbox %s\n", pageReference, box);
// Work via page number
for (int pageNr = 1; pageNr <= reader.getNumberOfPages(); pageNr++) {
PRIndirectReference pp = reader.getPageOrigRef(pageNr);
if (pp.getGeneration() == pageReference.getGeneration() && pp.getNumber() == pageReference.getNumber()) {
System.out.printf("* Target page %s has cropbox %s\n", pageNr, reader.getCropBox(pageNr));
break;
}
}
}
}
}
(ProcessLink test testDetermineTargetPage
)
顺便说一句,目的地也可以是命名目的地。因此,如果某些PDF的 Dest 值恰好不是数组而是字符串,则只需在 Dests 名称树中查找。< / p>