PDF Page Manipulation - Merge, Copy, Delete, Rearrange - C++ Sample Code

Sample code for using Apryse SDK to copy pages from one document to another, delete and rearrange pages, and use ImportPages() method for very efficient copy and merge operations. 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#include <PDF/PDFNet.h>
6#include <PDF/PDFDoc.h>
7#include <PDF/PDFDocInfo.h>
8#include <iostream>
9#include "../../LicenseKey/CPP/LicenseKey.h"
10
11using namespace std;
12
13using namespace pdftron;
14using namespace SDF;
15using namespace PDF;
16using namespace Filters;
17
18
19int main(int argc, char *argv[])
20{
21 int ret = 0;
22 PDFNet::Initialize(LicenseKey);
23
24 // Relative path to the folder containing test files.
25 string input_path = "../../TestFiles/";
26 string output_path = "../../TestFiles/Output/";
27
28 // Sample 1 - Split a PDF document into multiple pages
29 try
30 {
31 cout << "_______________________________________________" << endl;
32 cout << "Sample 1 - Split a PDF document into multiple pages..." << endl;
33 cout << "Opening the input pdf..." << endl;
34 PDFDoc in_doc((input_path + "newsletter.pdf").c_str());
35 in_doc.InitSecurityHandler();
36
37 int page_num = in_doc.GetPageCount();
38 for (int i=1; i<=page_num; ++i)
39 {
40 PDFDoc new_doc;
41 char fname[256];
42 sprintf(fname, "newsletter_split_page_%d.pdf", i);
43 string output_file(output_path + fname);
44 new_doc.InsertPages(0, in_doc, i, i, PDFDoc::e_none);
45 new_doc.Save(output_file, SDFDoc::e_remove_unused, 0);
46 cout << "Done. Result saved in " << fname << endl;
47 }
48 }
49 catch(Common::Exception& e)
50 {
51 cout << e << endl;
52 ret = 1;
53 }
54 catch(...)
55 {
56 cout << "Unknown Exception" << endl;
57 ret = 1;
58 }
59
60 // Sample 2 - Merge several PDF documents into one
61 try
62 {
63 cout << "_______________________________________________" << endl;
64 cout << "Sample 2 - Merge several PDF documents into one..." << endl;
65 PDFDoc new_doc;
66 new_doc.InitSecurityHandler();
67
68 int page_num = 15;
69 for (int i=1; i<=page_num; ++i)
70 {
71 char fname[256];
72 sprintf(fname, "newsletter_split_page_%d.pdf", i);
73 string input_file(output_path + fname);
74 cout << "Opening " << fname << endl;
75 PDFDoc in_doc(input_file);
76 new_doc.InsertPages(i, in_doc, 1, in_doc.GetPageCount(), PDFDoc::e_none);
77 }
78 new_doc.Save(output_path + "newsletter_merge_pages.pdf", SDFDoc::e_remove_unused, 0);
79 cout << "Done. Result saved in newsletter_merge_pages.pdf" << endl;
80 }
81 catch(Common::Exception& e)
82 {
83 cout << e << endl;
84 ret = 1;
85 }
86 catch(...)
87 {
88 cout << "Unknown Exception" << endl;
89 ret = 1;
90 }
91
92
93 // Sample 3 - Delete every second page
94 try
95 {
96 cout << "_______________________________________________" << endl;
97 cout << "Sample 3 - Delete every second page..." << endl;
98 cout << "Opening the input pdf..." << endl;
99 PDFDoc in_doc((input_path + "newsletter.pdf").c_str());
100 in_doc.InitSecurityHandler();
101
102 int page_num = in_doc.GetPageCount();
103 while (page_num>=1)
104 {
105 PageIterator itr = in_doc.GetPageIterator(page_num);
106 in_doc.PageRemove(itr);
107 page_num -= 2;
108 }
109
110 in_doc.Save((output_path + "newsletter_page_remove.pdf").c_str(), 0, 0);
111 cout << "Done. Result saved in newsletter_page_remove.pdf..." << endl;
112 }
113 catch(Common::Exception& e)
114 {
115 cout << e << endl;
116 ret = 1;
117 }
118 catch(...)
119 {
120 cout << "Unknown Exception" << endl;
121 ret = 1;
122 }
123
124 // Sample 4 - Inserts a page from one document at different
125 // locations within another document
126 try
127 {
128 cout << "_______________________________________________" << endl;
129 cout << "Sample 4 - Insert a page at different locations..." << endl;
130 cout << "Opening the input pdf..." << endl;
131
132 PDFDoc in1_doc((input_path + "newsletter.pdf").c_str());
133 in1_doc.InitSecurityHandler();
134
135 PDFDoc in2_doc((input_path + "fish.pdf").c_str());
136 in2_doc.InitSecurityHandler();
137
138 PageIterator src_page = in2_doc.GetPageIterator();
139 PageIterator dst_page = in1_doc.GetPageIterator();
140 int page_num = 1;
141 while (dst_page.HasNext()) {
142 if (page_num++ % 3 == 0) {
143 in1_doc.PageInsert(dst_page, src_page.Current());
144 }
145 dst_page.Next();
146 }
147 in1_doc.Save((output_path + "newsletter_page_insert.pdf").c_str(), 0 , NULL);
148 cout << "Done. Result saved in newsletter_page_insert.pdf..." << endl;
149 }
150 catch(Common::Exception& e)
151 {
152 cout << e << endl;
153 ret = 1;
154 }
155 catch(...)
156 {
157 cout << "Unknown Exception" << endl;
158 ret = 1;
159 }
160
161 // Sample 5 - Replicate pages within a single document
162 try
163 {
164 cout << "_______________________________________________" << endl;
165 cout << "Sample 5 - Replicate pages within a single document..." << endl;
166 cout << "Opening the input pdf..." << endl;
167 PDFDoc doc((input_path + "newsletter.pdf").c_str());
168 doc.InitSecurityHandler();
169
170 // Replicate the cover page three times (copy page #1 and place it before the
171 // seventh page in the document page sequence)
172 Page cover = doc.GetPage(1);
173 PageIterator p7 = doc.GetPageIterator(7);
174 doc.PageInsert(p7, cover);
175 doc.PageInsert(p7, cover);
176 doc.PageInsert(p7, cover);
177
178 // Replicate the cover page two more times by placing it before and after
179 // existing pages.
180 doc.PagePushFront(cover);
181 doc.PagePushBack(cover);
182
183 doc.Save((output_path + "newsletter_page_clone.pdf").c_str(), 0, NULL);
184 cout << "Done. Result saved in newsletter_page_clone.pdf..." << endl;
185 }
186 catch(Common::Exception& e)
187 {
188 cout << e << endl;
189 ret = 1;
190 }
191 catch(...)
192 {
193 cout << "Unknown Exception" << endl;
194 ret = 1;
195 }
196
197 // Sample 6 - Use ImportPages() in order to copy multiple pages at once
198 // in order to preserve shared resources between pages (e.g. images, fonts,
199 // colorspaces, etc.)
200 try
201 {
202 cout << "_______________________________________________" << endl;
203 cout << "Sample 6 - Preserving shared resources using ImportPages..." << endl;
204 cout << "Opening the input pdf..." << endl;
205 PDFDoc in_doc((input_path + "newsletter.pdf").c_str());
206 in_doc.InitSecurityHandler();
207
208 PDFDoc new_doc;
209
210 vector<Page> copy_pages;
211 for (PageIterator itr=in_doc.GetPageIterator(); itr.HasNext(); itr.Next())
212 {
213 copy_pages.push_back(itr.Current());
214 }
215
216 vector<Page> imported_pages = new_doc.ImportPages(copy_pages);
217 vector<Page>::iterator i;
218 for (i=imported_pages.begin(); i!=imported_pages.end(); ++i)
219 {
220 new_doc.PagePushFront(*i); // Order pages in reverse order.
221 // Use PagePushBack() if you would like to preserve the same order.
222 }
223
224 new_doc.Save((output_path + "newsletter_import_pages.pdf").c_str(), 0, NULL);
225 cout << "Done. Result saved in newsletter_import_pages.pdf..." << endl << endl
226 << "Note that the output file size is less than half the size" << endl
227 << "of the file produced using individual page copy operations" << endl
228 << "between two documents" << endl;
229 }
230 catch(Common::Exception& e)
231 {
232 cout << e << endl;
233 ret = 1;
234 }
235 catch(...)
236 {
237 cout << "Unknown Exception" << endl;
238 ret = 1;
239 }
240
241 PDFNet::Terminate();
242 return ret;
243}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales