package mkl.testarea.pdfbox2.content; import java.awt.Color; import java.io.File; import java.io.IOException; import org.apache.pdfbox.multipdf.LayerUtility; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject; import org.apache.pdfbox.util.Matrix; import org.junit.BeforeClass; import org.junit.Test; /** * @author mkl */ public class JoinPages { final static File RESULT_FOLDER = new File("target/test-outputs", "content"); @BeforeClass public static void setUpBeforeClass() throws Exception { RESULT_FOLDER.mkdirs(); } /** * <a href="https://stackoverflow.com/questions/47295391/create-a-one-page-pdf-from-two-pdfs-using-pdfbox"> * create a one page PDF from two PDFs using PDFBOX * </a> * <p> * This test shows how to join two pages into one putting one above the other. * </p> */ @Test public void testJoinSmallAndBig() throws IOException { try ( PDDocument document = new PDDocument(); PDDocument top = prepareSmallPdf(); PDDocument bottom = prepareBiggerPdf()) { join(document, top, bottom); document.save(new File(RESULT_FOLDER, "joinedPage.pdf")); } } /** * @see #testJoinSmallAndBig() */ void join(PDDocument target, PDDocument topSource, PDDocument bottomSource) throws IOException { LayerUtility layerUtility = new LayerUtility(target); PDFormXObject topForm = layerUtility.importPageAsForm(topSource, 0); PDFormXObject bottomForm = layerUtility.importPageAsForm(bottomSource, 0); float height = topForm.getBBox().getHeight() + bottomForm.getBBox().getHeight(); float width, topMargin, bottomMargin; if (topForm.getBBox().getWidth() > bottomForm.getBBox().getWidth()) { width = topForm.getBBox().getWidth(); topMargin = 0; bottomMargin = (topForm.getBBox().getWidth() - bottomForm.getBBox().getWidth()) / 2; } else { width = bottomForm.getBBox().getWidth(); topMargin = (bottomForm.getBBox().getWidth() - topForm.getBBox().getWidth()) / 2; bottomMargin = 0; } PDPage targetPage = new PDPage(new PDRectangle(width, height)); target.addPage(targetPage); PDPageContentStream contentStream = new PDPageContentStream(target, targetPage); if (bottomMargin != 0) contentStream.transform(Matrix.getTranslateInstance(bottomMargin, 0)); contentStream.drawForm(bottomForm); contentStream.transform(Matrix.getTranslateInstance(topMargin - bottomMargin, bottomForm.getBBox().getHeight())); contentStream.drawForm(topForm); contentStream.close(); } /** * @see #testJoinSmallAndBig() */ PDDocument prepareSmallPdf() throws IOException { PDDocument document = new PDDocument(); PDPage page = new PDPage(new PDRectangle(72, 72)); document.addPage(page); PDPageContentStream contentStream = new PDPageContentStream(document, page); contentStream.setNonStrokingColor(Color.YELLOW); contentStream.addRect(0, 0, 72, 72); contentStream.fill(); contentStream.setNonStrokingColor(Color.BLACK); PDFont font = PDType1Font.HELVETICA; contentStream.beginText(); contentStream.setFont(font, 18); contentStream.newLineAtOffset(2, 54); contentStream.showText("small"); contentStream.newLineAtOffset(0, -48); contentStream.showText("page"); contentStream.endText(); contentStream.close(); return document; } /** * @see #testJoinSmallAndBig() */ PDDocument prepareBiggerPdf() throws IOException { PDDocument document = new PDDocument(); PDPage page = new PDPage(PDRectangle.A5); document.addPage(page); PDPageContentStream contentStream = new PDPageContentStream(document, page); contentStream.setNonStrokingColor(Color.GREEN); contentStream.addRect(0, 0, PDRectangle.A5.getWidth(), PDRectangle.A5.getHeight()); contentStream.fill(); contentStream.setNonStrokingColor(Color.BLACK); PDFont font = PDType1Font.HELVETICA; contentStream.beginText(); contentStream.setFont(font, 18); contentStream.newLineAtOffset(2, PDRectangle.A5.getHeight() - 24); contentStream.showText("This is the Bigger page"); contentStream.newLineAtOffset(0, -48); contentStream.showText("BIGGER!"); contentStream.endText(); contentStream.close(); return document; } }