使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM