Merging PDFs
Use the pdf endpoint to easily merge PDF documents into a combined PDF document.
This tutorial uses the pdf
endpoint to merge three pre-existing PDFs into a new combined PDF.
We first call the pdf
endpoint directly using cURL from the command-line. We then use the DynamicPDF client libraries to illustrate merging using C#, Java, Node.js, PHP, GO, and Python.
Required Resources
To complete this tutorial, you must add the merge-pdfs-pdf-endpoint
sample to your samples folder in your cloud storage space using the File Manager. After adding the sample resources, you should see a samples/merge-pdfs-pdf-endpoint
folder containing the resources for this tutorial.
Sample | Sample Folder | Resources |
---|---|---|
Merge PDFs | samples/merge-pdfs-pdf-endpoint | DocumentA.pdf , DocumentB.pdf , DocumentC.pdf , instructions.json |
- From you cloud storage space, use the File Manager to download
DocumentA.pdf
,DocumentB.pdf
, andinstructions.json
to your local system; here we assume/temp/dynamicpdf-api-samples
. - After downloading, delete the documents and instructions from
samples/merge-pdfs-pdf-endpoint
using the File Manager. Be certain not to deleteDocumentC.pdf
.
Resource | Cloud/Local |
---|---|
DocumentA.pdf | local |
DocumentB.pdf | local |
DocumentC.pdf | cloud |
instructions.json | local |
See Sample Resources for instructions on adding sample resources.
Obtaining API Key
This tutorial assumes a valid API key. Refer to the following for instructions on getting an API key.
If you are not familiar with the File Manager or Apps and API Keys, refer to the following tutorial and relevant Users Guide pages.
Calling API Directly Using POST
Merging resources into a new PDF requires using the pdf endpoint. The pdf endpoint uses an instructions JSON document you send to the endpoint. The endpoint then processes the instructions to create the resultant PDF. When you call the pdf endpoint directly, you must create an instructions document. When you use one of the DynamicPDF client libraries, then the client library hides the complexities of creating the instructions document from you.
Let's call the endpoint directly using an instructions document.
Instructions JSON
- Open the
instructions.json
document that you downloaded earlier in a text editor.
{
"author": "Alex Smith",
"inputs": [
{
"type": "pdf",
"resourceName": "DocumentA.pdf",
"startPage": 1,
"pageCount": 1
},
{
"type": "pdf",
"resourceName": "DocumentB.pdf"
},
{
"type": "pdf",
"resourceName": "samples/merge-pdfs-pdf-endpoint/DocumentC.pdf"
}
]
}
The most important part of an instructions document is the inputs array. This array is where you specify the inputs to the pdf endpoint. Here we are specifying that three PDF documents as the inputs. The first two we refer to by name only, as you will download them from your cloud storage space to your local system and then use them locally. Dynamic resources that change with every request should be uploaded with the request and not reside in your cloud storage. The last document you refer to by the resources' path in your cloud storage space using the File Manager.
As you see in the next section, when referring to a resource locally, you specify the resource's name in the instructions document and its path in the call to the endpoint. When referring to a resource in your cloud storage space, you specify the path of the resource in the File Manager.
Refer to JSON Instructions Schema or Instructions Schema Diagram for more information on creating instruction documents.
cURL Command
The pdf
endpoint takes a POST request. When using cURL, you specify the endpoint, the HTTP command, the API key, any local resources required, and the instructions document. The following cURL command illustrates.
The tutorial's video uses Postman rather than the cURL command.
curl -X POST https://api.dpdf.io/v1.0/pdf
-H "Authorization:Bearer DP.xxx-api-key-xxx"
-F "Resource=@C:/temp/dynamicpdf-api-samples/DocumentA.pdf"
-F "Resource=@C:/temp/dynamicpdf-api-samples/DocumentB.pdf"
-F "Instructions=@C:/temp/dynamicpdf-api-samples/instructions.json"
-o merge-output.pdf
The cURL command places any errors in the output.pdf rather than command-line. If you cannot open the created PDF, try opening the PDF in a text editor to view the error message.
In the preceding command, the -H
parameter specifies that a header variable named Authorization
is sent to the endpoint. The two -F
parameters specify that they are form fields with the name of Resource
and then the value. The value of the two parameters specify the paths of both local resources.
If a filename in the cURL command does not match the filename in the instructions document, then add the filename by using a semicolon followed by the filename from the instructions document.
"Resource=@C:/temp/dynamicpdf-api-samples/DocumentB.pdf;MyDocument"
The -o
parameter specifies the output file to write the response to.
- Execute the cURL command and the PDF is saved to your local system.
Figure 1. The merged PDF after the pdf
endpoint processed.
Calling Endpoint Using Client Library
To simplify your development, you can also use one of the DynamicPDF API client libraries. Use the client library of your choice to complete this tutorial section.
Complete Source
You can access the complete source for this project at one of the following GitHub projects.
Language | File Name | Location (package/namespace/etc.) | GitHub Project |
---|---|---|---|
Java | MergePdfs.java | com.dynamicpdf.api.examples | https://github.com/dynamicpdf-api/java-client-examples |
C# | Program.cs | MergePdfs | https://github.com/dynamicpdf-api/dotnet-client-examples |
Nodejs | MergePdfs.js | nodejs-client-examples | https://github.com/dynamicpdf-api/nodejs-client-examples |
PHP | MergePdfs.php | php-client-examples | https://github.com/dynamicpdf-api/php-client-examples |
GO | merge-pdfs.go | go-client-examples | https://github.com/dynamicpdf-api/go-client-examples/tree/main |
Python | MergePdfs.py | python-client-examples | https://github.com/dynamicpdf-api/python-client-examples |
Click on the language tab of choice to view the tutorial steps for the particular language.
- C# (.NET)
- Java
- Node.js
- PHP
- GO
- Python
Available on NuGet:
Install-Package DynamicPDF.API
- Create a new Visual Studio C# Console App (.NET Core) project named
MergePdfs
. - Add the DynamicPdf.Api Nuget package to the project.
- Create a new static method named
Run
that takes the API key and base path as strings. - Add the call to
Run
toMain
. - In
Run
create a newPdf
instance. - Add
DocumentA.pdf
to thePdf
instance and get a reference to the returnedPdfInput
instance. - Set the
PdfInput
instance'sStartPage
property to one and itsEndPage
property to one. - Create a new
PdfResource
instance and in its constructor set the path toDocumentC.pdf
Note the difference between how you add the PDFs. Use the AddPdf
method to add a PDF that resides in your cloud storage space but use PdfResource
to add a resource from the local system.
-
Create a call to the
Process
method to return aPdfResponse
instance. -
Check to ensure the call is successful and then write the response's
Content
to a file.
using System;
using System.IO;
namespace MergePdfs
{
class Program
{
static void Main(string[] args)
{
Run("DP.xxx-api-key-xxx", "C:/temp/dynamicpdf-api-samples/");
}
public static void Run(String apiKey, String basePath)
{
// create new pdf instance and set api key
Pdf pdf = new Pdf();
pdf.ApiKey = apiKey;
//add pdf and get reference to PdfInput then set pages to append
var inputA = pdf.AddPdf(new PdfResource(basePath + "DocumentA.pdf"));
inputA.StartPage = 1;
inputA.PageCount = 1;
// add all of pdf from local system
pdf.AddPdf(new PdfResource(basePath + "DocumentB.pdf"));
// add pdf from cloud in resource manager
pdf.AddPdf("/samples/merge-pdfs-pdf-endpoint/DocumentC.pdf");
//call the pdf endpoint and get response
PdfResponse pdfResponse = pdf.Process();
// if successful, save merged pdf to file otherwise print JSON error
if(pdfResponse.IsSuccessful)
{
File.WriteAllBytes(Path.Combine(basePath, "merge-pdfs-output.pdf"), pdfResponse.Content);
} else
{
Console.WriteLine(pdfResponse.ErrorJson);
}
// process and get response from pdf endpoint
PdfResponse pdfResponse = pdf.Process();
// if the response is successful, save merged pdf to file if error, then printout JSON error
if(pdfResponse.IsSuccessful)
{
File.WriteAllBytes(Path.Combine(basePath, "merge-output.pdf"), pdfResponse.Content);
} else
{
Console.WriteLine(pdfResponse.ErrorJson);
}
}
}
- Run the application and the merged PDF is saved to your local system.
Available on NPM:
npm i @dynamicpdf/api
-
Use npm to install the DynamicPDF API module.
-
Create a new class named
MergePdfs
. -
Create a static
Run
method. -
Add a new instance of a
Pdf
class. -
Add
DocumentA.pdf
to thePdf
instance and get a reference to the returnedPdfInput
instance. -
Set the
PdfInput
instance'sstartPage
property to one and itsendPage
property to one. -
Create a new
PdfResource
instance and in its constructor set the path toDocumentC.pdf
Note the difference between how you add the PDFs. Use the AddPdf
method to add a PDF that resides in your cloud storage space but use PdfResource
to add a resource from the local system.
- Call
process
to return aPdfResponse
instance. - Check to ensure the call is successful and then write the response's
content
to a file. - Add the
Run
method call below theMergePdf
class definition.
import fs from 'fs';
import {
Pdf,
PdfResource,
PdfInput,
Endpoint
} from "@dynamicpdf/api"
export class MergePdfs {
static async Run() {
var pdf = new Pdf();
pdf.apiKey = "DP.xxx-api-key-xxx";
//add pdf from local system and obtain the reference to the pdfInput
var pdfInput = pdf.addPdf(new PdfResource("C:/temp/dynamicpdf-api-samples/DocumentA.pdf"));
//set the start page and page count so it returns one page
pdfInput.startPage = 1;
pdfInput.pageCount = 1;
//add the pdf from local system
pdf.addPdf(new PdfResource("C:/temp/dynamicpdf-api-samples/DocumentB.pdf"));
//add the pdf from File Manager
pdf.addPdf("samples/merge-pdfs-pdf-endpoint/DocumentC.pdf");
//call the endpoint and get response
var res = await pdf.process();
//if succsessful write response pdf to file otherwise print failure JSON
if (res.isSuccessful) {
var outFile = "C:/temp/dynamicpdf-api-samples/merge-pdfs-output.pdf";
var outStream = fs.createWriteStream(outFile);
outStream.write(res.content);
outStream.close();
} else {
console.log(res.errorJson);
}
}
}
await MergePdfs.Run();
- Run the application
node MergePdfs.js
and the merged PDF is written to your filesystem.
Available on Maven:
https://search.maven.org/search?q=g:com.dynamicpdf.api
<dependency>
<groupId>com.dynamicpdf.api</groupId>
<artifactId>dynamicpdf-api</artifactId>
<version>1.8.0</version>
</dependency>
- Create a new Maven project and add the DynamicPDF API as a dependency, also add the Apache Commons IO library.
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
-
Create a new class named
MergePdfs
with amain
method. -
Create a new method named
Run
. -
Add the
Run
method call tomain
. -
In
Run
create a newPdf
instance. -
Add
DocumentA.pdf
to thePdf
instance and get a reference to the returnedPdfInput
instance. -
Set the
PdfInput
instance'sStartPage
property to one and itsEndPage
property to one. -
Create a new
PdfResource
instance and in its constructor set the path toDocumentC.pdf
to add the PDF from your cloud storage space.
Note the difference between how you add the PDFs. Use the AddPdf
method to add a PDF that resides in your cloud storage but use PdfResource
to add a resource from the local system.
-
Create a call to the
process
method to return aPdfResponse
instance. -
Check to ensure the call was successful and write the response's
Content
to a file.
package com.dynamicpdf.api.examples;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import com.dynamicpdf.api.Pdf;
import com.dynamicpdf.api.PdfInput;
import com.dynamicpdf.api.PdfResource;
import com.dynamicpdf.api.PdfResponse;
public class MergePdfs {
public static void main(String[] args) {
MergePdfs.Run("DP.xxx-api-key-xxx",
"C:/temp/dynamicpdf-api-samples/");
}
public static void Run(String apiKey, String basePath) {
// create new pdf instance and set api key
Pdf pdf = new Pdf();
pdf.setApiKey(apiKey);
// add pdf from local system where specify that only one page
// from DocumentA is to be merged.
PdfInput pdfInput = pdf.addPdf(new PdfResource(basePath + "DocumentA.pdf"));
pdfInput.setStartPage(1);
pdfInput.setPageCount(1);
// add all of DocumentB to the PDF to be created
pdf.addPdf(new PdfResource(basePath + "DocumentB.pdf"));
// add DocumentC from the cloud in File Manager
pdf.addPdf("samples/merge-pdfs-pdf-endpoint/DocumentC.pdf");
// call the endpoint and return the results
PdfResponse pdfResponse = pdf.process();
// if the response is successful, save merged pdf to file. if error, then
// printout JSON error
if (pdfResponse.getIsSuccessful()) {
try {
FileUtils.writeByteArrayToFile(new File(basePath + "merge-pdfs-output.pdf"), pdfResponse.getContent());
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println(pdfResponse.getErrorJson());
}
}
}
- Run the application and the merged PDF is saved to your local system.
Available as a Composer package:
composer require dynamicpdf/api
-
Use composer to ensure you have the required PHP libraries.
-
Create a new class named
MergePdfs
. -
Add a
Run
method. -
In
Run
create a newPdf
instance. -
Add
DocumentA.pdf
to aPdfResource
instance and then add it to thePdf
instance -
Get a reference to the returned
PdfInput
instance. -
Set the
PdfInput
instance'sStartPage
property to one and itsEndPage
property to one. -
Add
DocumentB.pdf
to aPdfResource
instance and then add it to thePdf
instance. -
Add
DocumentC.pdf
to thePdf
instance directly, as the PDF comes from your cloud storage.
Note the difference between how you add the PDFs. Use the AddPdf
method to add a PDF that resides in the cloud in the File Manager but use PdfResource
to add a resource from the local system.
-
Create a call to the
Process
method to return aPdfResponse
instance. -
Ensure the call is successful and write the response's
Content
to a file.
require __DIR__ . '/vendor/autoload.php';
include_once("constants.php");
use DynamicPDF\Api\Pdf;
use DynamicPDF\Api\PdfResource;
class MergePdfs
{
public static function Run(string $apikey, string $path, string $output_path)
{
$pdf = new Pdf();
$pdf->ApiKey = $apikey;
$pdf->BaseUrl = "https://api-euw.dpdf.io/";
$pdfInput = $pdf->AddPdf(new PdfResource($path . "DocumentA.pdf"));
$pdfInput->StartPage = 1;
$pdfInput->PageCount = 1;
$pdf->AddPdf(new PdfResource($path . "DocumentB.pdf"));
$pdf->AddPdf("samples/merge-pdfs-pdf-endpoint/DocumentC.pdf");
$response = $pdf->Process();
if($response->IsSuccessful)
{
file_put_contents($output_path . "merge-pdfs-php-output.pdf", $response->Content);
} else {
echo("Error: ");
echo($response->StatusCode);
echo($response->ErrorJson);
}
}
}
MergePdfs::Run(CLIENT_EXAMPLES_API_KEY, CLIENT_EXAMPLES_BASE_PATH . "/merge-pdfs-pdf-endpoint/", CLIENT_EXAMPLES_OUTPUT_PATH);
- Run the application
php MergePdfs.php
and the merged PDF is saved to your local system.
Available a GO package: https://pkg.go.dev/github.com/dynamicpdf-api/go-client
- Ensure you have the required GO libraries
- Create a new class named
MergePdfs
. - Add a
main
method. - In
main
create a newPdf
instance. - Add
DocumentA.pdf
to aPdfResource
instance and then add it to thePdf
instance. - Get a reference to the returned
PdfInput
instance. - Set the
PdfInput
instance'sStartPage
property to one and itsEndPage
property to one. - Add
DocumentB.pdf
to aPdfResource
instance and then add it to thePdf
instance. - Add
DocumentC.pdf
to thePdf
instance directly, as the PDF comes from your cloud storage. - Create a call to the
Process
method to return aPdfResponse
instance. - Ensure the call is successful and write the response's
Content
to a file. - Run the application
go run MergePdfs.go
and the merged PDF is saved to your local system.
package main
import (
"fmt"
"os"
"github.com/dynamicpdf-api/go-client/endpoint"
"github.com/dynamicpdf-api/go-client/input"
"github.com/dynamicpdf-api/go-client/resource"
)
func main() {
pr := endpoint.NewPdf()
pr.Endpoint.BaseUrl = "https://api.dpdf.io/"
pr.Endpoint.ApiKey = "DP.xxx-api-key-xxx"
basePath := "c:/temp/dynamicpdf-api-samples/"
pdfResource := resource.NewPdfResourceWithResourcePath(basePath+"DocumentA.pdf", "DocumentA.pdf")
prInput := input.NewPdfWithResource(pdfResource)
prInput.StartPage = 1
prInput.PageCount = 1
pr.Inputs = append(pr.Inputs, prInput)
pdfResource2 := resource.NewPdfResourceWithResourcePath(basePath+"DocumentB.pdf", "DocumentB.pdf")
prInput2 := input.NewPdfWithResource(pdfResource2)
pr.Inputs = append(pr.Inputs, prInput2)
mergeOption := input.NewMergeOptions()
prInput3 := input.NewPdfWithCloudPath("samples/merge-pdfs-pdf-endpoint/DocumentC.pdf", mergeOption)
pr.Inputs = append(pr.Inputs, prInput3)
resp := pr.Process()
res := <-resp
if res.IsSuccessful() == false {
if res.ClientError() != nil {
fmt.Print("Failed with error: " + res.ClientError().Error())
} else {
fmt.Print("Failed with error: " + res.ErrorJson())
}
} else {
os.WriteFile(basePath+"merge-pdfs-output.pdf",
res.Content().Bytes(), os.ModeType)
}
}
Available at: pip install dynamicpdf-api
- Ensure you have the required Python libraries
- Create a new file named
MergePdfs.py
. - Add a
merge_pdfs
method. - Create a new
Pdf
instance. - Add
DocumentA.pdf
to aPdfResource
instance and then add it to thePdf
instance. - Get a reference to the returned
PdfInput
instance. - Set the
PdfInput
instance'sStartPage
property to one and itsEndPage
property to one. - Add
DocumentB.pdf
to aPdfResource
instance and then add it to thePdf
instance. - Add
DocumentC.pdf
to thePdf
instance directly, as the PDF comes from your cloud storage. - Create a call to the
Process
method to return aPdfResponse
instance. - Ensure the call is successful and write the response's
Content
to a file. - Add the call to
merge_pdfs
. - Run the application
python MergePdfs.py
and the merged PDF is saved to your local system.
from dynamicpdf_api.pdf import Pdf
from dynamicpdf_api.pdf_resource import PdfResource
def merge_pdfs():
basePath = "C:/temp/dynamicpdf-api-samples/"
pdf=Pdf()
pdf.api_key="DP.xxx-api-key-xxx"
inputA = pdf.add_pdf(PdfResource(basePath + "DocumentA.pdf"))
inputA.start_page = 1
inputA.page_count = 2
pdf.add_pdf(PdfResource(basePath + "DocumentB.pdf"))
pdf.add_pdf("samples/merge-pdfs-pdf-endpoint/DocumentC.pdf")
response = pdf.process()
if response.is_successful:
with open(basePath + "merge-pdfs-output-python.pdf", "wb") as output_file:
output_file.write(response.content)
else:
print(response.error_id)
print(response.error_message)
print(response.error_json)
merge_pdfs()
In all six languages, the steps were similar. First, we created a new instance of the Pdf
class, which abstracts the pdf
endpoint. This Pdf
instance holds the merged PDF after processing. We then added two local resources, DocumentA.pdf
and DocumentB.pdf
, to the pdf
endpoint. We first created a PdfResource
instance to add these local resources and then added the PdfResource
instance to the Pdf
instance. Because we only wanted the first page of DocumentA.pdf
, we obtained a reference to the returned PdfInput
. By getting a reference to the PdfInput
object containing DocumentA.pdf
, we could add merge instructions specifying only to use the first page.
We then added DocumentC.pdf
, but rather than first creating a PdfResource
instance, we added the resource directly to the Pdf
instance using its AddPdf
method.
The difference between adding local resources and adding cloud resources in the File Manager bears repeating. Add local resources by first creating a PdfResource
instance that loads the resource and then adding the PdfResource
instance to the Pdf
instance using its AddPdf
method. Add cloud resources in File Manager by calling AddPdf
and passing the path in File Manager as a string.
After adding all the resources to the Pdf
instance, we then call the endpoint using the Process
method and obtain the response from the endpoint. Finally, we ensured the call was successful and wrote the response's content to a PDF file.