如何在Flutter/Dart中为.ePub文件生成CFI字符串
在Dart中生成ePub章节的CFI字符串
问题分析
你当前的代码无法输出CFI的核心原因是:jumpTo 是异步的视图跳转操作,循环中直接调用 generateEpubCfi() 时,目标章节还未完成渲染加载,因此无法生成有效的CFI。此外,epub_view 的 generateEpubCfi() 方法依赖当前已加载的章节内容,必须等待视图完成渲染后才能调用。
修正方案(基于epub_view 3.0.0)
可以通过等待目录加载完成、确保视图渲染结束后再调用CFI生成方法,调整后的代码示例如下:
EpubBook epubBook = await EpubReader.readBook(epubFile.readAsBytes()); EpubController _epubController = EpubController(document: EpubDocument.openFile(epubFile)); // 等待目录数据加载完成 await _epubController.tableOfContentsListenable.future; for (var epubViewChapter in _epubController.tableOfContentsListenable.value) { // 执行章节跳转并等待视图状态稳定 await _epubController.jumpTo(index: epubViewChapter.startIndex); // 借助PostFrameCallback确保视图已完成渲染 WidgetsBinding.instance.addPostFrameCallback((_) async { String? cfi = await _epubController.generateEpubCfi(); print("Chapter: ${epubViewChapter.startIndex}, Name: ${epubViewChapter.title} CFI: $cfi"); }); }
如果仍无法获取CFI,需检查ePub文件是否符合标准结构,部分非规范的ePub可能无法被epub_view正确解析生成CFI。
替代方案(使用epub_parser包)
若epub_view无法满足需求,可切换到epub_parser包直接解析ePub结构,手动生成章节的基础CFI(CFI格式为epubcfi(/6/4[chapter1]!/4/2/1:0),路径需匹配章节的实际层级):
import 'package:epub_parser/epub_parser.dart'; EpubBook book = await EpubReader.readBook(epubFile.readAsBytes()); for (var tocItem in book.TableOfContents) { // 获取章节的资源路径 String chapterHref = tocItem.Content!.Src!; // 生成基础CFI(需根据ePub实际结构调整路径参数) String cfi = "epubcfi(/6/4[$chapterHref]!/4/2/1:0)"; print("Chapter: ${tocItem.Title}, CFI: $cfi"); }
手动生成CFI时,可通过解析ePub的OPF文件获取更精准的章节层级信息,调整CFI路径以匹配实际内容位置。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

