zoukankan      html  css  js  c++  java
  • 使用iText快速更新书签

    一.介绍  

    pdfbox基于Apache协议,商用无需开放源代码。

    iText基于APGL协议,打包和修改需发布源码,除非花钱买断。

    二.用途

    下载的电子书,有的书签是FitHeight,也就是缩放后整个高度都显示出来,页面很小了。

    我需要改成继承,也就是XYZ,x是left,y是height,z是zoom,继承的意思是根据当前pdf的缩放比例。

    而且有的pdf书没有目录,大部分都是扫描版,需要目录找资料,这年代北漂南漂基本一年一般家,那么多书来回累死。

    目录的话自己加太麻烦,从京东,亚马迅,当当上找目录,自动生成带跳转的目录。

    三.pdfBox

    结论:有Bug,或者是我不会用。

     public static void main(String[] args) throws Exception
        {
    
            String filename="E:\PDF\Go\Go语言编程.pdf";
            Catalog catalog=new Catalog();
            catalog.OpenPdf(filename);
            catalog.AdjustCatalog();
        }
        //set scale to inherit
        public void AdjustCatalog() throws Exception
        {
            //获取PDDocumentCatalog文档目录对象
            PDDocumentCatalog catalog=document.getDocumentCatalog();
            //获取PDDocumentOutline文档纲要对象
            PDDocumentOutline outline=catalog.getDocumentOutline();
            for (PDOutlineItem item:outline.children())
            {
                System.out.println(item.getTitle()+item.getDestination());
                AdjustCatalogRecurse(item);
            }
        }
        public void AdjustCatalogRecurse(PDOutlineItem item) throws Exception
        {
    //        PDPageXYZDestination xyzDestination=new PDPageXYZDestination();
            System.out.println(item.getDestination()==null?"null":item.getDestination().getClass());
            System.out.println(item.getTitle());
    //        UpdatePageDestination(item.getDestination(),xyzDestination);
    //        item.setDestination(xyzDestination);
            for (PDOutlineItem item_child:item.children())
            {
                AdjustCatalogRecurse(item_child);
            }
        }

    System.out.println(item.getDestination()==null?"null":item.getDestination().getClass());

    getDestination()是获取书签的页码,缩放,页面位置等信息,但是我测试了几本,有的好用,有的全部是null,有的一半是null,真晕了。

    左边是用Xchange viewer打开,跳转都没问题,右边是输出的内容,全都是null

    四.iText

    结论:真难用,更新操作别扭。

    PdfWriter只能新建用,更新的时候有保存书签的PdfOutline不给用,只能用一堆

    https://stackoverflow.com/questions/46716567/get-the-page-number-from-document-outline-bookmarks

    一个pdfWriter只能写不能读,还要加一个reader拷贝到writer,和我理解的输入输出有点不一样。

    1.更新操作

    有些pdf的书签设置缩放等级是适应高度,每次看完几页一点书签又变成小图了。

    下面是更新操作,我把其他全部的缩放等级都改成XYZ,xyz是继承的,书签的缩放等级和你当前页面的一样,你的页面改成多大就多大,

    其他的不动。

        public void editBookmarks(String src, String dest) throws DocumentException, IOException {
            PdfReader reader = new PdfReader(src);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
            List<HashMap<String, Object>> list = SimpleBookmark.getBookmark(reader);
            changeList(list);
            stamper.setOutlines(list);
            stamper.close();
            reader.close();
        }
    
        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("\b(Fit|FitV|FITB|FITBH|FITBV|FITH|FITR)\b", "XYZ"));
                    }
                }
            }
        }

    二.添加书签

    三点说明

    1.目录的页码是书上写的页码,pdf中页码是实际的页码,包括目录和前言,所以针对每个pdf都需要自己调整偏移

    2.父目录处理目前没有考虑中文的情况,比如第一章,第十六章,过段时间抽空加上。

    3.目录上可能多个书签同一页,电脑因为缩放问题,会有点挤,如果强迫症就自己调吧,比如下面的21.4书签,21.4.3亮了,因为他们是同一页。

    下面是spring攻略的pdf,测试过已经加好书签了,太详细的话做不到也没时间。

     public void createBookmarks(List<BookMark> booksmarks, String src, String dest) throws Exception {
            Document document = new Document();
            reader=new PdfReader(src);
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(dest));
            document.open();
    
            PdfOutline root = copy.getRootOutline();
    
            copy.addDocument(reader);
            PdfDestination destination = new PdfDestination(
                    PdfDestination.XYZ, -1, -1, 0);
    
            PdfAction action;
            copy.freeReader(reader);
            for(BookMark bookMark :booksmarks)
            {
                 action = PdfAction.gotoLocalPage(bookMark.getNum(), destination, copy);
                 new PdfOutline(root, action, bookMark.getTitle(), false);
            }
            copy.flush();
            copy.close();
            document.close();
    
        }

     五.源码

    https://github.com/zwxbest/Demo/tree/master/itextDemo

  • 相关阅读:
    java-继承的注意事项
    java-代码块-局部代码块、构造代码块、静态代码块
    java-源文件中可以有多个类,但是最多只能有一个public修饰
    java-权限修饰符的区别
    APP测试-adb简介
    APP测试-Android模拟器
    APP测试-SDK环境 for Windows
    自动化测试-流程
    接口测试-接口请求关联
    接口测试-moco+excel+requests框架
  • 原文地址:https://www.cnblogs.com/ptqueen/p/8490037.html
Copyright © 2011-2022 走看看