Browse Source

compdfkit(rn) - 新增合并、拆分文档接口

liuxiaolong 1 week ago
parent
commit
854a0d8ca0

+ 35 - 0
android/src/main/java/com/compdfkitpdf/reactnative/modules/CPDFViewModule.java

@@ -20,6 +20,7 @@ import com.facebook.react.bridge.ReadableArray;
 import com.facebook.react.bridge.ReadableMap;
 import com.facebook.react.uimanager.UIBlock;
 import com.facebook.react.uimanager.UIManagerModule;
+import java.lang.reflect.Array;
 
 
 public class CPDFViewModule extends ReactContextBaseJavaModule {
@@ -418,6 +419,40 @@ public class CPDFViewModule extends ReactContextBaseJavaModule {
     uiBlock(nativeViewHierarchyManager -> promise.resolve(mPDFViewInstance.getDocumentPath(tag)));
   }
 
+  @ReactMethod
+  public void importDocument(int tag, ReadableMap array, Promise promise){
+    uiBlock(nativeViewHierarchyManager -> {
+      String filePath = array.getString("file_path");
+      String password = array.getString("password");
+      int insertPosition = array.getInt("insert_position");
+      ReadableArray pagesArray = array.getArray("pages");
+      int[] pages = new int[pagesArray.size()];
+      for (int i = 0; i < pagesArray.size(); i++) {
+        pages[i] = pagesArray.getInt(i);
+      }
+      mPDFViewInstance.importDocument(tag, filePath, password, pages, insertPosition, promise);
+    });
+  }
+
+  @ReactMethod
+  public void splitDocumentPages(int tag, ReadableMap array, Promise promise){
+    uiBlock(nativeViewHierarchyManager -> {
+      String savePath = array.getString("save_path");
+      ReadableArray pagesArray = array.getArray("pages");
+      int size = 0;
+      if (pagesArray != null){
+        size = pagesArray.size();
+      }
+      int[] pages = new int[size];
+      if (size >0){
+        for (int i = 0; i < size; i++) {
+          pages[i] = pagesArray.getInt(i);
+        }
+      }
+      mPDFViewInstance.splitDocumentPage(tag, savePath, pages, promise);
+    });
+  }
+
 
   private void uiBlock(UIBlock uiBlock) {
     UIManagerModule uiManager = getReactApplicationContext().getNativeModule(UIManagerModule.class);

+ 1 - 4
android/src/main/java/com/compdfkitpdf/reactnative/util/CPDFDocumentUtil.java

@@ -2,9 +2,6 @@ package com.compdfkitpdf.reactnative.util;
 
 import android.content.Context;
 import android.net.Uri;
-import android.util.Log;
-import com.compdfkit.core.utils.TFileUtils;
-import com.compdfkit.tools.common.pdf.CPDFDocumentActivity;
 import com.compdfkit.tools.common.utils.CFileUtils;
 import com.compdfkit.tools.common.utils.CUriUtil;
 import java.io.File;
@@ -23,7 +20,7 @@ public class CPDFDocumentUtil {
       return CFileUtils.getAssetsTempFile(context, assetsPath, fileName);
   }
 
-  public static String getImportAnnotationPath(Context context, String pathOrUri) {
+  public static String getImportFilePath(Context context, String pathOrUri) {
     if (pathOrUri.startsWith(ASSETS_SCHEME)) {
       String assetsPath = pathOrUri.replace(ASSETS_SCHEME + "/","");
       String[] strs = pathOrUri.split("/");

+ 77 - 8
android/src/main/java/com/compdfkitpdf/reactnative/viewmanager/CPDFViewManager.java

@@ -28,6 +28,7 @@ import androidx.fragment.app.FragmentActivity;
 import com.compdfkit.core.common.CPDFDocumentException;
 import com.compdfkit.core.document.CPDFDocument;
 import com.compdfkit.core.document.CPDFDocument.PDFDocumentEncryptAlgo;
+import com.compdfkit.core.document.CPDFDocument.PDFDocumentError;
 import com.compdfkit.core.document.CPDFDocument.PDFDocumentPermissions;
 import com.compdfkit.core.document.CPDFDocument.PDFDocumentSaveType;
 import com.compdfkit.core.document.CPDFDocumentPermissionInfo;
@@ -38,6 +39,7 @@ import com.compdfkit.tools.common.utils.CFileUtils;
 import com.compdfkit.tools.common.utils.print.CPDFPrintUtils;
 import com.compdfkit.tools.common.utils.threadpools.CThreadPoolUtils;
 import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
+import com.compdfkit.tools.common.views.pdfview.CPDFPageIndicatorView;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl.COnSaveCallback;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl.COnSaveError;
@@ -47,12 +49,10 @@ import com.compdfkitpdf.reactnative.util.CPDFDocumentUtil;
 import com.compdfkitpdf.reactnative.view.CPDFView;
 import com.facebook.react.bridge.Promise;
 import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.ReactMethod;
 import com.facebook.react.uimanager.ThemedReactContext;
 import com.facebook.react.uimanager.ViewGroupManager;
 import com.facebook.react.uimanager.annotations.ReactProp;
 import java.io.File;
-import java.util.Map;
 
 public class CPDFViewManager extends ViewGroupManager<CPDFView> {
 
@@ -169,7 +169,7 @@ public class CPDFViewManager extends ViewGroupManager<CPDFView> {
   }
 
   public boolean importAnnotations(int tag, String xfdfFilePath) throws Exception {
-    String xfdf = CPDFDocumentUtil.getImportAnnotationPath(reactContext, xfdfFilePath);
+    String xfdf = CPDFDocumentUtil.getImportFilePath(reactContext, xfdfFilePath);
     CPDFView pdfView = mDocumentViews.get(tag);
     CPDFReaderView readerView = pdfView.documentFragment.pdfView.getCPdfReaderView();
     CPDFDocument document = readerView.getPDFDocument();
@@ -466,7 +466,7 @@ public class CPDFViewManager extends ViewGroupManager<CPDFView> {
         } else {
           saveResult = document.saveAs(savePath, removeSecurity, false, fontSubSet);
         }
-        CThreadPoolUtils.getInstance().executeMain(()->{
+        CThreadPoolUtils.getInstance().executeMain(() -> {
           if (document.shouleReloadDocument()) {
             document.reload();
           }
@@ -581,7 +581,7 @@ public class CPDFViewManager extends ViewGroupManager<CPDFView> {
   }
 
   public boolean importWidgets(int tag, String xfdfFilePath) throws Exception {
-    String xfdf = CPDFDocumentUtil.getImportAnnotationPath(reactContext, xfdfFilePath);
+    String xfdf = CPDFDocumentUtil.getImportFilePath(reactContext, xfdfFilePath);
     CPDFView pdfView = mDocumentViews.get(tag);
     CPDFReaderView readerView = pdfView.documentFragment.pdfView.getCPdfReaderView();
     CPDFDocument document = readerView.getPDFDocument();
@@ -649,19 +649,88 @@ public class CPDFViewManager extends ViewGroupManager<CPDFView> {
         promise.reject("SAVE_FAIL", "Save failed.");
       }
     } catch (Exception e) {
-      if (e instanceof CPDFDocumentException){
+      if (e instanceof CPDFDocumentException) {
         promise.reject("SAVE_FAIL", ((CPDFDocumentException) e).getErrType().name());
-      }else {
+      } else {
         promise.reject("SAVE_FAIL", e.getMessage());
       }
     }
   }
 
-  public void reloadPages(int tag){
+  public void reloadPages(int tag) {
     CPDFView cpdfView = mDocumentViews.get(tag);
     cpdfView.getCPDFReaderView().reloadPages();
   }
 
+  public void importDocument(int tag, String filePath, String password, int[] pages,
+    int insertPosition, Promise promise) {
+    try {
+      CPDFView cpdfView = mDocumentViews.get(tag);
+      CPDFDocument document = cpdfView.getCPDFReaderView().getPDFDocument();
+
+      CPDFDocument importDocument = new CPDFDocument(reactContext);
+      String importDocumentPath = CPDFDocumentUtil.getImportFilePath(reactContext, filePath);
+      PDFDocumentError error = importDocument.open(importDocumentPath, password);
+      if (error != PDFDocumentError.PDFDocumentErrorSuccess) {
+        promise.reject("IMPORT_DOCUMENT_FAIL", "open import document fail, error:" + error.name());
+        return;
+      }
+      if (pages == null || pages.length == 0) {
+        int pageCount = importDocument.getPageCount();
+        pages = new int[pageCount];
+        for (int i = 0; i < pageCount; i++) {
+          pages[i] = i;
+        }
+      }
+      if (insertPosition == -1) {
+        insertPosition = document.getPageCount();
+      }
+      boolean importResult = document.importPages(importDocument, pages, insertPosition);
+      promise.resolve(importResult);
+      CPDFPageIndicatorView indicatorView = cpdfView.documentFragment.pdfView.indicatorView;
+      cpdfView.getCPDFReaderView().reloadPages();
+      indicatorView.setTotalPage(document.getPageCount());
+      indicatorView.setCurrentPageIndex(cpdfView.getCPDFReaderView().getPageNum());
+    } catch (Exception e) {
+      promise.reject("IMPORT_DOCUMENT_FAIL", "error:" + e.getMessage());
+    }
+  }
+
+
+  public void splitDocumentPage(int tag, String savePath, int[] pages, Promise promise) {
+    try {
+      CPDFView cpdfView = mDocumentViews.get(tag);
+      CPDFDocument document = cpdfView.getCPDFReaderView().getPDFDocument();
+      if (pages == null || pages.length == 0) {
+        int pageCount = document.getPageCount();
+        pages = new int[pageCount];
+        for (int i = 0; i < pageCount; i++) {
+          pages[i] = i;
+        }
+      }
+      int[] finalPages = pages;
+      CThreadPoolUtils.getInstance().executeIO(() -> {
+        try {
+          CPDFDocument newDocument = CPDFDocument.createDocument(reactContext);
+          newDocument.importPages(document, finalPages, 0);
+          boolean saveResult;
+          if (savePath.startsWith(CONTENT_SCHEME)) {
+            saveResult = newDocument.saveAs(Uri.parse(savePath), false, true);
+          } else {
+            saveResult = newDocument.saveAs(savePath, false, false, true);
+          }
+          promise.resolve(saveResult);
+          newDocument.close();
+        } catch (CPDFDocumentException e) {
+          promise.reject("SPLIT_DOCUMENT_FAIL", "error:" + e.getErrType().name());
+        }
+      });
+    } catch (Exception e) {
+      e.printStackTrace();
+      promise.reject("SPLIT_DOCUMENT_FAIL", "error:" + e.getMessage());
+    }
+  }
+
   public String getDocumentPath(int tag) {
     CPDFView pdfView = mDocumentViews.get(tag);
     CPDFReaderView readerView = pdfView.getCPDFReaderView();

File diff suppressed because it is too large
+ 8 - 0
example/App.tsx


+ 182 - 0
example/src/CPDFPagesExample.tsx

@@ -0,0 +1,182 @@
+/**
+ * Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+import React, { useState, useRef } from 'react';
+import { Image, Platform, StyleSheet, Text, View } from 'react-native';
+import { CPDFReaderView, ComPDFKit, CPDFToolbarAction, CPDFDocument } from '@compdfkit_pdf_sdk/react_native';
+import { useNavigation, useRoute, RouteProp } from '@react-navigation/native';
+import { HeaderBackButton } from '@react-navigation/elements';
+import { MenuProvider, Menu, MenuTrigger, MenuOptions, MenuOption } from 'react-native-popup-menu';
+import { SafeAreaView } from 'react-native-safe-area-context';
+import DocumentPicker from 'react-native-document-picker';
+import RNFS from 'react-native-fs';
+
+type RootStackParamList = {
+    CPDFReaderViewExample: { document?: string };
+};
+
+type CPDFPagesExampleScreenRouteProp = RouteProp<
+    RootStackParamList,
+    'CPDFReaderViewExample'
+>;
+
+const CPDFPagesExampleScreen = () => {
+
+    const pdfReaderRef = useRef<CPDFReaderView>(null);
+
+    const navigation = useNavigation();
+
+    const route = useRoute<CPDFPagesExampleScreenRouteProp>();
+
+    const [samplePDF] = useState(
+        route.params?.document || (Platform.OS === 'android'
+            ? 'file:///android_asset/PDF_Document.pdf'
+            : 'PDF_Document.pdf')
+    );
+
+    const handleSave = async () => {
+        if (pdfReaderRef.current) {
+            const success = await pdfReaderRef.current.save();
+            if (success) {
+                console.log('ComPDFKitRN save() : Document saved successfully');
+            } else {
+                console.log('ComPDFKitRN save() : Failed to save document');
+            }
+        }
+    };
+
+    const menuOptions = [
+        'Save',
+        'Import Document',
+        'Split Document'];
+
+    const handleMenuItemPress = async (action: string) => {
+        switch (action) {
+            case 'Save':
+                handleSave();
+                break;
+            case 'Import Document':
+                const pickerResult = DocumentPicker.pick({
+                    type: [DocumentPicker.types.pdf],
+                    copyTo: 'cachesDirectory'
+                });
+                pickerResult.then(async (res) => {
+                    const file = res[0];
+                    const path = file!!.fileCopyUri!!
+                    if (!path?.endsWith('pdf')) {
+                        console.log('ComPDFKitRN please select pdf format file');
+                        return;
+                    }
+                    const pages = [0];
+                    const insertPosition = 0;
+                    const importResult = await pdfReaderRef.current?._pdfDocument.importDocument(
+                        path,pages, insertPosition
+                    )
+                    console.log('ComPDFKitRN importDocument:', importResult);
+                })
+                break;
+            case 'Split Document':
+                // const uri = await ComPDFKit.createUri('split_document_test.pdf', '', 'application/pdf')
+                
+                const appCacheDirectory = RNFS.CachesDirectoryPath;
+                const savePath = appCacheDirectory + '/split_document_test.pdf';
+
+                const pages = [0];
+                const splitResult = await pdfReaderRef.current?._pdfDocument.splitDocumentPages(
+                    savePath, pages
+                )
+                console.log('ComPDFKitRN splitDocumentPages:', splitResult);
+                if(splitResult){
+                    console.log('ComPDFKitRN splitDocumentPages: Split document saved at:', savePath);
+                    await pdfReaderRef?.current?._pdfDocument.open(savePath);
+                }
+                break;
+            default:
+                break;
+        }
+    };
+
+    const handleBack = () => {
+        navigation.goBack();
+    };
+
+    const renderToolbar = () => {
+        return (
+            <View style={styles.toolbar}>
+                <HeaderBackButton onPress={handleBack} />
+                <Text style={styles.toolbarTitle}>Pages Example</Text>
+
+                <Menu>
+                    <MenuTrigger>
+                        <Image source={require('../assets/more.png')} style={{ width: 24, height: 24, marginEnd: 8 }} />
+                    </MenuTrigger>
+
+                    <MenuOptions>
+                        {menuOptions.map((option, index) => (
+                            <MenuOption key={index} onSelect={() => handleMenuItemPress(option)}>
+                                <Text style={styles.menuOption}>{option}</Text>
+                            </MenuOption>
+                        ))}
+                    </MenuOptions>
+                </Menu>
+            </View>
+        );
+    };
+
+    return (
+        <MenuProvider>
+            <SafeAreaView style={{ flex: 1 }}>
+                <View style={{ flex: 1 }}>
+                    {renderToolbar()}
+                    <CPDFReaderView
+                        ref={pdfReaderRef}
+                        document={samplePDF}
+                        configuration={ComPDFKit.getDefaultConfig({
+                            toolbarConfig: {
+                                iosLeftBarAvailableActions: [
+                                    CPDFToolbarAction.THUMBNAIL
+                                ]
+                            }
+                        })} />
+                </View>
+            </SafeAreaView>
+        </MenuProvider>
+    );
+};
+
+const styles = StyleSheet.create({
+    toolbar: {
+        height: 56,
+        flexDirection: 'row',
+        alignItems: 'center',
+        justifyContent: 'flex-start',
+        backgroundColor: '#FAFCFF',
+        paddingHorizontal: 4,
+    },
+    toolbarButton: {
+        padding: 8,
+    },
+    toolbarTitle: {
+        flex: 1,
+        color: 'black',
+        fontSize: 16,
+        fontWeight: 'bold',
+        marginStart: 8
+    },
+    menuOption: {
+        padding: 8,
+        fontSize: 14,
+        color: 'black',
+    },
+});
+
+export default CPDFPagesExampleScreen;
+
+
+

+ 8 - 0
example/src/examples.tsx

@@ -92,6 +92,14 @@ const uiConpomentExamples = [
             component.props.navigation.navigate('CPDFSecurityExample');
         }
     },
+    {
+        key: 'item8',
+        title: 'Pages Example',
+        description: 'This example demonstrates PDF page related operations, such as inserting and splitting PDF documents.',
+        action: (component: any)  => {
+            component.props.navigation.navigate('CPDFPagesExample');
+        }
+    },
 ];
 
 export const examples = [

+ 5 - 0
src/annotation/CPDFAnnotation.tsx

@@ -0,0 +1,5 @@
+import { CPDFAnnotationType } from "../configuration/CPDFOptions";
+
+abstract class CPDFAnnotation{
+
+}

+ 120 - 27
src/view/CPDFDocument.tsx

@@ -1,3 +1,12 @@
+/**
+ * Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
 import { NativeModules, findNodeHandle } from 'react-native';
 import { CPDFDocumentEncryptAlgo, CPDFDocumentPermissions } from '../configuration/CPDFOptions';
 const { CPDFViewManager } = NativeModules;
@@ -10,6 +19,15 @@ export class CPDFDocument {
         this._viewerRef = viewerRef;
     }
 
+    /**
+     * Get the page object at the specified index
+     * @param pageIndex The index of the page to retrieve
+     * @returns The page object at the specified index
+     */
+    pageAtIndex = (pageIndex : number) : CPDFPage  => {
+        return new CPDFPage(pageIndex);
+    }
+
     /**
      * Reopens a specified document in the current `CPDFReaderView` component.
      *
@@ -376,16 +394,16 @@ export class CPDFDocument {
      * const result = await pdfReaderRef.current?._pdfDocument.flattenAllPages(savePath, fontSubset);
      * @returns Returns the save path of the current document.
      */
-    // flattenAllPages = (savePath : string, fontSubset : boolean) : Promise<string> => {
-    //     const tag = findNodeHandle(this._viewerRef);
-    //     if (tag != null) {
-    //         return CPDFViewManager.flattenAllPages(tag, {
-    //             'save_path': savePath,
-    //             'font_sub_set': fontSubset
-    //         });
-    //     }
-    //     return Promise.reject(new Error('Unable to find the native view reference'));
-    // }
+    flattenAllPages = (savePath : string, fontSubset : boolean) : Promise<string> => {
+        const tag = findNodeHandle(this._viewerRef);
+        if (tag != null) {
+            return CPDFViewManager.flattenAllPages(tag, {
+                'save_path': savePath,
+                'font_sub_set': fontSubset
+            });
+        }
+        return Promise.reject('Unable to find the native view reference');
+    }
 
     /**
      * Saves the document to the specified directory.
@@ -403,31 +421,105 @@ export class CPDFDocument {
      * @param fontSubset
      * @returns Whether to embed the font subset when saving the PDF.
      */
-    // saveAs = (savePath : string, removeSecurity : boolean, fontSubset : boolean) : Promise<string> => {
-    //     const tag = findNodeHandle(this._viewerRef);
-    //     if (tag != null) {
-    //         return CPDFViewManager.saveAs(tag, {
-    //             'save_path': savePath,
-    //             'remove_security': removeSecurity,
-    //             'font_sub_set': fontSubset
-    //         });
-    //     }
-    //     return Promise.reject(new Error('Unable to find the native view reference'));
-    // }
+    saveAs = (savePath : string, removeSecurity : boolean, fontSubset : boolean) : Promise<string> => {
+        const tag = findNodeHandle(this._viewerRef);
+        if (tag != null) {
+            return CPDFViewManager.saveAs(tag, {
+                'save_path': savePath,
+                'remove_security': removeSecurity,
+                'font_sub_set': fontSubset
+            });
+        }
+        return Promise.reject('Unable to find the native view reference');
+    }
+
+    /**
+     * Imports another PDF document and inserts it at a specified position in the current document.
+     *
+     * This method imports an external PDF document into the current document, allowing you to choose which pages to import and where to insert the document.
+     *
+     * @example
+     * const filePath = '/data/user/0/com.compdfkit.flutter.example/cache/temp/PDF_Document.pdf';
+     * const pages = [0]; // The pages to import from the document
+     * const insertPosition = 0; // The position to insert, 0 means insert at the beginning of the document
+     * const password = ''; // The password for the document, if encrypted
+     * const importResult = await pdfReaderRef.current?._pdfDocument.importDocument(filePath, pages, insertPosition, password);
+     *
+     * @param filePath The path of the PDF document to import. Must be a valid, accessible path on the device.
+     * @param pages The collection of pages to import, represented as an array of integers. If `null` or an empty array is passed, the entire document will be imported.
+     * @param insertPosition The position to insert the external document into the current document. This value must be provided. If not specified, the document will be inserted at the end of the current document.
+     * @param password The password for the document, if it is encrypted. If the document is not encrypted, an empty string `''` can be passed.
+     *
+     * @returns Returns a `Promise<boolean>` indicating whether the document import was successful.
+     * - `true` indicates success
+     * - `false` or an error indicates failure
+     *
+     * @throws If the native view reference cannot be found, the promise will be rejected with an error.
+     */
+    importDocument = (
+        filePath : string,
+        pages: Array<number> | null = [],
+        insertPosition: number = -1,
+        password : string | null = '',
+    ) : Promise<boolean> => {
+        const tag = findNodeHandle(this._viewerRef);
+        if (tag != null) {
+            return CPDFViewManager.importDocument(tag, {
+                'file_path' : filePath,
+                'password' : password,
+                'pages': pages,
+                'insert_position' : insertPosition
+            });
+        }
+        return Promise.reject(new Error('Unable to find the native view reference'));
+    }
+
+    /**
+     * Splits the specified pages from the current document and saves them as a new document.
+     *
+     * This function extracts the given pages from the current PDF document and saves them as a
+     * new document at the provided save path.
+     *
+     * @example
+     * const savePath = '/path/to/save/new_document.pdf';
+     * const pages = [0, 2, 4]; // Pages to extract from the current document
+     * const result = await pdfReaderRef.current?.splitDocumentPages(savePath, pages);
+     *
+     * @param savePath The path where the new document will be saved.
+     * @param pages The array of page numbers to be extracted and saved in the new document.
+     *
+     * @returns A Promise that resolves to `true` if the operation is successful, or `false` if it fails.
+     *
+     * @throws If the native view reference is not found, the promise will be rejected with an error message.
+     */
+    splitDocumentPages = (
+        savePath : string,
+        pages : Array<number> = [],
+    ) : Promise<boolean> => {
+        const tag = findNodeHandle(this._viewerRef);
+        if (tag != null) {
+            return CPDFViewManager.splitDocumentPages(tag, {
+                'save_path' : savePath,
+                'pages' : pages
+            });
+        }
+        return Promise.reject('Unable to find the native view reference');
+    }
+
 
     /**
      * Retrieves the path of the current document.
      * On Android, if the document was opened via a URI, the URI will be returned.
-     * 
-     * This function returns the path of the document being viewed. If the document was opened 
+     *
+     * This function returns the path of the document being viewed. If the document was opened
      * through a file URI on Android, the URI string will be returned instead of a file path.
-     * 
+     *
      * @example
      * const documentPath = await pdfReaderRef.current?._pdfDocument.getDocumentPath();
-     * 
+     *
      * @returns A promise that resolves to the path (or URI) of the current document.
      * If the native view reference is not found, the promise will be rejected with an error.
-     * 
+     *
      * @throws Will reject with an error message if the native view reference cannot be found.
      */
     getDocumentPath = () : Promise<string> => {
@@ -437,6 +529,7 @@ export class CPDFDocument {
         }
         return Promise.reject(new Error('Unable to find the native view reference'));
     }
-
 }
+
+
 // export default CPDFDocument;

+ 25 - 0
src/view/CPDFPage.tsx

@@ -0,0 +1,25 @@
+/**
+ * Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
+ *
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+
+class CPDFPage {
+
+    _pageIndex : number
+
+    constructor(pageIndex : number) {
+        this._pageIndex = pageIndex;
+    }
+
+
+    getAnnotations = () : Promise<Array<number>> =>{
+        return new Promise((resolve, reject) => {
+            resolve([1,2,3,4,5]);
+        });
+    }
+
+}