Print PDFs - C++ Sample Code

Sample code for using Apryse SDK to print a PDF file using the currently selected default printer; provided in Python, C++, C#, Java, Node.js (JavaScript), PHP, Ruby, Go and VB. It is possible to use this printing functionality in both client and server applications without dependence on any third party components. Learn more about our Server SDK.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2021 by PDFTron Systems 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/Print.h> // new Print API
9#include <iostream>
10#include "../../LicenseKey/CPP/LicenseKey.h"
11
12using namespace std;
13using namespace pdftron;
14using namespace PDF;
15
16
17/**
18 * The following sample is a simplest C/C++ program used to illustrate how to print
19 * PDF document using currently selected default printer. In this sample, PDF::Print class
20 * is used to send data to the printer.
21 *
22 * Following this function is the more complex way of using PDFDraw directly.
23 *
24 * The first example uses the new PDF::Print::StartPrintJob function to send a rasterization
25 * of the document with optimal compression to the printer. If the OS is Windows 7, then the
26 * XPS print path will be used to preserve vector quality.
27 *
28 * The second example uses PDFDraw send unoptimized rasterized data via the print path.
29 *
30 * If you would like to rasterize page at high resolutions (e.g. more than 600 DPI), you
31 * should use PDFRasterizer or PDFNet vector output instead of PDFDraw.
32 */
33int main()
34{
35 PDFNet::Initialize(LicenseKey);
36 try
37 {
38 // Relative path to the folder containing test files.
39 string input_path = "../../TestFiles/";
40 PDFDoc doc((input_path + "tiger.pdf").c_str());
41 doc.InitSecurityHandler();
42
43 // Set our PrinterMode options
44 PrinterMode printerMode;
45 printerMode.SetCollation(true);
46 printerMode.SetCopyCount(1);
47 printerMode.SetDPI(600); // regardless of ordering, an explicit DPI setting overrides the OutputQuality setting
48 printerMode.SetDuplexing(PrinterMode::e_Duplex_Auto);
49
50 // If the XPS print path is being used, then the printer spooler file will
51 // ignore the grayscale option and be in full color
52 printerMode.SetOutputColor(PrinterMode::e_OutputColor_Grayscale);
53 printerMode.SetOutputQuality(PrinterMode::e_OutputQuality_Medium);
54 // printerMode.SetNUp(2,1);
55 // printerMode.SetScaleType(PrinterMode::e_ScaleType_FitToOutputPage);
56
57 // Print the PDF document to the default printer, using "tiger.pdf" as the document
58 // name, send the file to the printer not to an output file, print all pages, set the printerMode
59 // and don't provide a cancel flag.
60 Print::StartPrintJob(doc, UString(""), doc.GetFileName(), UString(""), NULL, &printerMode, NULL );
61 }
62 catch(Common::Exception& e)
63 {
64 std::cout << e << std::endl;
65 }
66 catch(...)
67 {
68 std::cout << "Unknown Exception" << std::endl;
69 }
70
71 PDFNet::Terminate (); // Done with PDFNet related stuff --------------------
72
73 return 0;
74}
75
76
77
78
79//////////////////////////////////////////////////////////////////////////
80// The second example uses PDFDraw send unoptimized rasterized data via the print path.
81//////////////////////////////////////////////////////////////////////////
82#include <PDF/PDFDraw.h> // only needed for more complex example
83#if defined(_WIN32) && !defined(__WINRT__)
84#include <windows.h>
85#include <windef.h>
86#include <wingdi.h>
87
88// Return HDC for the default printer
89HDC GetDefaultPrinterDC(void);
90
91int PrintUsingPDFDraw ()
92{
93 PRINTDLG pd;
94
95 pd.lStructSize = sizeof(pd);
96 pd.hDevMode = NULL;
97 pd.hDevNames = NULL;
98 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC | PD_HIDEPRINTTOFILE | PD_NOSELECTION | PD_NOPAGENUMS;
99 pd.nCopies = 1;
100 pd.nFromPage = 0xFFFF;
101 pd.nToPage = 0xFFFF;
102 pd.nMinPage = 1;
103 pd.nMaxPage = 0xFFFF;
104 pd.hDC = GetDefaultPrinterDC();
105
106 DOCINFOA docinfo;
107 memset(&docinfo, 0, sizeof(DOCINFO));
108 docinfo.cbSize = sizeof(docinfo);
109 docinfo.lpszDocName = "My Test";
110 docinfo.fwType = 0;
111 docinfo.lpszDatatype = (LPSTR) 0;
112 docinfo.lpszOutput = (LPSTR)0;
113
114 int nError = StartDocA(pd.hDC, &docinfo);
115 if(nError == SP_ERROR) {
116 MessageBoxA(NULL, "Error", "Error, Printing", MB_OK | MB_ICONEXCLAMATION);
117 return 1;
118 }
119
120 // Start with PDFNew related stuff -----------------------
121 PDFNet::Initialize();
122 try
123 {
124 // Relative path to the folder containing test files.
125 string input_path = "../../TestFiles/";
126 PDFDoc doc((input_path + "tiger.pdf").c_str());
127 doc.InitSecurityHandler();
128
129 PDFDraw pdfdraw;
130
131 pdfdraw.SetRasterizerType(PDFRasterizer::e_BuiltIn);
132
133 // Note: If you would like to rasterize page at high resolutions (e.g. more
134 // than 600 DPI), you should use PDFRasterizer.
135 pdfdraw.SetDPI(200); // Set DPI (Dots Per Inch).
136 pdfdraw.SetPrintMode(true);
137
138 for (PageIterator itr = doc.GetPageIterator(); itr.HasNext(); itr.Next())
139 {
140 nError = StartPage(pd.hDC);
141 if(nError == SP_ERROR) {
142 MessageBoxA(NULL, "Error", "Error, Printing", MB_OK | MB_ICONEXCLAMATION);
143 AbortDoc(pd.hDC);
144 return 1;
145 }
146
147 // Obtain the size of printer page (in pixels).
148 PDF::Rect r;
149 bool use_physical_page = false;
150 if (use_physical_page){
151 // Use the physical page for printing. Note: the physical page is almost always
152 // greater than the printable area of the page, and never smaller.
153 r.x1 = -GetDeviceCaps(pd.hDC, PHYSICALOFFSETX);
154 r.y1 = -GetDeviceCaps(pd.hDC, PHYSICALOFFSETY);
155 r.x2 = GetDeviceCaps(pd.hDC, PHYSICALWIDTH) - GetDeviceCaps(pd.hDC, PHYSICALOFFSETX);
156 r.y2 = GetDeviceCaps(pd.hDC, PHYSICALHEIGHT) - GetDeviceCaps(pd.hDC, PHYSICALOFFSETY);
157 }
158 else { // use the printable area of the page for printing.
159 r.x1 = r.y1 = 0;
160 r.x2 = GetDeviceCaps(pd.hDC, PHYSICALWIDTH) - GetDeviceCaps(pd.hDC, PHYSICALOFFSETX) * 2;
161 r.y2 = GetDeviceCaps(pd.hDC, PHYSICALHEIGHT) - GetDeviceCaps(pd.hDC, PHYSICALOFFSETY) * 2;
162 }
163
164 // Convert page rectangle dimensions to points. One PDF point is 1/72 of an inch.
165 // LOGPIXELSX/Y returns number of pixels per logical inch along the screen width/height.
166 double conv_x2pts = 72.0/GetDeviceCaps(pd.hDC, LOGPIXELSX);
167 double conv_y2pts = 72.0/GetDeviceCaps(pd.hDC, LOGPIXELSY);
168 r.x1 *= conv_x2pts; r.y1 *= conv_y2pts;
169 r.x2 *= conv_x2pts; r.y2 *= conv_y2pts;
170
171 pdfdraw.DrawInRect(itr.Current(), pd.hDC, r); // Print the page
172 EndPage(pd.hDC);
173 }
174 }
175 catch(Common::Exception& e)
176 {
177 std::cout << e << std::endl;
178 }
179 catch(...)
180 {
181 std::cout << "Unknown Exception" << std::endl;
182 }
183
184 PDFNet::Terminate (); // Done with PDFNet related stuff --------------------
185
186 EndDoc(pd.hDC);
187 DeleteDC(pd.hDC);
188
189 return 0;
190}
191
192HDC GetDefaultPrinterDC(void)
193{
194 char szPrinter[80];
195 char *szDevice, *szDriver, *szOutput;
196
197 GetProfileStringA("WINDOWS", "DEVICE", ",,,", szPrinter, 80);
198
199 szDevice = strtok(szPrinter, ",");
200 szDriver = strtok(NULL, ",");
201 szOutput = strtok(NULL, ",");
202
203 if ( !szDevice || !szDriver || !szOutput )
204 return 0;
205 else
206 return CreateDCA( szDriver, szDevice, szOutput, NULL );
207
208 return 0;
209}
210#endif //_WIN32

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales