Combine PDFs with Page Imposition - C++ Sample Code

Sample code for using Apryse SDK to combine (impose) multiple PDF pages. Page imposition can be used to arrange/order pages prior to printing or for document assembly (assemble a 'master' page from several 'source' pages). It is also possible to write applications that can re-order the pages such that they will display in the correct order when the hard copy pages are compiled and folded correctly. Sample code provided in Python, C++, C#, Java, Node.js (JavaScript), PHP, Ruby and VB.

Learn more about our Server SDK and PDF Editing & Manipulation Library.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6#include <PDF/PDFNet.h>
7#include <PDF/PDFDoc.h>
8#include <PDF/ElementBuilder.h>
9#include <PDF/ElementWriter.h>
10#include <PDF/ElementReader.h>
11#include <iostream>
12#include "../../LicenseKey/CPP/LicenseKey.h"
13
14using namespace std;
15using namespace pdftron;
16using namespace Common;
17using namespace SDF;
18using namespace PDF;
19
20//-----------------------------------------------------------------------------------
21// The sample illustrates how multiple pages can be combined/imposed
22// using PDFNet. Page imposition can be used to arrange/order pages
23// prior to printing or to assemble a 'master' page from several 'source'
24// pages. Using PDFNet API it is possible to write applications that can
25// re-order the pages such that they will display in the correct order
26// when the hard copy pages are compiled and folded correctly.
27//-----------------------------------------------------------------------------------
28
29int main(int argc, char *argv[])
30{
31 int ret = 0;
32 PDFNet::Initialize(LicenseKey);
33
34 const char* resource_path = argc>3 ? argv[3] : "../../../resources";
35
36 // Relative path to the folder containing test files.
37 string input_path = "../../TestFiles/newsletter.pdf";
38 string output_path = "../../TestFiles/Output/newsletter_booklet.pdf";
39
40 try
41 {
42 cout << "-------------------------------------------------" << endl;
43 cout << "Opening the input pdf..." << endl;
44
45 const char* filein = argc>1 ? argv[1] : input_path.c_str();
46 const char* fileout = argc>2 ? argv[2] : output_path.c_str();
47
48 PDFDoc in_doc(filein);
49 in_doc.InitSecurityHandler();
50
51 // Create a list of pages to import from one PDF document to another.
52 vector<Page> import_pages;
53 for (PageIterator itr=in_doc.GetPageIterator(); itr.HasNext(); itr.Next())
54 import_pages.push_back(itr.Current());
55
56 PDFDoc new_doc;
57 vector<Page> imported_pages = new_doc.ImportPages(import_pages);
58
59 // Paper dimension for A3 format in points. Because one inch has
60 // 72 points, 11.69 inch 72 = 841.69 points
61 Rect media_box(0, 0, 1190.88, 841.69);
62 double mid_point = media_box.Width()/2;
63
64 ElementBuilder builder;
65 ElementWriter writer;
66
67 for (size_t i=0; i<imported_pages.size(); ++i)
68 {
69 // Create a blank new A3 page and place on it two pages from the input document.
70 Page new_page = new_doc.PageCreate(media_box);
71 writer.Begin(new_page);
72
73 // Place the first page
74 Page src_page = imported_pages[i];
75 Element element = builder.CreateForm(src_page);
76
77 double sc_x = mid_point / src_page.GetPageWidth();
78 double sc_y = media_box.Height() / src_page.GetPageHeight();
79 double scale = sc_x < sc_y ? sc_x : sc_y; // min(sc_x, sc_y)
80 element.GetGState().SetTransform(scale, 0, 0, scale, 0, 0);
81 writer.WritePlacedElement(element);
82
83 // Place the second page
84 ++i;
85 if (i<imported_pages.size()) {
86 src_page = imported_pages[i];
87 element = builder.CreateForm(src_page);
88 sc_x = mid_point / src_page.GetPageWidth();
89 sc_y = media_box.Height() / src_page.GetPageHeight();
90 scale = sc_x < sc_y ? sc_x : sc_y; // min(sc_x, sc_y)
91 element.GetGState().SetTransform(scale, 0, 0, scale, mid_point, 0);
92 writer.WritePlacedElement(element);
93 }
94
95 writer.End();
96 new_doc.PagePushBack(new_page);
97 }
98
99 new_doc.Save(fileout, SDFDoc::e_linearized, 0);
100 cout << "Done. Result saved in newsletter_booklet.pdf..." << endl;
101 }
102 catch(Common::Exception& e)
103 {
104 cout << e << endl;
105 ret = 1;
106 }
107 catch(...)
108 {
109 cout << "Unknown Exception" << endl;
110 ret = 1;
111 }
112
113 PDFNet::Terminate();
114 return ret;
115}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales