HarmonyOS 鸿蒙Next 从服务端拿到epub文件,如何在本地读取并展示

发布于 1周前 作者 songsunli 最后一次编辑是 5天前 来自 鸿蒙OS

1、使用epublib三方库,下载demo:https://gitee.com/openharmony-tpc/openharmony_tpc_samples/tree/master/epublib

2、迁移适配HarmonyOS

工程级目录下的build-profile.json5中替换products配置:

    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "compatibleSdkVersion": "5.0.0(12)",
        "runtimeOS": "HarmonyOS",
      }
    ]

3、修改代码将工程中的profile文件复制到沙箱路径下

demo的index文件中添加方法:

  copyFile2Sanbox() {
    /**
     * 通过fd来进行拷贝,避免文件过大的内存占用问题
     * data.fd是hap包的fd,data.offset表示目标文件在hap包中的偏移,data.length表示目标文件的长度
     */
    this.context.resourceManager.getRawFd("epubBook.epub", (err, data) => {
      if (err != null) {
        console.error(err.message)
        return
      }
      let sanboxPath = this.context.filesDir
      console.log("沙箱路径:" + sanboxPath)
      let filePath = this.context.tempDir + "/epubBookTest.epub"
      console.log("压缩文件路径:" + filePath)
      let dest = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
      let bufsize = 4096
      let buf = new ArrayBuffer(bufsize)
      let off = 0, len = 0, readedLen = 0
      /**
       * 通过buffer将rawfile文件内容copy到沙箱路径
       */
      while (len = fs.readSync(data.fd, buf, { offset: data.offset + off, length: bufsize })) {
        readedLen += len
        fs.writeSync(dest.fd, buf, { offset: off, length: len })
        off = off + len
        if ((data.length - readedLen) < bufsize) {
          bufsize = data.length - readedLen
        }
      }
      fs.close(dest.fd)
    })
  }

4、整体demo操作,先点击Copy按钮将文件复制到沙箱路径下,然后点击compress,最后点击click;

import {
  DOMParser,
  EpubReader,
  EpubWriter,
  Book,
  Author,
  EpubResource,
  MediaType,
  Metadata
} from "@ohos/epublib"
import util from '@ohos.util';
import prompt from '@ohos.promptAction';
import fs from '@ohos.file.fs';

@Entry
@Component
struct Index {
  srcStr = '<?xml version="1.0"?>' +
  '<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">' +
  '<rootfiles>' +
  '<rootfile full-path="content.opf" media-type="application/oebps-package+xml"/>' +
  '</rootfiles>' +
  '</container>';
  @State text: string | undefined  = '-Epub-'
  @State compressEnabled: boolean = true
  @State clickEnabled: boolean = true
  private context: Context = getContext()
  filePath: string = this.context.tempDir



  build() {
    Column() {

      Button('CopyFile2Sanbox')
        .width(150)
        .height(60)
        .onClick(() => {
          console.info("CopyFile");
         this.copyFile2Sanbox();
        })


      Button('Compress')
        .width(150)
        .height(60)
        .enabled(this.compressEnabled)
        .onClick(() => {
          console.info("- St -");
          this.funcUnEpub(this.filePath + "/epubBookTest.epub");
        })

      Button('Click')
        .width(150)
        .enabled(this.clickEnabled)
        .height(60)
        .onClick(() => {
          console.info("- St -");
          this.funcStart(this.filePath + "/epubBookTest.epub");
        })
        .margin({ top: 10 })
      TextArea({ text: this.text })
        .height('60%')
        .padding(15)
        .fontSize(px2fp(25))
        .focusable(false)
        .fontColor("#070707")
        .margin({ top: 30 })
        .align(Alignment.TopStart)
    }.height('90%').width('100%').padding(35).margin({ top: 30 })
  }

  test() {
    console.info("- Test to unit system lib.dow.d.ts of  getElementsByTagNameNS(namespaceURI: string, localName: string)-");
    let dataStr = this.readerFile(this.filePath + "/test", "mimetype");
    let domParser: DOMParser = new DOMParser();
    let result: ESObject = domParser.parseFromString(dataStr + "");
    this.text = result.toString();
  }
  
  funcUnEpub(input: string) {
    try {
      EpubReader.unEpub(input).then((data) => {
        this.compressEnabled= !this.compressEnabled
        console.log("----unEpub----successful-----------" + data)
      });
    } catch (err) {
      prompt.showToast({ message: 'no input file found',
        duration: 2000 });
      console.log("----unEpub----failed-----------" + err)
    }
  }

  funcStart(epubFile: string) {
    let book = EpubReader.readEpubFile(EpubReader.outFile(epubFile))

    if (book) {
      this.text = book.getResources()
        ?.getResourceMap()
        ?.get("chapter_446465249.xhtml")
        ?.getStrData()
        ?.toString();
      this.clickEnabled = !this.clickEnabled
      console.error("----index-result-------" + this.text)
      this.testEpubWriter(book)
    }
  }

  private testEpubWriter1() {
    let book = new Book();
    // Set the title
    book.getMetadata().addTitle("Epublib test book 1");
    // Add an Author
    book.getMetadata().addAuthor(new Author("Joe", "Tester"));
    let res = new EpubResource("heft", new MediaType("name", "extend"))
    book.addResource(res)
    book.setMetadata(new Metadata())
    // Create EpubWriter
    let epubWriter = new EpubWriter();

    // Write the Book as Epub
    epubWriter.write(book, "test1_book1.epub");

  }

  private testEpubWriter(book: Book) {
    let epubWriter = new EpubWriter();
    // Write the Book as Epub
    epubWriter.write(book, "test1_book1.epub");

  }

  private testFileIO2() {
    console.log('test start')
    console.info("------------getFilesDir dir: " + this.filePath);
    let fullPath = this.filePath + "/test/chapter_446465249.xhtml";
    let fileFD = fs.openSync(fullPath, 0o2);
    console.info("------openSync fileFD:" + fileFD);
    let buf = new ArrayBuffer(4096);
    let num = fs.readSync(fileFD.fd, buf);
    let fileRet = this.a2s(buf);
    let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true });
    let strData = textDecoder.decodeWithStream(new Uint8Array(buf));
    let testStr = fs.readTextSync(fullPath, { encoding: 'utf-8' })
    console.info("----------readSync num:" + num + ", testStr:" + testStr)
    console.info("----------readSync num:" + num + ", testStr:" + strData)
  }

  private a2s(buf: ArrayBuffer): string {
    let intArray: Int32Array = new Int32Array(buf)
    let numberArray: number[] = Array.from(intArray)
    return String.fromCharCode(...numberArray);
  }

  private readerFile(dirPath: string, nameFile: string): string {
    let fullpath = dirPath + "/" + nameFile;
    console.debug("---------fullpath----" + fullpath);
    let stat = fs.statSync(fullpath);
    let strData = fs.readTextSync(fullpath, { encoding: 'utf-8' });
    return strData;
  }

  copyStr(src: string) {
    let str = ""
    for (let i = 0; i < src.length; i++) {
      str += src[i]
    }
    return str
  }

  copyFile2Sanbox() {
    /**
     * 通过fd来进行拷贝,避免文件过大的内存占用问题
     * data.fd是hap包的fd,data.offset表示目标文件在hap包中的偏移,data.length表示目标文件的长度
     */
    this.context.resourceManager.getRawFd("epubBook.epub", (err, data) => {
      if (err != null) {
        console.error(err.message)
        return
      }
      let sanboxPath = this.context.filesDir
      console.log("沙箱路径:" + sanboxPath)
      let filePath = this.context.tempDir + "/epubBookTest.epub"
      console.log("压缩文件路径:" + filePath)
      let dest = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
      let bufsize = 4096
      let buf = new ArrayBuffer(bufsize)
      let off = 0, len = 0, readedLen = 0
      /**
       * 通过buffer将rawfile文件内容copy到沙箱路径
       */
      while (len = fs.readSync(data.fd, buf, { offset: data.offset + off, length: bufsize })) {
        readedLen += len
        fs.writeSync(dest.fd, buf, { offset: off, length: len })
        off = off + len
        if ((data.length - readedLen) < bufsize) {
          bufsize = data.length - readedLen
        }
      }
      fs.close(dest.fd)
    })
  }
}

更多关于HarmonyOS 鸿蒙Next 从服务端拿到epub文件,如何在本地读取并展示的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next 从服务端拿到epub文件,如何在本地读取并展示的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next系统中,从服务端获取epub文件并在本地读取展示,可以通过以下步骤实现:

  1. 文件下载:使用网络请求库(如Request库)从服务端下载epub文件,并保存到本地存储中。

  2. 文件解析:利用epub解析库(如epublibepub3的鸿蒙版本,需确认鸿蒙系统是否支持这些库或是否有等效的鸿蒙原生库)对下载的epub文件进行解析,提取其中的内容,包括书籍信息、章节信息等。

  3. UI展示:根据解析出的内容,利用鸿蒙系统的UI组件(如TextImageScrollView等)在界面上进行展示。对于文本内容,可以直接使用Text组件;对于图片,则使用Image组件;对于复杂的排版,可能需要自定义组件或使用ScrollView来滚动显示。

  4. 交互处理:添加用户交互功能,如翻页、目录跳转等,提升用户体验。

示例代码(伪代码,因实际库和API调用需参考鸿蒙开发文档):

// 伪代码示例
DownloadEpubFromServer();
EpubParser parser = new EpubParser();
EpubBook book = parser.parse(localEpubPath);
DisplayEpubContent(book);

请注意,上述步骤中的库和API调用需根据实际鸿蒙开发环境进行选择和调整。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部