Flutter PDF处理插件pdftron_flutter的使用
Flutter PDF处理插件pdftron_flutter的使用
关于PDFTron Flutter
PDFTron的Flutter PDF库为iOS和Android应用程序带来了流畅、灵活且独立的文档查看和编辑解决方案。以下是该库的一些主要特点:
- 直接查看和转换MS Office文档
- 完全可自定义的开源UI以提高应用参与度
- 文档重排以提高移动设备上的可读性和可访问性
- 文件流式传输以更快地查看远程和复杂文档
- 夜间模式以在低光环境下改善查看体验
- 更多功能…
更多信息可以在官方文档中找到。
目录
前提条件
- 试用期间不需要许可证密钥。但是,试用期结束后需要有效的商业许可证密钥。
- PDFTron SDK >= 6.9.0
- Flutter >= 2.0.0
空安全
Dart现在支持空安全,从Dart 2.12.0和Flutter 2.0.0开始可用。有关迁移指南,请参阅迁移指南。
如果您希望使用我们的空安全SDK,可以在以下地方找到:
遗留UI
版本0.0.6
是遗留UI的最后一个稳定版本。可以在这里找到该版本。
安装
1. 创建Flutter项目
首先按照Flutter入门指南安装、设置编辑器和创建Flutter项目。假设您的项目是通过运行flutter create myapp
创建的。
2. 添加依赖
在myapp/pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
pdftron_flutter:
或者从GitHub添加:
dependencies:
flutter:
sdk: flutter
pdftron_flutter:
git:
url: git://github.com/ApryseSDK/pdftron-flutter.git
3. 获取包
在myapp
目录中运行flutter packages get
。
4. Android配置
在myapp/android/app/build.gradle
文件中添加以下内容:
defaultConfig {
applicationId "com.example.myapp"
minSdkVersion 21
multiDexEnabled true
manifestPlaceholders += [pdftronLicenseKey:PDFTRON_LICENSE_KEY]
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
在myapp/android/gradle.properties
文件中添加以下内容:
# Add the PDFTRON_LICENSE_KEY variable here.
# For trial purposes leave it blank.
# For production add a valid commercial license key.
PDFTRON_LICENSE_KEY=
在myapp/android/app/src/main/AndroidManifest.xml
文件中添加以下内容:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
android:largeHeap="true"
android:usesCleartextTraffic="true">
<meta-data
android:name="pdftron_license_key"
android:value="${pdftronLicenseKey}"/>
</application>
</manifest>
如果使用DocumentView
小部件,将MainActivity
文件(Kotlin或Java)的父类更改为FlutterFragmentActivity
:
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity : FlutterFragmentActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
5. iOS配置
在myapp/ios/Podfile
文件中添加以下内容:
platform :ios, '10.0'
target 'Runner' do
use_frameworks!
pod 'PDFTron', podspec: 'https://pdftron.com/downloads/ios/flutter/pdftron/latest.podspec'
pod 'PDFTronTools', podspec: 'https://pdftron.com/downloads/ios/flutter/pdftron-tools/latest.podspec'
end
确保集成过程成功,运行flutter build ios --no-codesign
。
Widget或插件
有2种不同的方式使用PDFTron Flutter API:
- 通过插件呈现文档。
- 通过小部件显示PDFTron文档视图。
您必须选择其中一种方式,并在所有API中使用它。混合使用小部件和插件API将无法正常工作。
如果您选择Android小部件,需要为操作系统入侵(如设备顶部的状态栏)添加填充。一种方法是设置启用的系统UI,然后将小部件包装在SafeArea
或使用AppBar
中:
// 如果使用Flutter v2.3.0-17.0.pre或更早版本
SystemChrome.setEnabledSystemUIOverlays(
SystemUiOverlay.values
);
// 如果使用较新版本的Flutter
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.edgeToEdge,
);
// 如果使用SafeArea:
return SafeArea (
child: DocumentView(
onCreated: _onDocumentViewCreated,
));
// 如果使用AppBar:
return Scaffold(
appBar: AppBar( toolbarHeight: 0 ),
body: DocumentView(
onCreated: _onDocumentViewCreated,
));
使用方法
1. 添加权限处理
如果您想使用本地文件,需要在myapp/pubspec.yaml
中添加以下依赖:
permission_handler: ^11.3.1
2. 替换lib/main.dart
打开lib/main.dart
,替换整个文件内容如下:
import 'dart:async';
import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pdftron_flutter/pdftron_flutter.dart';
// 如果使用本地文件,取消注释以下行
// import 'package:permission_handler/permission_handler.dart';
// 设置此值以通过Widget查看文档
var enableWidget = true;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Viewer(),
);
}
}
class Viewer extends StatefulWidget {
@override
_ViewerState createState() => _ViewerState();
}
class _ViewerState extends State<Viewer> {
String _version = 'Unknown';
String _document = "https://pdftron.s3.amazonaws.com/downloads/pl/PDFTRON_mobile_about.pdf";
bool _showViewer = true;
@override
void initState() {
super.initState();
initPlatformState();
if (!enableWidget) {
showViewer();
}
// 如果使用本地文件:
// * 删除上面的 `showViewer();` 行。
// * 更改 `_document` 字段为您的本地文件路径。
// * 取消注释以下部分,包括 `launchWithPermission()`。
// if (Platform.isIOS) {
// showViewer(); // iOS 不需要权限。
// } else {
// launchWithPermission(); // Android 需要权限。
// }
}
// 如果使用本地文件,取消注释以下部分:
// Future<void> launchWithPermission() async {
// PermissionStatus permission = await Permission.storage.request();
// if (permission.isGranted) {
// showViewer();
// }
// }
// 平台消息是异步的,因此在异步方法中初始化。
Future<void> initPlatformState() async {
String version;
// 平台消息可能失败,因此使用 try/catch PlatformException。
try {
// 初始化 PDFTron SDK,必须在使用任何功能之前调用。
PdftronFlutter.initialize("your_pdftron_license_key");
version = await PdftronFlutter.version;
} on PlatformException {
version = 'Failed to get platform version.';
}
// 如果在异步平台消息飞行过程中移除了小部件,则应丢弃回复而不是调用
// setState 来更新我们不存在的外观。
if (!mounted) return;
setState(() {
_version = version;
});
}
void showViewer() async {
// 没有配置文件打开时将启用所有功能。
// await PdftronFlutter.openDocument(_document);
var config = Config();
// 如何禁用功能:
// config.disabledElements = [Buttons.shareButton, Buttons.searchButton];
// config.disabledTools = [Tools.annotationCreateLine, Tools.annotationCreateRectangle];
// 其他查看器配置:
// config.multiTabEnabled = true;
// config.customHeaders = {'headerName': 'headerValue'};
// 文档加载事件监听器
var documentLoadedCancel = startDocumentLoadedListener((filePath) {
print("document loaded: $filePath");
});
await PdftronFlutter.openDocument(_document, config: config);
try {
// 导入注释命令,格式为XFDF,告诉是否在当前文档中添加、修改或删除注释。
PdftronFlutter.importAnnotationCommand(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<xfdf xmlns=\"http://ns.adobe.com/xfdf/\" xml:space=\"preserve\">\n" +
" <add>\n" +
" <square style=\"solid\" width=\"5\" color=\"#E44234\" opacity=\"1\" creationdate=\"D:20200619203211Z\" flags=\"print\" date=\"D:20200619203211Z\" name=\"c684da06-12d2-4ccd-9361-0a1bf2e089e3\" page=\"1\" rect=\"113.312,277.056,235.43,350.173\" title=\"\" />\n" +
" </add>\n" +
" <modify />\n" +
" <delete />\n" +
" <pdf-info import-version=\"3\" version=\"2\" xmlns=\"http://www.pdftron.com/pdfinfo\" />\n" +
"</xfdf>");
} on PlatformException catch (e) {
print("Failed to importAnnotationCommand '${e.message}'.");
}
try {
PdftronFlutter.importBookmarkJson('{"0":"Page 1"}');
} on PlatformException catch (e) {
print("Failed to importBookmarkJson '${e.message}'.");
}
// 当本地注释更改提交到文档时的事件监听器。
// xfdfCommand 是最后更改的注释的 XFDF 命令。
var annotCancel = startExportAnnotationCommandListener((xfdfCommand) {
// 本地注释更改。
// 在此处将 XFDF 命令上传到服务器。
String command = xfdfCommand;
// Dart 限制了打印到控制台的字符数。
// 以下代码确保所有 XFDF 命令都被打印。
if (command.length > 1024) {
print("flutter xfdfCommand:\n");
int start = 0;
int end = 1023;
while (end < command.length) {
print(command.substring(start, end) + "\n");
start += 1024;
end += 1024;
}
print(command.substring(start));
} else {
print(command);
}
});
// 当本地书签更改提交到文档时的事件监听器。
// bookmarkJson 是包含更改时存在的所有书签的 JSON 字符串。
var bookmarkCancel = startExportBookmarkListener((bookmarkJson) {
print("flutter bookmark: $bookmarkJson");
});
var path = await PdftronFlutter.saveDocument();
print("flutter save: $path");
// 取消事件:
// annotCancel();
// bookmarkCancel();
// documentLoadedCancel();
}
@override
Widget build(BuildContext context) {
Widget documentChild = Container();
if (enableWidget) {
// 如果使用 Android 小部件,取消注释以下行之一:
// 如果使用 Flutter v2.3.0-17.0.pre 或更早版本。
// SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
// 如果使用较新版本的 Flutter。
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.edgeToEdge,
);
documentChild = _showViewer
? SafeArea(
child: DocumentView(
onCreated: _onDocumentViewCreated,
))
: Container();
}
return Scaffold(
body: Container(
width: double.infinity,
height: double.infinity,
child: documentChild,
),
);
}
// 此函数用于在创建后控制 DocumentView 小部件。
// 小部件需要传递一个 void Function(DocumentViewController controller) 才能工作。
void _onDocumentViewCreated(DocumentViewController controller) async {
Config config = new Config();
var leadingNavCancel = startLeadingNavButtonPressedListener(() {
// 取消注释此行以在按下前导导航按钮时退出查看器:
// this.setState(() {
// _showViewer = !_showViewer;
// });
// 在按下前导导航按钮时显示对话框。
_showMyDialog();
});
await controller.openDocument(_document, config: config);
}
Future<void> _showMyDialog() async {
print('hello');
return showDialog<void>(
context: context,
barrierDismissible: false, // 用户必须点击按钮!
builder: (BuildContext context) {
return AlertDialog(
title: Text('AlertDialog'),
content: SingleChildScrollView(
child: Text('前导导航按钮已被按下。'),
),
actions: <Widget>[
TextButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
变更日志
参见变更日志。
贡献
参见贡献指南。
许可证
参见许可证。
更多关于Flutter PDF处理插件pdftron_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html