批量重命名PDF文件中的PDF书签/轮廓

时间:2014-04-07 22:40:58

标签: java pdf itext

我需要做与Stack Overflow问题几乎相同的事情:Renaming named destinations in PDF files但是我的PDF充满了书签,而不是包含命名目的地的文本本身。当我运行Bruno's code时,我的名字对象是空的 - 尽管(正确读入)PDF中有200多个书签 - 而Java会抛出NullPointerException。有关为什么的任何想法?

Exception in thread "main" java.lang.NullPointerException
at annotations.RenameDestinations.manipulatePdf(RenameDestinations.java:41)
at annotations.RenameDestinations.main(RenameDestinations.java:33)

免责声明:我是iText的新手。

1 个答案:

答案 0 :(得分:0)

我得到了这个工作。如果其他人需要在许多PDF文件中重命名PDF书签(批量书签重命名),您可以避免使用下面的脚本支付Autobookmark。我是第一个承认它可以改进的人,可能是极大的(尤其是通过重构),但它确实有效!我使用的是Windows 7 64位和带有UTF-8编码字形的文件。它假定您使用" in"创建一个c:\ in和c:\ out。包含原件的文件夹和" out"包含重命名的书签版本。该计划不会改变您原来的PDF格式。观察控制台输出以查看itext无法处理的任何PDF。就我而言,我有一些零字节的PDF,安全的PDF,甚至已经损坏的PDF也无法处理。

package annotations;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.SimpleBookmark;

 public class RenameDestinations {
public static void main(String[] args) throws IOException, DocumentException {
    String in = "c:/in"; // this must be a directory
    String out = "c:/out"; // this must be a directory

    // Parent Bookmarks
    String find1 = "_\n    <"; // e.g., Something_ <Title ...> child bookmark</Title>
    String repl1 = "X\n    <"; // e.g., SomethingX <Title ...> child bookmark</Title>

    // No children
    String find2 = "_</Title>"; // e.g., <Title>Something_</Title>
    String repl2 = "X</Title>"; // e.g., <Title>SomethingX</Title>

    // read a directory of files
    // http://stackoverflow.com/questions/13918876/java-open-directory
    File directory = new File(in);
    File[] contents = directory.listFiles();
    for (File f : contents) {
        // get extension
        String filename = f.getName();
        String extension = filename.substring(filename.lastIndexOf(".") + 1, filename.length()).toLowerCase();

        // leave if not a PDF
        if (!extension.equals("pdf")) {
            System.out.println(filename);
            System.out.println("   NOT PDF, SKIPPED");
            continue;
        }

        // inform user
        System.out.println(filename);

        String src = f.getAbsolutePath();
        String dst = out + "/" + f.getName();
        String srcx = in + "/bookmarks.xml"; // save this book's bookmarks

        // read and create an xml file of the bookmarks
        PdfReader reader = new PdfReader(src);
        List<HashMap<String, Object>> list = SimpleBookmark.getBookmark(reader);

        // Create a stamper
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dst));

        //leave if no bookmarks
        if (list == null) {
            System.out.println(filename);
            System.out.println("   NO BOOKMARKS, THUS NO CHANGES MADE");
            stamper.setOutlines(list);
        }else {
            // create bookmarks xml
            SimpleBookmark.exportToXML(list, new FileOutputStream(srcx), "UTF-8", true);

            // find and replace bookmark titles
            // http://stackoverflow.com/questions/3935791/find-and-replace-words-lines-in-a-file
            Path path = Paths.get(srcx);
            Charset charset = StandardCharsets.UTF_8;
            // store
            String content = new String(Files.readAllBytes(path), charset);
            // replace
            content = content.replaceAll(find1, repl1);
            content = content.replaceAll(find2, repl2);
            // write
            Files.write(path, content.getBytes(charset));

            // read
            // https://code.google.com/p/pdf-pub-tools/source/browse/trunk/pdf-pub-tools/src/java/net/mitnet/tools/pdf/book/pdf/util/PdfBookmarkBuilder.java?spec=svn133&r=133
            List<HashMap<String, Object>> bookmarks = SimpleBookmark.importFromXML(new FileReader(srcx));
            stamper.setOutlines(bookmarks);

            //inform user
            System.out.println("   BOOKMARKS RENAMED!");
        }

        // Close the stamper and reader
        stamper.close();
        reader.close();

    }
    //inform user
    System.out.println("DONE!");
}

}