1# Printing Files (C/C++) 2 3<!--Kit: Basic Services Kit--> 4<!--Subsystem: Print--> 5<!--Owner: @guoshengbang--> 6<!--Designer: @gcw_4D6e0BBd--> 7<!--Tester: @guoshengbang--> 8<!--Adviser: @RayShih--> 9 10The OS provides two printing methods: 11 12[Method 1](#3-method-1-starting-the-print-preview-page-to-send-print-jobs): An application calls an API to start the system print preview page and sends a print job for the rendered PDF file to a printer. This method is suitable for applications that need to quickly print files using system capabilities. 13 14[Method 2](#4-method-2-discovering-and-connecting-to-printers-to-send-print-jobs): An application calls the print APIs to discover and connect to printers and sends print jobs. This method is suitable for applications that have their own print preview pages. The applications can discover printers, obtain the printer capabilities, and construct a print job. 15 16> **NOTE** 17> 18> To use the print service, declare the ohos.permission.PRINT permission. For details, see [Declaring Permissions](../../security/AccessToken/declare-permissions.md). 19> 20> When the print service is no longer used, call **OH_Print_Release()** to release the print client resources and cancel event subscription. 21 22 23 24## How to Develop 25 26### 1. Including header files. 27 28```c++ 29#include <cstdint> 30#include <cstdio> 31#include <cwchar> 32#include <vector> 33#include <string> 34#include "hilog/log.h" 35#include "napi/native_api.h" 36#include "BasicServicesKit/ohprint.h" 37``` 38 39### 2. Adding dynamic link libraries to the CMake script. 40 41```txt 42target_link_libraries(entry PUBLIC 43 libace_napi.z.so 44 libhilog_ndk.z.so 45 libohprint.so 46) 47``` 48 49### 3. Method 1: Starting the print preview page to send print jobs. 50 51```ts 52import { Context } from '@kit.AbilityKit'; 53 54@Entry 55@Component 56struct Index { 57 build() { 58 Button("call native") 59 .onClick(() => { 60 let ctx = this.getUIContext().getHostContext();; // Obtain the context of the ability. 61 if (ctx === undefined) { 62 console.error('get fileUri or context failed'); 63 return; 64 } 65 getContext(ctx); // Pass the context to the C++ side. 66 }); 67 } 68} 69``` 70 71```c++ 72// Send the print task to the printer through system. 73static void* context; 74static char* currentJobId; 75 76// Initialize the print service. 77Print_ErrorCode ret = OH_Print_Init(); 78 79static napi_value getContext(napi_env env, napi_callback_info info) 80{ 81 size_t argc = 1; 82 napi_value argv[1] = {nullptr}; 83 // Assume that napi_get_cb_info is returned properly. 84 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 85 // Save the context for future use. 86 napi_status ret = napi_unwrap(env, argv[0], &context); 87 return nullptr; 88} 89 90// Invoke the callback of the system print preview page when the page is started for the first time or the user changes the print parameters. 91static void StartLayoutWriteCb(const char *jobId, 92 uint32_t fd, 93 const Print_PrintAttributes *oldAttrs, 94 const Print_PrintAttributes *newAttrs, 95 Print_WriteResultCallback writeCallback) 96{ 97 // Cache the unique task ID. 98 currentJobId = jobId; 99 // Implement WriteFile() to obtain the print parameters before and after modification, render the file to be printed, and write data using a fd, for example, color mode or page number. 100 uint32_t retCode = WriteFile(fd, oldAttrs, newAttrs); 101 // Notify the system that the file has been written. 102 writeCallback(jobId, retCode); 103} 104 105// After the file is written, the system displays the print preview page. You can click Print to send the print job. 106// Callback used to listen for the print job state changes based on the task ID. 107static void JobStateChangedCb(const char *jobId, uint32_t state) 108{ 109 // Logic for managing the print job state based on the task ID. 110} 111 112// Call the print API to display the print preview page. 113char printJobName[] = "fileName"; 114Print_PrintDocCallback printDocCallback = { StartLayoutWriteCb, JobStateChangedCb }; 115Print_ErrorCode ret = OH_Print_StartPrintByNative(printJobName, printDocCallback, context); 116 117// Release resources when the print service is no longer used. 118OH_Print_Release() 119``` 120 121### 4. Method 2: Discovering and connecting to printers to send print jobs. 122 123```c++ 124// Initialize the print service. 125Print_ErrorCode ret = OH_Print_Init(); 126 127// Register the callback for the printer discovery event and start discovering printers. 128static void PrinterDiscoveryCallback(Print_DiscoveryEvent event, const Print_PrinterInfo *printerInfo) 129{ 130 // Discover a printer. The device ID is used as the unique identifier. 131 if (printerInfo == nullptr) { 132 OH_LOG_Print(LOG_APP, LOG_INFO, 0, "print c/c++", "printerInfo is nullptr"); 133 return; 134 } 135 // Implement the following callback logic based on the specific service scenario. 136 switch (event) { 137 // An event indicating that a printer is discovered. 138 case PRINTER_DISCOVERED: 139 OnPrinterDiscovered(printerInfo); 140 break; 141 // An event indicating that a printer is lost. 142 case PRINTER_LOST: 143 OnPrinterLost(printerInfo); 144 break; 145 // An event indicating that a printer is connecting, which is triggered by OH_Print_ConnectPrinter. 146 case PRINTER_CONNECTING: 147 OnPrinterConnecting(printerInfo); 148 break; 149 // An event indicating that a printer is connected, which is triggered by OH_Print_ConnectPrinter. 150 case PRINTER_CONNECTED: 151 OnPrinterConnected(printerInfo); 152 break; 153 default: 154 break; 155 } 156} 157Print_PrinterDiscoveryCallback callback = PrinterDiscoveryCallback; 158Print_ErrorCode ret = OH_Print_StartPrinterDiscovery(callback); 159 160// Obtain the printer properties through PrinterDiscoveryCallback and connect to the printer based on the printer ID. 161// After the connection is successful, the PRINTER_CONNECTED event is received. 162Print_ErrorCode ret = OH_Print_ConnectPrinter(printerInfo->printerId); 163 164// Stop device discovery when this feature is not required. 165Print_ErrorCode ret = OH_Print_StopPrinterDiscovery(); 166 167// Obtain the added printer list. 168Print_StringList addedPrinterList = {0}; 169Print_ErrorCode ret = OH_Print_QueryPrinterList(&addedPrinterList); 170for (uint32_t index = 0; index < addedPrinterList.count; index++) { 171 Print_PrinterInfo *printerInfo = nullptr; 172 // Obtain the printer properties using the name of an added printer. 173 ret = OH_Print_QueryPrinterInfo(addedPrinterList[index], &printerInfo); 174 // Service code. 175 // Release resources after the printer properties are used. 176 OH_Print_ReleasePrinterInfo(printerInfo); 177} 178// Release the added printer list. 179OH_Print_ReleasePrinterList(&addedPrinterList); 180 181// Send a print job. 182// This example uses printerInfo->defaultValue as the print job parameter to send the task. 183std::vector<uint32_t> fdList = { 44, 45 }; 184Print_PrintJob* printJob = new Print_PrintJob{ jobName, 185 fdList.data(), 186 static_cast<uint32_t>(fdList.size()), 187 printerInfo->printerId, 188 1, // Number of copies. 189 printerInfo->defaultValue.defaultPaperSource, 190 printerInfo->defaultValue.defaultMediaType, 191 printerInfo->defaultValue.defaultPageSizeId, 192 printerInfo->defaultValue.defaultColorMode, 193 printerInfo->defaultValue.defaultDuplexMode, 194 printerInfo->defaultValue.defaultResolution, 195 printerInfo->defaultValue.defaultMargin, 196 true, 197 printerInfo->defaultValue.defaultOrientation, 198 printerInfo->defaultValue.defaultPrintQuality, 199 DOCUMENT_FORMAT_PDF, 200 printerInfo->defaultValue.otherDefaultValues, }; 201Print_ErrorCode ret = OH_Print_StartPrintJob(printJob); 202delete printJob; 203 204// Release resources when the print service is no longer used. 205OH_Print_Release() 206``` 207