ecp_file_view 4.0.0 copy "ecp_file_view: ^4.0.0" to clipboard
ecp_file_view: ^4.0.0 copied to clipboard

A file viewer plugin for Flutter, support local file and network link of Android, iOS.

example/lib/main.dart

import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:ecp_file_view/ecp_file_view.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:path_provider/path_provider.dart';

import 'page_local_file_viewer.dart';

void main() async {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      localizationsDelegates: <LocalizationsDelegate<dynamic>>[
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        ViewerLocalizationsDelegate.delegate,
      ],
      supportedLocales: [Locale('en', 'US'), Locale('zh', 'CN')],
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  /// 本地文件(assets/files 目录)
  final List<String> localFiles = [
    'docx.docx',
    'doc.doc',
    'xlsx.xlsx',
    'xls.xls',
    'pptx.pptx',
    'ppt.ppt',
    'pdf.pdf',
    'txt.txt',
  ];

  /// 在线大文档测试链接(非 GitHub 源,国内可访问,均已验证)
  final List<String> networkFiles = [
    // txt 2.2MB(Unicode 官方字符表)
    'https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt',
    // pdf 10.5MB(华为《迈向智能世界》计算白皮书)
    'https://www-file.huawei.com/-/media/corp2020/pdf/giv/striding-towards-the-intelligent-world/the_intelligent_world_computing_cn.pdf?la=zh',
    // doc 6.2MB(Apache POI 测试数据,Gitee 镜像)
    'https://gitee.com/apache/poi/raw/trunk/test-data/document/Bug61268.doc',
    // docx 3.0MB(Apache POI 测试数据,Gitee 镜像)
    'https://gitee.com/apache/poi/raw/trunk/test-data/document/saut_page.docx',
    // xls 4.7MB(Apache POI 测试数据,Gitee 镜像)
    'https://gitee.com/apache/poi/raw/trunk/test-data/spreadsheet/ex45698-22488.xls',
    // xlsx 2.9MB(Apache POI 测试数据,Gitee 镜像)
    'https://gitee.com/apache/poi/raw/trunk/test-data/spreadsheet/LIBRE_OFFICE-116306-0.xlsx',
    // ppt 3.3MB(Apache POI 测试数据,Gitee 镜像)
    'https://gitee.com/apache/poi/raw/trunk/test-data/slideshow/customGeo.ppt',
    // pptx 2.3MB(Apache POI 测试数据,Gitee 镜像)
    'https://gitee.com/apache/poi/raw/trunk/test-data/slideshow/KEY02.pptx',
  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('File View'),
          bottom: const TabBar(tabs: [Tab(text: '本地'), Tab(text: '网络')]),
        ),
        body: TabBarView(
          children: [_buildLocalListWidget(), _buildNetworkListWidget()],
        ),
      ),
    );
  }

  /// 本地文件列表
  Widget _buildLocalListWidget() {
    return ListView.builder(
      itemCount: localFiles.length,
      itemBuilder: (context, index) {
        String name = localFiles[index];
        String type = FileTool.getFileType(name);
        return _buildListItem(
          name,
          () => onLocalTap(type, 'assets/files/$name'),
        );
      },
    );
  }

  /// 网络文件列表
  Widget _buildNetworkListWidget() {
    return ListView.builder(
      itemCount: networkFiles.length,
      itemBuilder: (context, index) {
        String url = networkFiles[index];
        return _buildListItem(
          _getDisplayName(url),
          () => onNetworkTap(url),
        );
      },
    );
  }

  /// 从链接中提取显示名称(去掉 query 参数)
  String _getDisplayName(String url) {
    var name = FileTool.getFileName(url);
    int queryIndex = name.indexOf('?');
    if (queryIndex > -1) {
      name = name.substring(0, queryIndex);
    }
    return name;
  }

  /// 通用列表项
  Widget _buildListItem(String title, VoidCallback onTap) {
    return Container(
      margin: const EdgeInsets.only(top: 10.0),
      padding: const EdgeInsets.symmetric(horizontal: 15.0),
      child: ElevatedButton(
        onPressed: onTap,
        child: Text(title),
      ),
    );
  }

  Future onLocalTap(String type, String assetPath) async {
    String filePath = await setFilePath(type, assetPath);
    if (!await asset2Local(type, assetPath)) {
      return;
    }

    Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
      return LocalFileViewerPage(filePath: filePath);
    }));
  }

  Future onNetworkTap(String downloadUrl) async {
    // 优先使用链接中的文件名(含扩展名),便于预览时识别文档类型
    var name = _getDisplayName(downloadUrl);
    if (!name.contains('.')) {
      name = 'test.txt';
    }
    Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
      return NetworkFileViewer(url: downloadUrl, name: name);
    }));
  }

  Future asset2Local(String type, String assetPath) async {
    String filePath = await setFilePath(type, assetPath);

    File file = File(filePath);
    if (fileExists(filePath)) {
      await file.delete();
    }

    await file.create(recursive: true);
    debugPrint("文件路径 -> ${file.path}");
    ByteData bd = await rootBundle.load(assetPath);
    await file.writeAsBytes(bd.buffer.asUint8List(), flush: true);
    return true;
  }

  Future setFilePath(String type, String assetPath) async {
    final directory = await getTemporaryDirectory();
    return "${directory.path}/fileview/${base64.encode(utf8.encode(assetPath))}.$type";
  }

  bool fileExists(String filePath) => File(filePath).existsSync();
}
0
likes
130
points
141
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A file viewer plugin for Flutter, support local file and network link of Android, iOS.

Repository

License

Apache-2.0 (license)

Dependencies

better_open_file, dict_flutter_extension, dio, ecp_net, ecp_theme, flutter, flutter_smart_dialog, path_provider, permission_handler

More

Packages that depend on ecp_file_view

Packages that implement ecp_file_view