如何重新排序PDF文件的页面?

时间:2015-06-18 09:14:34

标签: java pdf itext

我最后生成目录,我想在开始时移动目录。 假设我的PDF中有16页,TOC从第13页开始到第15页结束。 我想将TOC移动到第二页,这样第一页仍然是第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) {
    }
}

请提出一些解决方案。

2 个答案:

答案 0 :(得分:4)

你的公式错了。你有:

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

从这些变量中,我们得到两个变量:

  • TOC的最后一页。这是最后一页减一,或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)

第一次出现的%sString后的第一个参数替换,%s的第二次出现被String后的第二个参数替换,并且等......

如果startToc = 13n = 16,则会产生:

1, 13-15, 2-12, 16

答案 1 :(得分:0)

您可以选择由PdfReader引用的页面:

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

然后您可以按顺序使用PdfStamper或PdfCopy进行组装。 请参阅:

Itext DocumentationRelated 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();
}
Bruno发布的

编辑2:,这是一个糟糕的解决方案,因为使用文档/ pdfWritter组合丢失了所有pdf链接。