更改PDF文件中轮廓(书签)的缩放级别 您的原始代码您的备用代码改进您的备用代码

我想使用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);
    }
}
jhfuuu 回答:更改PDF文件中轮廓(书签)的缩放级别 您的原始代码您的备用代码改进您的备用代码

是这样吗?

    PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC),new PdfWriter(DEST));                                                   
    pdfDoc.getCatalog().setOpenAction(PdfExplicitDestination.createXYZ(pdfDoc.getPage(1),pdfDoc.getPage(1).getPageSize().getHeight(),0.75f)); 
    pdfDoc.close();

https://itextpdf.com/en/resources/faq/technical-support/itext-7/how-can-i-set-zoom-level-pdf-using-itext-7

,

您的原始代码

  

问题在于上面的代码似乎不起作用,因为保存了生成的pdf,但是缩放级别没有变化。

尝试原始代码我无法确认,标题页轮廓的缩放级别和y坐标(为什么还要更改?)也已更改!

其他轮廓没有更改,原因有两个:

  • 您的原始代码仅在顶级轮廓上进行迭代(直接目录概述子级),因此仅可以更改顶级轮廓条目。
  • 您的原始代码假定大纲中有一个 GoTo Action A ),其中包装了一个明确的 XYZ目标 D 映射到5个元素的数组)。

    这仅在您的文档适用于标题页的情况下,所有其他轮廓立即包含一个非显式的名称, Destination Dest 映射到名称)

您的备用代码

您的备用代码确实可以解决问题

    它还递归访问顶级大纲的所有祖先,因此可以更改所有大纲条目;和
  • 它使用iText类来识别和评估各种目的地,无论它们是否包装在一个动作中,无论它们是显式的还是命名的,...

在Adobe Reader中,结果似乎可以按预期工作,但仔细观察后发现存在问题:

  • 标题页大纲(这是您仅有的带有 Action 条目的大纲)现在同时具有 和旧的 Action 条目,一个新的目的地条目。严格来说,该规范是禁止的。因此,您应该删除现有的 Action 条目。
  • 创建的目标数组包含目标页(第一个数组条目)作为整数页号。仅在远程转到操作中的目标位置允许。由于您的新目的地显然不是远程的,也不是非行动的,因此这仅是有效的,因为Adobe Reader非常宽松。应该使用页面对象而不是页码,并且不应该使用PdfExplicitRemoteGoToDestination开头。

改进您的备用代码

要解决上述问题,请更改

outline.addDestination(PdfExplicitRemoteGoToDestination.createXYZ(
        pageNumber,0F,height,ZOOM_LEVEL));

outline.getContent().remove(PdfName.A);
outline.addDestination(PdfExplicitDestination.createXYZ(
        document.GetPage(pageNumber),ZOOM_LEVEL));

严格来说,您的代码可以得到进一步的改进。

  • 您使用PageSize,但是对于可见页面区域,您应该使用CropBox
  • 然后使用0F,height作为目标视图左上角的坐标。假设坐标系的原点位于页面的左下角,则应使用box.getLeft(),box.getTop()而不是box作为相关页面的裁剪框。

但是,在示例文档中,媒体框和裁切框重合,并且原点确实位于左下角。因此,对于该文档,您不需要进行改进。

本文链接:https://www.f2er.com/3164281.html

大家都在问