CPDFReaderViewControllerExample.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /**
  2. * Copyright © 2014-2025 PDF Technologies, Inc. All Rights Reserved.
  3. *
  4. * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  5. * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  6. * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  7. * This notice may not be removed from this file.
  8. */
  9. import React, { useState, useEffect, useRef } from 'react';
  10. import { Image, Platform, StyleSheet, Text, View, ScrollView } from 'react-native';
  11. import PDFReaderContext, { CPDFReaderView, ComPDFKit, CPDFToolbarAction } from '@compdfkit_pdf_sdk/react_native';
  12. import { useNavigation, useRoute, RouteProp } from '@react-navigation/native';
  13. import { HeaderBackButton } from '@react-navigation/elements';
  14. import { MenuProvider, Menu, MenuTrigger, MenuOptions, MenuOption } from 'react-native-popup-menu';
  15. import { SafeAreaView } from 'react-native-safe-area-context';
  16. import { CPDFDisplaySettingsScreen } from './screens/CPDFDisplaySettingsScreen';
  17. import { CPDFPreviewModeListScreen } from './screens/CPDFPreviewModeListScreen';
  18. import RNFS from 'react-native-fs';
  19. import { CPDFFileUtil } from './util/CPDFFileUtil';
  20. type RootStackParamList = {
  21. CPDFReaderViewExample: { document?: string };
  22. };
  23. type CPDFReaderViewExampleScreenRouteProp = RouteProp<
  24. RootStackParamList,
  25. 'CPDFReaderViewExample'
  26. >;
  27. const CPDFReaderViewControllerExampleScreen = () => {
  28. const [displaySettingModalVisible, setDisplaySettingModalVisible] = useState(false);
  29. const [previewModeModalVisible, setPreviewModeModalVisible] = useState(false);
  30. const pdfReaderRef = useRef<CPDFReaderView | null>(null);
  31. const navigation = useNavigation();
  32. const route = useRoute<CPDFReaderViewExampleScreenRouteProp>();
  33. const [samplePDF] = useState(
  34. route.params?.document || (Platform.OS === 'android'
  35. ? 'file:///android_asset/PDF_Document.pdf'
  36. : 'PDF_Document.pdf')
  37. );
  38. useEffect(() => {
  39. const unsubscribe = navigation.addListener('beforeRemove', (e) => {
  40. e.preventDefault();
  41. // Save document changes
  42. handleSave();
  43. navigation.dispatch(e.data.action);
  44. });
  45. return unsubscribe;
  46. }, [navigation]);
  47. const handleSave = async () => {
  48. if (pdfReaderRef.current) {
  49. const success = await pdfReaderRef.current.save();
  50. if (success) {
  51. console.log('ComPDFKitRN save() : Document saved successfully');
  52. } else {
  53. console.log('ComPDFKitRN save() : Failed to save document');
  54. }
  55. }
  56. };
  57. const handleBack = () => {
  58. navigation.goBack();
  59. };
  60. const menuOptions = [
  61. 'openDocument',
  62. 'save',
  63. 'saveAs',
  64. 'hasChange',
  65. 'DisplaySettings',
  66. 'PreviewModeScreen',
  67. 'showThumbnailView',
  68. 'showBotaView',
  69. 'showAddWatermarkView',
  70. 'showSecurityView',
  71. 'showDisplaySettingView',
  72. 'enterSnipMode',
  73. 'exitSnipMode',
  74. 'setDisplayPageIndex',
  75. 'getCurrentPageIndex',
  76. 'setMargins',
  77. 'removeSignFileList',
  78. 'setScale',
  79. ...(Platform.OS === 'android') ? [
  80. 'setPageSpacing',
  81. 'setPageSameWidth',
  82. 'setFixedScroll',
  83. 'isPageInScreen',
  84. ] : [],
  85. 'print'];
  86. const handleMenuItemPress = async (action: string) => {
  87. switch (action) {
  88. case 'openDocument':
  89. const document = await ComPDFKit.pickFile();
  90. if (document) {
  91. await pdfReaderRef.current?._pdfDocument.open(document);
  92. }
  93. break;
  94. case 'save':
  95. handleSave();
  96. break;
  97. case 'saveAs':
  98. const fileUtil = new CPDFFileUtil();
  99. const baseName = 'save_as_test';
  100. const extension = 'pdf';
  101. const uniqueFilePath = await fileUtil.getUniqueFilePath(baseName, extension);
  102. console.log('ComPDFKitRN saveAs:', uniqueFilePath);
  103. // const androidUri = await ComPDFKit.createUri('save_as_test.pdf', '', 'application/pdf');
  104. const success = await pdfReaderRef.current?._pdfDocument.saveAs(uniqueFilePath, false, true);
  105. if (success) {
  106. await pdfReaderRef.current?._pdfDocument.open(uniqueFilePath, '');
  107. }
  108. console.log('ComPDFKitRN saveAs:', success);
  109. break;
  110. case 'hasChange':
  111. const hasChange = await pdfReaderRef.current?._pdfDocument.hasChange();
  112. console.log('ComPDFKitRN hasChange:', hasChange);
  113. break;
  114. case 'DisplaySettings':
  115. setDisplaySettingModalVisible(true);
  116. break;
  117. case 'PreviewModeScreen':
  118. setPreviewModeModalVisible(true);
  119. break;
  120. case 'showThumbnailView':
  121. await pdfReaderRef.current?.showThumbnailView(false);
  122. break;
  123. case 'showBotaView':
  124. await pdfReaderRef.current?.showBotaView();
  125. break;
  126. case 'showAddWatermarkView':
  127. await pdfReaderRef.current?.showAddWatermarkView(false);
  128. break;
  129. case 'showSecurityView':
  130. await pdfReaderRef.current?.showSecurityView();
  131. break;
  132. case 'showDisplaySettingView':
  133. await pdfReaderRef.current?.showDisplaySettingView();
  134. break;
  135. case 'enterSnipMode':
  136. await pdfReaderRef.current?.enterSnipMode();
  137. break;
  138. case 'exitSnipMode':
  139. await pdfReaderRef.current?.exitSnipMode();
  140. break;
  141. case 'setDisplayPageIndex':
  142. await pdfReaderRef.current?.setDisplayPageIndex(1);
  143. break;
  144. case 'getCurrentPageIndex':
  145. const pageIndex = await pdfReaderRef.current?.getCurrentPageIndex();
  146. console.log('ComPDFKitRN currentPageIndex:', pageIndex);
  147. break;
  148. case 'setMargins':
  149. await pdfReaderRef.current?.setMargins(10, 20, 10, 20)
  150. break;
  151. case 'removeSignFileList':
  152. await ComPDFKit.removeSignFileList();
  153. break;
  154. case 'setScale':
  155. await pdfReaderRef.current?.setScale(2.3);
  156. var scale = await pdfReaderRef.current?.getScale();
  157. console.log('ComPDFKitRN getScale:', scale);
  158. break;
  159. case 'setPageSpacing':
  160. await pdfReaderRef.current?.setPageSpacing(50);
  161. break;
  162. case 'setPageSameWidth':
  163. await pdfReaderRef.current?.setPageSameWidth(true);
  164. break;
  165. case 'isPageInScreen':
  166. const inScreen = await pdfReaderRef.current?.isPageInScreen(1);
  167. console.log('ComPDFKit-RN inScreen:', inScreen);
  168. break;
  169. case 'setFixedScroll':
  170. await pdfReaderRef.current?.setFixedScroll(false);
  171. break;
  172. case 'print':
  173. await pdfReaderRef.current?._pdfDocument.printDocument();
  174. break;
  175. default:
  176. break;
  177. }
  178. };
  179. const renderToolbar = () => {
  180. return (
  181. <View style={styles.toolbar}>
  182. <HeaderBackButton onPress={handleBack} />
  183. <Text style={styles.toolbarTitle}>Controller Example</Text>
  184. <Menu>
  185. <MenuTrigger>
  186. <Image source={require('../assets/more.png')} style={{ width: 24, height: 24, marginEnd: 8 }} />
  187. </MenuTrigger>
  188. <MenuOptions customStyles={{ optionsWrapper: styles.menuOptionsWrapper }}>
  189. <ScrollView>
  190. {menuOptions.map((option, index) => (
  191. <MenuOption key={index} onSelect={() => handleMenuItemPress(option)}>
  192. <Text style={styles.menuOption}>{option}</Text>
  193. </MenuOption>
  194. ))}
  195. </ScrollView>
  196. </MenuOptions>
  197. </Menu>
  198. </View>
  199. );
  200. };
  201. const onPageChanged = (pageIndex: number) => {
  202. console.log('ComPDFKitRN --- onPageChanged:', pageIndex);
  203. }
  204. const saveDocument = () => {
  205. console.log('ComPDFKitRN saveDocument');
  206. }
  207. return (
  208. <PDFReaderContext.Provider value={pdfReaderRef.current}>
  209. <MenuProvider>
  210. <SafeAreaView style={{ flex: 1 }}>
  211. <View style={{ flex: 1 }}>
  212. {renderToolbar()}
  213. <CPDFReaderView
  214. ref={pdfReaderRef}
  215. document={samplePDF}
  216. onPageChanged={onPageChanged}
  217. saveDocument={saveDocument}
  218. configuration={ComPDFKit.getDefaultConfig({
  219. toolbarConfig: {
  220. iosLeftBarAvailableActions: [
  221. CPDFToolbarAction.THUMBNAIL
  222. ]
  223. }
  224. })} />
  225. <CPDFDisplaySettingsScreen
  226. visible={displaySettingModalVisible}
  227. onClose={() => setDisplaySettingModalVisible(false)}
  228. />
  229. <CPDFPreviewModeListScreen
  230. visible={previewModeModalVisible}
  231. onClose={() => setPreviewModeModalVisible(false)}
  232. />
  233. </View>
  234. </SafeAreaView>
  235. </MenuProvider>
  236. </PDFReaderContext.Provider>
  237. );
  238. };
  239. const styles = StyleSheet.create({
  240. toolbar: {
  241. height: 56,
  242. flexDirection: 'row',
  243. alignItems: 'center',
  244. justifyContent: 'flex-start',
  245. backgroundColor: '#FAFCFF',
  246. paddingHorizontal: 4,
  247. },
  248. toolbarButton: {
  249. padding: 8,
  250. },
  251. toolbarTitle: {
  252. flex: 1,
  253. color: 'black',
  254. fontSize: 16,
  255. fontWeight: 'bold',
  256. marginStart: 8
  257. },
  258. menuOption: {
  259. padding: 8,
  260. fontSize: 14,
  261. color: 'black',
  262. },
  263. menuOptionsWrapper: {
  264. maxHeight: 500,
  265. },
  266. });
  267. export default CPDFReaderViewControllerExampleScreen;