如何将A4尺寸的PDF转换为A3 PDF小册子?

时间:2015-12-23 09:35:05

标签: java pdf itext

我需要对回答以下问题时给出的示例进行修改:How to convert an existing A4 PDF document to an A3 booklet?

我或多或少有相同的要求,但我不希望连续的页面在同一页面上并排出现。

例如:如果我有以下文件

我希望输出如下:

请建议我如何使用iText。

1 个答案:

答案 0 :(得分:1)

当打印书籍时,打印页面的机器实际上打印在更大的页面上,然后通常会切割和折叠更大的页面。您会看到大多数图书的总页数可以被16个分割。例如,当我写“iText in Action”书籍时,添加了其他书籍广告的额外页面,以便总页数是16的倍数。

这显示了通常打印页面的方式:

enter image description here (图片来自名为“Page counts explained”的博客

我们可以轻松地将具有A4页面的文档转换为具有A4尺寸的8倍的文档,其中我们将8页原始文档添加到新文档中的单个页面,组织方式如上所示图片。这是在MakeBooklet示例中完成的:

public void manipulatePdf(String src, String dest)
    throws IOException, DocumentException {
    // Creating a reader
    PdfReader reader = new PdfReader(src);
    // step 1
    Rectangle pagesize = new Rectangle(
        PageSize.A4.getWidth() * 4,
        PageSize.A4.getHeight() * 2);
    Document document = new Document(pagesize);
    // step 2
    PdfWriter writer
        = PdfWriter.getInstance(document, new FileOutputStream(dest));
    // step 3
    document.open();
    // step 4
    PdfContentByte canvas = writer.getDirectContent();
    float a4_width = PageSize.A4.getWidth();
    float a4_height = PageSize.A4.getHeight();
    int n = reader.getNumberOfPages();
    int p = 1;
    PdfImportedPage page;
    while ((p - 1) / 16 <= n / 16) {
        addPage(canvas, reader, p + 3, 0);
        addPage(canvas, reader, p + 12, a4_width);
        addPage(canvas, reader, p + 15, a4_width * 2);
        addPage(canvas, reader, p, a4_width * 3);
        AffineTransform at = AffineTransform.getRotateInstance(-Math.PI);
        at.concatenate(AffineTransform.getTranslateInstance(0, -a4_height * 2));
        canvas.saveState();
        canvas.concatCTM(at);
        addPage(canvas, reader, p + 4, -a4_width);
        addPage(canvas, reader, p + 11, -a4_width * 2);
        addPage(canvas, reader, p + 8, -a4_width * 3);
        addPage(canvas, reader, p + 7, -a4_width * 4);
        canvas.restoreState();
        document.newPage();
        addPage(canvas, reader, p + 1, 0);
        addPage(canvas, reader, p + 14, a4_width);
        addPage(canvas, reader, p + 13, a4_width * 2);
        addPage(canvas, reader, p + 2, a4_width * 3);
        canvas.saveState();
        canvas.concatCTM(at);
        addPage(canvas, reader, p + 6, -a4_width);
        addPage(canvas, reader, p + 9, -a4_width * 2);
        addPage(canvas, reader, p + 10, -a4_width * 3);
        addPage(canvas, reader, p + 5, -a4_width * 4);
        canvas.restoreState();
        document.newPage();
        p += 16;
    }
    // step 5
    document.close();
    reader.close();
}

public void addPage(PdfContentByte canvas,
        PdfReader reader, int p, float x) {
    if (p > reader.getNumberOfPages()) return;
    PdfImportedPage page = canvas.getPdfWriter().getImportedPage(reader, p);
    canvas.addTemplate(page, x, 0);
}

manipulatePdf()方法中,我们创建了一个循环,我们在其中添加了2个页面。在每个页面上,我们添加8页原始PDF,但我们在非常具体的地方添加这些页面。对于最后4行的页面,我们介绍了一个翻译(我们为每个新页面向右移动a4_width)。然后我们引入一个旋转来添加顶行页面(它们需要颠倒)。

那很有趣不是吗?实际上,这只是数学问题(而数学总是有趣)。您可以在此处找到结果:book16.pdf

你的问题不那么有趣,因为它很简单。您甚至不需要旋转页面!看看MakeBookletA3示例:

public void manipulatePdf(String src, String dest)
    throws IOException, DocumentException {
    // Creating a reader
    PdfReader reader = new PdfReader(src);
    // step 1
    Rectangle pagesize = new Rectangle(
        PageSize.A4.getWidth() * 2,
        PageSize.A4.getHeight());
    Document document = new Document(pagesize);
    // step 2
    PdfWriter writer
        = PdfWriter.getInstance(document, new FileOutputStream(dest));
    // step 3
    document.open();
    // step 4
    PdfContentByte canvas = writer.getDirectContent();
    float a4_width = PageSize.A4.getWidth();
    int n = reader.getNumberOfPages();
    int p = 1;
    PdfImportedPage page;
    while ((p - 1) / 4 <= n / 4) {
        addPage(canvas, reader, p + 3, 0);
        addPage(canvas, reader, p, a4_width);
        document.newPage();
        addPage(canvas, reader, p + 1, 0);
        addPage(canvas, reader, p + 2, a4_width);
        document.newPage();
        p += 4;
    }
    // step 5
    document.close();
    reader.close();
}

public void addPage(PdfContentByte canvas,
        PdfReader reader, int p, float x) {
    if (p > reader.getNumberOfPages()) return;
    PdfImportedPage page = canvas.getPdfWriter().getImportedPage(reader, p);
    canvas.addTemplate(page, x, 0);
}

现在我们只在循环中创建2个页面,并且我们为每个新页面添加2个旧页面。结果:book4.pdf