我需要对回答以下问题时给出的示例进行修改:How to convert an existing A4 PDF document to an A3 booklet?
我或多或少有相同的要求,但我不希望连续的页面在同一页面上并排出现。
例如:如果我有以下文件
我希望输出如下:
请建议我如何使用iText。
答案 0 :(得分:1)
当打印书籍时,打印页面的机器实际上打印在更大的页面上,然后通常会切割和折叠更大的页面。您会看到大多数图书的总页数可以被16个分割。例如,当我写“iText in Action”书籍时,添加了其他书籍广告的额外页面,以便总页数是16的倍数。
这显示了通常打印页面的方式:
(图片来自名为“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