我想使用iText7
更改轮廓的缩放级别。请注意,与iText 5中的处理方式相比,这可能已经改变。
通过反复试验,我得出了以下代码:
List<PdfOutline> outlines = pdfDoc.getOutlines(true).getAllChildren();
for (int i = 0; i < outlines.size(); i++) {
PdfOutline outline = outlines.get(i);
PdfDictionary content = outline.getContent();
PdfDictionary pdfDictionary = (PdfDictionary) content.get(PdfName.A);
if (pdfDictionary != null) {
PdfArray arr = (PdfArray) pdfDictionary.get(PdfName.D);
if (arr.size() == 5) { // for XYZ zoom type
PdfName xyz = (PdfName) arr.get(1);
arr.set(3, new PdfNumber(2_000));
arr.set(4, new PdfNumber(2_000));
}
}
编辑
问题在于上面的代码似乎不起作用,因为保存了生成的pdf,但是缩放级别没有变化。
更新 我想出了一个不同的解决方案(受different question at SO的启发):
PdfNameTree destsTree = document.getCatalog().getNameTree(PdfName.Dests);
PdfOutline outline = document.getOutlines(false);
if (outline != null) {
walkOutlines(outline, destsTree.getNames(), document);
}
private static void walkOutlines(PdfOutline outline, Map<String, PdfObject> names,
PdfDocument document) {
if (outline.getDestination() != null) {
int pageNumber = document.getPageNumber(
(PdfDictionary) outline.getDestination().getDestinationPage(names));
float height = document.getPage(pageNumber).getPageSize().getHeight();
outline.setOpen(false);
outline.addDestination(PdfExplicitRemoteGoToDestination.createXYZ(
pageNumber, 0F, height, ZOOM_LEVEL));
}
for (PdfOutline child : outline.getAllChildren()) {
walkOutlines(child, names, document);
}
}
答案 0 :(得分:0)
是这样吗?
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));
pdfDoc.getCatalog().setOpenAction(PdfExplicitDestination.createXYZ(pdfDoc.getPage(1), 0, pdfDoc.getPage(1).getPageSize().getHeight(), 0.75f));
pdfDoc.close();
答案 1 :(得分:0)
问题在于上面的代码似乎不起作用,因为保存了生成的pdf,但是缩放级别没有变化。
尝试原始代码我无法确认,标题页轮廓的缩放级别和y坐标(为什么还要更改?)也已更改!
其他轮廓没有更改,原因有两个:
您的原始代码假定大纲中有一个 GoTo Action ( A ),其中包装了一个明确的 XYZ目标( D 映射到5个元素的数组)。
这仅在您的文档适用于标题页的情况下,所有其他轮廓立即包含一个非显式的名称, Destination ( Dest 映射到名称)
您的备用代码确实可以解决问题
在Adobe Reader中,结果似乎可以按预期工作,但仔细观察后发现存在问题:
PdfExplicitRemoteGoToDestination
开头。要解决上述问题,请更改
outline.addDestination(PdfExplicitRemoteGoToDestination.createXYZ(
pageNumber, 0F, height, ZOOM_LEVEL));
到
outline.getContent().remove(PdfName.A);
outline.addDestination(PdfExplicitDestination.createXYZ(
document.GetPage(pageNumber), 0F, height, ZOOM_LEVEL));
严格来说,您的代码可以得到进一步的改进。
PageSize
,但是对于可见页面区域,您应该使用CropBox
。0F, height
作为目标视图左上角的坐标。假设坐标系的原点位于页面的左下角,则应使用box.getLeft(), box.getTop()
而不是box
作为相关页面的裁剪框。但是,在示例文档中,媒体框和裁切框重合,并且原点确实位于左下角。因此,对于该文档,您不需要进行改进。