cpdf_document.dart 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
  2. //
  3. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  4. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  5. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  6. // This notice may not be removed from this file.
  7. import 'package:compdfkit_flutter/configuration/cpdf_options.dart';
  8. import 'package:compdfkit_flutter/document/cpdf_watermark.dart';
  9. import 'package:flutter/services.dart';
  10. import 'package:flutter/widgets.dart';
  11. /// A class to handle PDF documents without using [CPDFReaderWidget]
  12. ///
  13. /// example:
  14. /// ```dart
  15. /// var document = CPDFDocument();
  16. /// document.open('pdf file path', 'password');
  17. ///
  18. /// /// get pdf document info.
  19. /// var info = await document.getInfo();
  20. ///
  21. /// /// get pdf document file name.
  22. /// var fileName = await document.getFileName();
  23. /// ```
  24. class CPDFDocument {
  25. late final MethodChannel _channel;
  26. bool _isValid = false;
  27. get isValid => _isValid;
  28. CPDFDocument.withController(int viewId)
  29. : _channel = MethodChannel('com.compdfkit.flutter.document_$viewId'),
  30. _isValid = true;
  31. Future<bool> open(String filePath, String password) async {
  32. return await _channel.invokeMethod(
  33. 'open_document', {'filePath': filePath, 'password': password});
  34. }
  35. /// Gets the file name of the PDF document.
  36. ///
  37. /// example:
  38. /// ```dart
  39. /// var fileName = await document.getFileName();
  40. /// ```
  41. Future<String> getFileName() async {
  42. return await _channel.invokeMethod('get_file_name');
  43. }
  44. /// Checks if the PDF document is encrypted.
  45. ///
  46. /// example:
  47. /// ```dart
  48. /// var isEncrypted = await document.isEncrypted();
  49. /// ```
  50. Future<bool> isEncrypted() async {
  51. return await _channel.invokeMethod('is_encrypted');
  52. }
  53. /// Checks if the PDF document is an image document.
  54. /// This is a time-consuming operation that depends on the document size.
  55. ///
  56. /// example:
  57. /// ```dart
  58. /// var isImageDoc = await document.isImageDoc();
  59. /// ```
  60. Future<bool> isImageDoc() async {
  61. return await _channel.invokeMethod('is_image_doc');
  62. }
  63. /// Gets the current document's permissions. There are three types of permissions:
  64. /// No restrictions: [CPDFDocumentPermissions.none]
  65. /// If the document has an open password and an owner password,
  66. /// using the open password will grant [CPDFDocumentPermissions.user] permissions,
  67. /// and using the owner password will grant [CPDFDocumentPermissions.owner] permissions.
  68. ///
  69. /// example:
  70. /// ```dart
  71. /// var permissions = await document.getPermissions();
  72. /// ```
  73. Future<CPDFDocumentPermissions> getPermissions() async {
  74. int permissionId = await _channel.invokeMethod('get_permissions');
  75. return CPDFDocumentPermissions.values[permissionId];
  76. }
  77. /// Check if owner permissions are unlocked
  78. ///
  79. /// example:
  80. /// ```dart
  81. /// var isUnlocked = await document.checkOwnerUnlocked();
  82. /// ```
  83. Future<bool> checkOwnerUnlocked() async {
  84. return await _channel.invokeMethod('check_owner_unlocked');
  85. }
  86. /// Whether the owner password is correct.
  87. ///
  88. /// example:
  89. /// ```dart
  90. /// var isCorrect = await document.checkOwnerPassword('password');
  91. /// ```
  92. Future<bool> checkOwnerPassword(String password) async {
  93. return await _channel.invokeMethod('check_owner_password',
  94. {'password': password});
  95. }
  96. /// Check the document for modifications
  97. ///
  98. /// example:
  99. /// ```dart
  100. /// bool hasChange = await document.hasChange();
  101. /// ```
  102. Future<bool> hasChange() async {
  103. return await _channel.invokeMethod('has_change');
  104. }
  105. /// Imports annotations from the specified XFDF file into the current PDF document.
  106. ///
  107. /// **Parameters:**<br/>
  108. /// xfdfFile - Path of the XFDF file to be imported.
  109. ///
  110. /// **example:**
  111. /// ```dart
  112. /// bool result = await document.importAnnotations(xxx.xfdf);
  113. /// ```
  114. ///
  115. /// **Returns:**
  116. /// true if the import is successful; otherwise, false.
  117. Future<bool> importAnnotations(String xfdfFile) async {
  118. return await _channel.invokeMethod('import_annotations', xfdfFile);
  119. }
  120. /// Exports annotations from the current PDF document to an XFDF file.
  121. ///
  122. /// **example:**
  123. /// ```dart
  124. /// String xfdfPath = await document.exportAnnotations();
  125. /// ```
  126. ///
  127. /// Returns:
  128. /// The path of the XFDF file if export is successful; an empty string if the export fails.
  129. Future<String> exportAnnotations() async {
  130. return await _channel.invokeMethod('export_annotations');
  131. }
  132. /// Delete all comments in the current document
  133. ///
  134. /// example:
  135. /// ```dart
  136. /// bool result = await document.removeAllAnnotations();
  137. /// ```
  138. Future<bool> removeAllAnnotations() async {
  139. return await _channel.invokeMethod('remove_all_annotations');
  140. }
  141. /// Get the total number of pages in the current document
  142. ///
  143. /// example:
  144. /// ```dart
  145. /// int pageCount = await document.getPageCount();
  146. /// ```
  147. Future<int> getPageCount() async {
  148. return await _channel.invokeMethod('get_page_count');
  149. }
  150. /// Save document
  151. ///
  152. /// example:
  153. /// ```dart
  154. /// bool result = await _controller.save();
  155. /// ```
  156. /// Return value: **true** if the save is successful,
  157. /// **false** if the save fails.
  158. Future<bool> save() async {
  159. return await _channel.invokeMethod('save');
  160. }
  161. /// Saves the document to the specified directory.
  162. ///
  163. /// Example usage:
  164. /// ```dart
  165. /// await controller.document.saveAs('data/your_package_name/files/xxx.pdf')
  166. /// ```
  167. /// - [savePath] Specifies the path where the document should be saved.
  168. /// On Android, both file paths and URIs are supported. For example:
  169. /// - File path: `/data/user/0/com.compdfkit.flutter.example/cache/temp/PDF_Document.pdf`
  170. /// - URI: `content://media/external/file/1000045118`
  171. /// - [removeSecurity] Whether to remove the document's password.
  172. /// - [fontSubSet] Whether to embed the font subset when saving the PDF.
  173. /// This will affect how text appears in other PDF software. This is a time-consuming operation.
  174. Future<bool> saveAs(String savePath, {
  175. bool removeSecurity = false,
  176. bool fontSubSet = true
  177. }) async {
  178. try {
  179. return await _channel.invokeMethod('save_as', {
  180. 'save_path' : savePath,
  181. 'remove_security' : removeSecurity,
  182. 'font_sub_set' : fontSubSet
  183. });
  184. } on PlatformException catch (e) {
  185. debugPrint(e.details);
  186. return false;
  187. } catch (e) {
  188. return false;
  189. }
  190. }
  191. /// Invokes the system's print service to print the current document.
  192. ///
  193. /// example:
  194. /// ```dart
  195. /// await document.printDocument();
  196. /// ```
  197. Future<void> printDocument() async {
  198. await _channel.invokeMethod('print');
  199. }
  200. /// Remove the user password and owner permission password
  201. /// set in the document, and perform an incremental save.
  202. ///
  203. /// example:
  204. /// ```dart
  205. /// bool result = await document.removePassword();
  206. /// ```
  207. Future<bool> removePassword() async{
  208. try{
  209. return await _channel.invokeMethod('remove_password');
  210. } on PlatformException catch (e) {
  211. debugPrint(e.message);
  212. return false;
  213. }
  214. }
  215. /// This method sets the document password, including the user password for access restrictions
  216. /// and the owner password for granting permissions.
  217. ///
  218. /// - To enable permissions like printing or copying, the owner password must be set; otherwise,
  219. /// the settings will not take effect.
  220. ///
  221. /// example:
  222. /// ```dart
  223. /// bool result = controller.document.setPassword(
  224. /// userPassword : '1234',
  225. /// ownerPassword : '4321',
  226. /// allowsPrinting : false,
  227. /// allowsCopying : false,
  228. /// encryptAlgo = CPDFDocumentEncryptAlgo.rc4
  229. /// );
  230. /// ```
  231. Future<bool> setPassword({
  232. String? userPassword,
  233. String? ownerPassword,
  234. bool allowsPrinting = true,
  235. bool allowsCopying = true,
  236. CPDFDocumentEncryptAlgo encryptAlgo = CPDFDocumentEncryptAlgo.rc4
  237. }) async {
  238. try{
  239. return await _channel.invokeMethod('set_password', {
  240. 'user_password' : userPassword,
  241. 'owner_password' : ownerPassword,
  242. 'allows_printing' : allowsPrinting,
  243. 'allows_copying' : allowsCopying,
  244. 'encrypt_algo' : encryptAlgo.name
  245. });
  246. } on PlatformException catch (e) {
  247. debugPrint(e.message);
  248. return false;
  249. }
  250. }
  251. /// Get the encryption algorithm of the current document
  252. ///
  253. /// example:
  254. /// ```dart
  255. /// CPDFDocumentEncryptAlgo encryptAlgo = await controller.document.getEncryptAlgo();
  256. /// ```
  257. Future<CPDFDocumentEncryptAlgo> getEncryptAlgo() async {
  258. String encryptAlgoStr = await _channel.invokeMethod('get_encrypt_algorithm');
  259. return CPDFDocumentEncryptAlgo.values.where((e) => e.name == encryptAlgoStr).first;
  260. }
  261. /// Create document watermarks, including text watermarks and image watermarks
  262. ///
  263. /// - Add Text Watermark Example:
  264. /// ```dart
  265. /// await controller.document.createWatermark(CPDFWatermark.text(
  266. /// textContent: 'Flutter',
  267. /// scale: 1.0,
  268. /// fontSize: 50,
  269. /// textColor: Colors.deepOrange,
  270. /// pages: [0, 1, 2, 3,8,9]));
  271. /// ```
  272. ///
  273. /// - Add Image Watermark Example:
  274. /// ```dart
  275. /// File imageFile = await extractAsset(context, 'images/logo.png');
  276. /// await controller.document.createWatermark(CPDFWatermark.image(
  277. /// imagePath: imageFile.path,
  278. /// pages: [0, 1, 2, 3],
  279. /// horizontalSpacing: 50,
  280. /// verticalSpacing: 50,
  281. /// horizontalAlignment: CPDFWatermarkHorizontalAlignment.center,
  282. /// verticalAlignment: CPDFWatermarkVerticalAlignment.center,
  283. /// ));
  284. /// ```
  285. Future<bool> createWatermark(CPDFWatermark watermark) async {
  286. return await _channel.invokeMethod('create_watermark', watermark.toJson());
  287. }
  288. /// remove all watermark
  289. ///
  290. /// example:
  291. /// ```dart
  292. /// await controller.document.removeAllWatermarks();
  293. /// ```
  294. Future<void> removeAllWatermarks() async{
  295. return await _channel.invokeMethod('remove_all_watermarks');
  296. }
  297. }