Itext change bookmarks zoom level to inherit zoom

2019-04-16 02:27发布

问题:

Using the iText5 PDF library, I am able to read bookmarks exist in PDF. Now I want to change the zoom level of bookmarks (Inherit zoom) in existing PDF using iText. Is it possible using the iText PDF library, and how?

I have attached a screenshot.

This is the code I am using to change the bookmark zoom level (as per @lowagie comment):

public void changeList(List<HashMap<String, Object>> list) {
        for (HashMap<String, Object> entry : list) {
            for (String key : entry.keySet()) {
                System.out.println(key);

                if ("Kids".equals(key)) {
                    Object o = entry.get(key);
                    changeList((List<HashMap<String, Object>>) o);
                } else if ("Page".equals(key)) {
                    String dest = (String) entry.get(key);
                    entry.put("Page", dest.replaceAll("Fit", "XYZ 30 100 0"));
                }
            }
        }
    }

Bookmark Tree Structure :

回答1:

Please take a look at my answer to the following question: Set inherit Zoom(action property) to bookmark in the pdf file

In that answer, I read bookmarks using the SimpleBookmark object. That's probably the same way you are reading bookmarks. The result is a List of HashMap objects that represents an outline tree. I use a recursive method to find all the "Page" entries.

These page entries contain a destination, for instance Fit, FitH, XYZ,... You need to change all these references into XYZ references of which you set the zoom factor to 0. A zoom factor 0 is the equivalent of 'Inherit Zoom'.

In my answer to Set inherit Zoom(action property) to bookmark in the pdf file I had this code:

public void changeList(List<HashMap<String, Object>> list) {
    for (HashMap<String, Object> entry : list) {
        for (String key : entry.keySet()) {
            if ("Kids".equals(key)) {
                Object o = entry.get(key);
                changeList((List<HashMap<String, Object>>)o);
            }
            else if ("Page".equals(key)) {
                String dest = (String)entry.get(key);
                entry.put("Page", dest.replaceAll("Fit", "FitV 60"));
            }
        }
    }
}

It's obvious that you can replace any existing "Page" action by a completely new action. For instance:

entry.put("Page", "XYZ 30 100 0");

Now you'll jump to the coordinate 30 100 on the page with an inherited zoom factor. If you want to zoom in on another part, for instance a location that corresponds more or less with the original location, you need to examine the coordinates that followed the FitR in your original PDF. There are 4: the lower-left x, lower-left y, upper-right x and upper-right y coordinate. You could parse the string with the original destination for those values and reuse two of these coordinates as your X and Y values in the XYZ destination.

The X Y coordinate passed with the XYZ destination is the coordinate of the top-left corner. For instance, if you have FitR -3 234 486 627, then you zoom in on a rectangle with coordinates llx = -3, lly = 234, urx = 486 and ury = 627 (ll refers to lower-left; ur refers to upper-right). The top left corner is llx,ury or in your case x = -3 and y = 627. In short: in this case, you'd need "XYZ -3 627 0".



回答2:

Unfortunately I can't help you out if you must do it with iText. But if you just want to change the zoom level of your bookmarks, you can also use the PDF Clown library, which I personally like a lot (especially when it comes to API design compared with iText).

Check out this small Java application I wrote, that does exactly what you want. The Wizard class gives you an overview on how to the change the zoom level. Basically you can achieve this with:

private void modifyBookmarks(Bookmarks bookmarks) {
    for (Bookmark bm : bookmarks) {
        if (!bm.getBookmarks().isEmpty()) {
            modifyBookmarks(bm.getBookmarks());
        }

        if (bm.getTarget() instanceof GoToDestination<?>) {
            Destination dest = ((GoToDestination<?>) 
                    bm.getTarget()).getDestination();
            dest.setMode(ModeEnum.XYZ);
            dest.setZoom(0.0);
        }
    }
}


标签: java itext