【问题标题】:How to reorder the pages of a PDF file?如何重新排序 PDF 文件的页面?
【发布时间】:2015-06-18 09:14:34
【问题描述】:

我最后正在生成目录,我想在开始时移动目录。 假设我的 PDF 中有 16 页,并且 TOC 从第 13 页开始,到第 15 页结束。 我想将目录移动到第二页,以便第一页保持第 1 页,最后一页保持第 16 页。 这段代码没有给我我想要的:

public void changePagesOrder()  {
    try {
         PdfReader sourcePDFReader = new PdfReader(RESULT1);    
         int n = sourcePDFReader.getNumberOfPages();
         System.out.println("no of pages in pdf files..."+n);
         int totalNoPages=n;
         int tocStartsPage=13;

         sourcePDFReader.selectPages(String.format("%d-%d, 2-%d", tocStartsPage, totalNoPages-1, tocStartsPage -2));
         PdfStamper stamper = new PdfStamper(sourcePDFReader, new FileOutputStream(RESULT2));
         stamper.close();   

         System.out.println("pdf changes are done.....");
    }
    catch(Exception ex) {
    }
}

请提出一些解决方案。

【问题讨论】:

    标签: java pdf itext


    【解决方案1】:

    你的公式是错误的。你有:

    sourcePDFReader.selectPages(String.format("%d-%d, 2-%d", tocStartsPage, totalNoPages-1, tocStartsPage -2);
    

    但这会将您的 TOC 放在第 1 页。根据您的描述,这不是您想要的。

    你想要这样的东西:

    PdfReader reader = new PdfReader(baos.toByteArray());
    int startToc = 13;
    int n = reader.getNumberOfPages();
    reader.selectPages(String.format("1,%s-%s, 2-%s, %s", startToc, n-1, startToc - 1, n));
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.close();
    

    此代码已使用 ReorderPage 示例在 16 页的 PDF 上进行了测试,其中文本 Page 1Page 2、...、Page 16 作为内容。结果是以下 PDF: (reordered.pdf)[http://itextpdf.com/sites/default/files/reordered.pdf]

    页面现在按以下顺序排列:第 1 页、第 13 页、第 14 页、第 15 页、第 2 页、第 3 页、第 4 页、第 5 页、第 6 页、第 7 页、第 8 页、第 9 页、第 10 页、第 11 页、第 12 页、第 16 页。这是您在问题中描述的顺序。

    更新:

    在评论中,您问String.format() 在这种情况下是如何工作的。

    让我们先看看我们想要实现什么。我们按以下顺序排列页面:

    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
    

    我们想像这样重新排列它们:

    1, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16
    

    这意味着我们需要这种模式:

    1, 13-15, 2-12, 16
    

    这是一个硬编码模式,其中两个变量很重要:

    • TOC 开头:第 13 页 (startToc)
    • 最后一页:16 (n)

    从这些变量中,我们又推导出两个变量:

    • 目录的最后一页。这是最后一页减一,即 16 - 1 = 15 (n - 1)
    • TOC 之前的最后一页:13 - 1 = 12 (startToc - 1)

    我们现在可以像这样重写模式:

    1, startToc-(n - 1), 2-(startToc - 1), n
    

    我们需要将其设为String,这就是我们使用String.format()的原因:

    String.format("1,%s-%s, 2-%s, %s", startToc, n-1, startToc - 1, n)
    

    %s 的第一次出现被String 之后的第一个参数替换,%s 的第二次出现被String 之后的第二个参数替换,以此类推...

    如果startToc = 13n = 16,则结果为:

    1, 13-15, 2-12, 16
    

    【讨论】:

    • 它工作正常。非常感谢。我只想说,从过去两个月开始,我一直在研究 itext,我发现它非常有趣。我想了解字符串格式化程序在这种情况下如何工作的一个小帮助?再次感谢。
    【解决方案2】:

    您可以选择PdfReader阅读的页面:

    PdfReader sourcePDFReader = new PdfReader(RESULT1);
    reader.selectPages("1-13");
    

    然后您可以使用 PdfStamper 或 PdfCopy 来按顺序组装。 请参考:

    Itext Documentation, Related question

    编辑:这是我用来将pdf列表放在一起的一段代码,也许对你有帮助。 (您可以阅读第 15-16 页,保存为 pdf,然后重复第 1-13 页。然后合并两个生成的 pdf)

    private byte[] combinePdf(List<byte[]> archivos) throws DocumentException,
            IOException {
        ByteArrayOutputStream osPdf = new ByteArrayOutputStream();
        com.itextpdf.text.Document document = new com.itextpdf.text.Document();
        PdfWriter writer = PdfWriter.getInstance(document, osPdf);
        document.open();
        PdfContentByte cb = writer.getDirectContent();
    
        for (byte[] in : archivos) {
            PdfReader reader = new PdfReader(in);
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                document.newPage();
                PdfImportedPage page = writer.getImportedPage(reader, i);
                cb.addTemplate(page, 0, 0);
            }
        }
        osPdf.flush();
        document.close();
    
        return osPdf.toByteArray();
    }
    

    编辑 2: 正如 Bruno 所说,这是一个糟糕的解决方案,因为使用 document/pdfWritter 组合会丢失所有 pdf 链接。

    【讨论】:

    • 这是一个非常糟糕的答案,因为使用 Document/PdfWriter 的组合会丢弃您 PDF 中的所有链接。
    • 我从来没有注意到,因为在我的解决方案中我不使用链接,但你是对的。我会编辑答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 2013-01-05
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多