Skip to content

Commit 4ee145f

Browse files
Merge pull request #123 from datalogics-cgreen/blank-pdf
PDFCLOUD-5394 Add Blank PDF samples
2 parents efb1eb6 + 311c036 commit 4ee145f

25 files changed

Lines changed: 1158 additions & 0 deletions

File tree

CPlusPlus/Endpoint Examples/JSON Payload/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ if (cpr_FOUND AND nlohmann_json_FOUND)
1919
add_executable(translated_pdf_text_json translated_pdf_text.cpp)
2020
target_link_libraries(translated_pdf_text_json PRIVATE cpr::cpr nlohmann_json::nlohmann_json)
2121
target_compile_features(translated_pdf_text_json PRIVATE cxx_std_20)
22+
23+
add_executable(blank_pdf_json blank_pdf.cpp)
24+
target_link_libraries(blank_pdf_json PRIVATE cpr::cpr nlohmann_json::nlohmann_json)
25+
target_compile_features(blank_pdf_json PRIVATE cxx_std_20)
2226
endif()
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* What this sample does:
3+
* - Calls /blank-pdf with a JSON payload to create an empty three-page PDF.
4+
*
5+
* Setup (environment):
6+
* - Set PDFREST_API_KEY=your_api_key_here
7+
* - Optional: set PDFREST_URL to override the API region. For EU/GDPR, use:
8+
* PDFREST_URL=https://eu-api.pdfrest.com
9+
* More info: https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
10+
*
11+
* Usage:
12+
* ./blank_pdf_json
13+
*
14+
* Output:
15+
* - Prints the JSON response. Non-2xx responses exit non-zero.
16+
*/
17+
18+
#include <cpr/cpr.h>
19+
#include <nlohmann/json.hpp>
20+
21+
#include <cstdlib>
22+
#include <filesystem>
23+
#include <fstream>
24+
#include <iostream>
25+
#include <string>
26+
27+
namespace fs = std::filesystem;
28+
using json = nlohmann::json;
29+
30+
static std::string rtrim_slashes(std::string s) {
31+
while (!s.empty() && (s.back() == '/' || s.back() == '\\')) {
32+
s.pop_back();
33+
}
34+
return s;
35+
}
36+
37+
static void load_dotenv_if_present(const fs::path &path) {
38+
std::ifstream f(path);
39+
if (!f.is_open()) return;
40+
std::string line;
41+
while (std::getline(f, line)) {
42+
if (line.empty() || line[0] == '#') continue;
43+
auto pos = line.find('=');
44+
if (pos == std::string::npos) continue;
45+
std::string key = line.substr(0, pos);
46+
std::string val = line.substr(pos + 1);
47+
auto trim = [](std::string &s) {
48+
size_t start = s.find_first_not_of(" \t\r\n");
49+
size_t end = s.find_last_not_of(" \t\r\n");
50+
if (start == std::string::npos) { s.clear(); return; }
51+
s = s.substr(start, end - start + 1);
52+
};
53+
trim(key);
54+
trim(val);
55+
if (key.empty()) continue;
56+
if (std::getenv(key.c_str()) == nullptr) {
57+
#ifdef _WIN32
58+
_putenv_s(key.c_str(), val.c_str());
59+
#else
60+
setenv(key.c_str(), val.c_str(), 0);
61+
#endif
62+
}
63+
}
64+
}
65+
66+
static void load_env() {
67+
const fs::path here = fs::current_path();
68+
load_dotenv_if_present(here / ".env");
69+
if (fs::exists(here.parent_path())) {
70+
load_dotenv_if_present(here.parent_path() / ".env");
71+
}
72+
}
73+
74+
int main() {
75+
load_env();
76+
77+
const char *api_key_c = std::getenv("PDFREST_API_KEY");
78+
if (api_key_c == nullptr || std::string(api_key_c).empty()) {
79+
std::cerr << "Missing required environment variable: PDFREST_API_KEY\n";
80+
return 1;
81+
}
82+
83+
const char *base_url_c = std::getenv("PDFREST_URL");
84+
std::string base_url = base_url_c && std::string(base_url_c).size()
85+
? base_url_c
86+
: std::string("https://api.pdfrest.com");
87+
base_url = rtrim_slashes(base_url);
88+
89+
json payload = {
90+
{"page_size", "letter"},
91+
{"page_count", 3},
92+
{"page_orientation", "portrait"}
93+
};
94+
95+
cpr::Header headers{
96+
{"Api-Key", api_key_c},
97+
{"Accept", "application/json"},
98+
{"Content-Type", "application/json"}
99+
};
100+
101+
auto res = cpr::Post(
102+
cpr::Url{base_url + "/blank-pdf"},
103+
headers,
104+
cpr::Body{payload.dump()}
105+
);
106+
107+
if (res.error || res.status_code < 200 || res.status_code >= 300) {
108+
std::cerr << "blank-pdf failed (status " << res.status_code << "): "
109+
<< res.error.message << "\n" << res.text << "\n";
110+
return 1;
111+
}
112+
113+
std::cout << res.text << "\n";
114+
return 0;
115+
}

CPlusPlus/Endpoint Examples/Multipart Payload/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ if (cpr_FOUND)
1818
add_executable(translated_pdf_text_multipart translated_pdf_text.cpp)
1919
target_link_libraries(translated_pdf_text_multipart PRIVATE cpr::cpr)
2020
target_compile_features(translated_pdf_text_multipart PRIVATE cxx_std_20)
21+
22+
add_executable(blank_pdf_multipart blank_pdf.cpp)
23+
target_link_libraries(blank_pdf_multipart PRIVATE cpr::cpr)
24+
target_compile_features(blank_pdf_multipart PRIVATE cxx_std_20)
2125
endif()
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* What this sample does:
3+
* - Calls /blank-pdf via multipart/form-data to create a blank three-page PDF.
4+
*
5+
* Setup (environment):
6+
* - Copy .env.example to .env
7+
* - Set PDFREST_API_KEY=your_api_key_here
8+
* - Optional: set PDFREST_URL to override the API region. For EU/GDPR compliance and proximity, use:
9+
* PDFREST_URL=https://eu-api.pdfrest.com
10+
* For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
11+
*
12+
* Usage:
13+
* ./blank_pdf_multipart
14+
*
15+
* Output:
16+
* - Prints the JSON response to stdout; non-2xx exits with concise error.
17+
*/
18+
19+
#include <cpr/cpr.h>
20+
21+
#include <cstdlib>
22+
#include <filesystem>
23+
#include <fstream>
24+
#include <iostream>
25+
#include <string>
26+
27+
namespace fs = std::filesystem;
28+
29+
static std::string rtrim_slashes(std::string s) {
30+
while (!s.empty() && (s.back() == '/' || s.back() == '\\')) s.pop_back();
31+
return s;
32+
}
33+
34+
static void load_dotenv_if_present(const fs::path &path) {
35+
std::ifstream f(path);
36+
if (!f.is_open()) return;
37+
std::string line;
38+
while (std::getline(f, line)) {
39+
if (line.empty() || line[0] == '#') continue;
40+
auto p = line.find('=');
41+
if (p == std::string::npos) continue;
42+
std::string k = line.substr(0, p);
43+
std::string v = line.substr(p + 1);
44+
auto trim = [](std::string &s) {
45+
size_t b = s.find_first_not_of(" \t\r\n"), e = s.find_last_not_of(" \t\r\n");
46+
if (b == std::string::npos) { s.clear(); return; }
47+
s = s.substr(b, e - b + 1);
48+
};
49+
trim(k); trim(v);
50+
if (k.empty()) continue;
51+
if (!std::getenv(k.c_str())) {
52+
#ifdef _WIN32
53+
_putenv_s(k.c_str(), v.c_str());
54+
#else
55+
setenv(k.c_str(), v.c_str(), 0);
56+
#endif
57+
}
58+
}
59+
}
60+
61+
static void load_env() {
62+
auto here = fs::current_path();
63+
load_dotenv_if_present(here / ".env");
64+
if (fs::exists(here.parent_path())) {
65+
load_dotenv_if_present(here.parent_path() / ".env");
66+
}
67+
}
68+
69+
int main() {
70+
load_env();
71+
const char *key = getenv("PDFREST_API_KEY");
72+
if (!key || !*key) {
73+
std::cerr << "Missing PDFREST_API_KEY\n";
74+
return 1;
75+
}
76+
std::string base = getenv("PDFREST_URL") ? getenv("PDFREST_URL") : "https://api.pdfrest.com";
77+
base = rtrim_slashes(base);
78+
79+
cpr::Header hdr{{"Api-Key", key}, {"Accept", "application/json"}};
80+
cpr::Multipart mp{
81+
{"page_size", "letter"},
82+
{"page_count", "3"},
83+
{"page_orientation", "portrait"}
84+
};
85+
86+
auto res = cpr::Post(cpr::Url{base + "/blank-pdf"}, hdr, mp);
87+
if (res.error || res.status_code < 200 || res.status_code >= 300) {
88+
std::cerr << "blank-pdf failed (" << res.status_code << ")\n"
89+
<< res.error.message << "\n" << res.text << "\n";
90+
return 1;
91+
}
92+
std::cout << res.text << "\n";
93+
return 0;
94+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* What this sample does:
3+
* - Requests a new blank PDF using the JSON payload route.
4+
*
5+
* Setup (environment):
6+
* - Copy .env.example to .env
7+
* - Set PDFREST_API_KEY=your_api_key_here
8+
* - Optional: set PDFREST_URL to override the API region. For EU/GDPR compliance and proximity, use:
9+
* PDFREST_URL=https://eu-api.pdfrest.com
10+
* For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
11+
*
12+
* Usage:
13+
* dotnet run -- blank-pdf
14+
*
15+
* Output:
16+
* - Prints JSON response for the generated blank document.
17+
*/
18+
using Newtonsoft.Json.Linq;
19+
using System.Text;
20+
21+
namespace Samples.EndpointExamples.JsonPayload
22+
{
23+
public static class BlankPdf
24+
{
25+
public static async Task Execute(string[] args)
26+
{
27+
var apiKey = Environment.GetEnvironmentVariable("PDFREST_API_KEY");
28+
if (string.IsNullOrWhiteSpace(apiKey))
29+
{
30+
Console.Error.WriteLine("Missing required environment variable: PDFREST_API_KEY");
31+
Environment.Exit(1);
32+
return;
33+
}
34+
35+
var baseUrl = Environment.GetEnvironmentVariable("PDFREST_URL") ?? "https://api.pdfrest.com";
36+
37+
using (var httpClient = new HttpClient { BaseAddress = new Uri(baseUrl) })
38+
using (var request = new HttpRequestMessage(HttpMethod.Post, "blank-pdf"))
39+
{
40+
request.Headers.TryAddWithoutValidation("Api-Key", apiKey);
41+
request.Headers.Accept.Add(new("application/json"));
42+
43+
var payload = new JObject
44+
{
45+
["page_size"] = "letter",
46+
["page_count"] = 3,
47+
["page_orientation"] = "portrait"
48+
};
49+
50+
request.Content = new StringContent(payload.ToString(), Encoding.UTF8, "application/json");
51+
52+
var response = await httpClient.SendAsync(request);
53+
var result = await response.Content.ReadAsStringAsync();
54+
55+
Console.WriteLine("Blank PDF response received.");
56+
Console.WriteLine(result);
57+
58+
if (!response.IsSuccessStatusCode)
59+
{
60+
Environment.ExitCode = 1;
61+
}
62+
}
63+
}
64+
}
65+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* What this sample does:
3+
* - Calls /blank-pdf via multipart/form-data to create a three-page blank PDF.
4+
* - Routed from Program.cs as: `dotnet run -- blank-pdf-multipart`.
5+
*
6+
* Setup (environment):
7+
* - Copy .env.example to .env
8+
* - Set PDFREST_API_KEY=your_api_key_here
9+
* - Optional: set PDFREST_URL to override the API region. For EU/GDPR compliance and proximity, use:
10+
* PDFREST_URL=https://eu-api.pdfrest.com
11+
* For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
12+
*
13+
* Usage:
14+
* dotnet run -- blank-pdf-multipart
15+
*
16+
* Output:
17+
* - Prints the JSON response. Validation errors (args/env) exit non-zero.
18+
*/
19+
20+
namespace Samples.EndpointExamples.MultipartPayload
21+
{
22+
public static class BlankPdf
23+
{
24+
public static async Task Execute(string[] args)
25+
{
26+
var apiKey = Environment.GetEnvironmentVariable("PDFREST_API_KEY");
27+
if (string.IsNullOrWhiteSpace(apiKey))
28+
{
29+
Console.Error.WriteLine("Missing required environment variable: PDFREST_API_KEY");
30+
Environment.Exit(1);
31+
return;
32+
}
33+
34+
var baseUrl = Environment.GetEnvironmentVariable("PDFREST_URL") ?? "https://api.pdfrest.com";
35+
36+
using (var httpClient = new HttpClient { BaseAddress = new Uri(baseUrl) })
37+
using (var request = new HttpRequestMessage(HttpMethod.Post, "blank-pdf"))
38+
{
39+
request.Headers.TryAddWithoutValidation("Api-Key", apiKey);
40+
request.Headers.Accept.Add(new("application/json"));
41+
42+
var multipartContent = new MultipartFormDataContent
43+
{
44+
{ new StringContent("letter"), "page_size" },
45+
{ new StringContent("3"), "page_count" },
46+
{ new StringContent("portrait"), "page_orientation" }
47+
};
48+
49+
request.Content = multipartContent;
50+
var response = await httpClient.SendAsync(request);
51+
var apiResult = await response.Content.ReadAsStringAsync();
52+
53+
Console.WriteLine("blank-pdf response received.");
54+
Console.WriteLine(apiResult);
55+
56+
if (!response.IsSuccessStatusCode)
57+
{
58+
Environment.ExitCode = 1;
59+
}
60+
}
61+
}
62+
}
63+
}

DotNET/Program.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static void PrintUsage()
4646
Console.Error.WriteLine(" pdf-with-redacted-text-preview <pdf> Preview redactions");
4747
Console.Error.WriteLine(" pdf-with-redacted-text-applied <pdf> Apply redactions");
4848
Console.Error.WriteLine(" Page / Files:");
49+
Console.Error.WriteLine(" blank-pdf Generate an empty PDF");
4950
Console.Error.WriteLine(" split-pdf <pdf> Split by page ranges");
5051
Console.Error.WriteLine(" merged-pdf <pdf1> <pdf2> Merge two PDFs by id");
5152
Console.Error.WriteLine(" Resources / Packaging / Signing:");
@@ -95,6 +96,7 @@ static void PrintUsage()
9596
Console.Error.WriteLine(" pdf-with-redacted-text-preview-multipart <pdf> Preview redactions");
9697
Console.Error.WriteLine(" pdf-with-redacted-text-applied-multipart <pdf> Apply redactions");
9798
Console.Error.WriteLine(" Page / Files:");
99+
Console.Error.WriteLine(" blank-pdf-multipart Generate an empty PDF");
98100
Console.Error.WriteLine(" split-pdf-multipart <pdf> Split by page ranges");
99101
Console.Error.WriteLine(" merged-pdf-multipart <f1> <f2> Merge two files");
100102
Console.Error.WriteLine(" Resources / Packaging / Signing:");
@@ -149,6 +151,9 @@ static void PrintUsage()
149151
case "rasterized-pdf":
150152
await Samples.EndpointExamples.JsonPayload.RasterizedPdf.Execute(rest);
151153
break;
154+
case "blank-pdf":
155+
await Samples.EndpointExamples.JsonPayload.BlankPdf.Execute(rest);
156+
break;
152157
case "pdf-multipart":
153158
await Samples.EndpointExamples.MultipartPayload.Pdf.Execute(rest);
154159
break;
@@ -306,6 +311,9 @@ static void PrintUsage()
306311
case "rasterized-pdf-multipart":
307312
await Samples.EndpointExamples.MultipartPayload.RasterizedPdf.Execute(rest);
308313
break;
314+
case "blank-pdf-multipart":
315+
await Samples.EndpointExamples.MultipartPayload.BlankPdf.Execute(rest);
316+
break;
309317
case "compressed-pdf":
310318
await Samples.EndpointExamples.JsonPayload.CompressedPdf.Execute(rest);
311319
break;

0 commit comments

Comments
 (0)