logo
积分中心
鸿蒙版本的App浏览PDF文档 原创
头像 aqi00 2026-10-14 14:49:04    发布
1 浏览 0 点赞 0 收藏

​HarmonyOS 5.0开始自带的PDF Kit提供了PDF文档浏览和修改服务,不但支持预览PDF文档内容,还支持对PDF文档添加文本内容、图片、批注、页眉页脚、水印、背景图片、书签等。

使用PDF服务之前,要先在ETS代码开头添加以下的导包语句,表示引入PDF服务需要的pdfService、pdfViewManager、PdfView等模块,及其依赖的BusinessError模块:

import { pdfService, pdfViewManager, PdfView } from '@kit.PDFKit';
import { BusinessError } from '@kit.BasicServicesKit';

其中PdfView为界面布局需要的PDF预览组件,用来展示PDF文档内容。PdfView组件的构造接口可输入以下字段:

controller:PdfView组件的控制器,取值为pdfViewManager.PdfController类型。
pageLayout:页面布局显示模式。取值为pdfService.PageLayout枚举,为LAYOUT_SINGLE代表单页显示,为LAYOUT_DOUBLE代表双页显示。默认LAYOUT_SINGLE。
isContinuous:是否连续预览。取值true代表连续预览,取值false代表不连续预览。默认true。
showScroll:是否显示滚动条。取值true代表显示滚动条,取值false代表隐藏滚动条。默认true
pageFit:页面适配模式。取值为pdfService.PageFit枚举,为FIT_NONE代表实际大小,为FIT_PAGE代表按页缩放,为FIT_WIDTH代表按宽度缩放,为FIT_HEIGHT代表按高度缩放。默认FIT_NONE。

以上字段当中,controller为必填字段,其余为可选字段。不过建议将pageFit字段设置为pdfService.PageFit.FIT_WIDTH,这样PDF页面能够适配屏幕宽度缩放,否则原始页面太大,手机屏幕放不下。

为什么controller是必填字段呢?这是因为只有控制器才能加载指定路径的PDF文件,也只有控制器才能操纵PDF文档的浏览动作。控制器类型pdfViewManager.PdfController主要提供了下列方法:
registerPageCountChangedListener:注册总页数变化的时候监听器,必须在loadDocument之前调用。
loadDocument:加载指定路径的PDF文件,并通过PdfView组件显示PDF文档内容,使用Promise异步回调。
releaseDocument:释放已加载的PDF文档。
saveDocument:保存PDF文档,使用Promise异步回调。

由于loadDocument方法只能加载应用沙箱内部的PDF文件,因此其他来源的PDF文档必须先复制到应用沙箱,再让PDF控制器加载沙箱PDF。为此可将PDF文档的浏览功能分解成以下几个步骤:

1、给ETS页面声明一个控制器实例,并在build函数中添加PdfView组件的布局内容,如下所示:

private controller = new pdfViewManager.PdfController();

build() {
  Column() {
    PdfView({
      controller: this.controller,
      pageFit: pdfService.PageFit.FIT_WIDTH,
    }).width('100%')
  }.width('100%').height('100%')
}

2、把其他地方的PDF文件复制到应用内部的沙箱路径,比如下面代码把资源目录下的tangshi.pdf文档复制到了应用沙箱。

let context = getContext() as common.UIAbilityContext;
// 确保在工程目录src/main/resources/rawfile里存在tangshi.pdf文档
let filePath = context.filesDir + '/' + this.fileName;
let res = fileIo.accessSync(filePath);
if (!res) {
  let content = context.resourceManager.getRawFileContentSync('rawfile/'+this.fileName);
  let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
  fileIo.writeSync(file.fd, content.buffer);
  fileIo.closeSync(file.fd);
}

3、调用PDF控制器的loadDocument方法,从应用沙箱路径加载PDF文件,加载代码如下所示:

(async () => { // 异步方式加载PDF文档
  // 该监听方法只能在文档加载前调用一次
  this.controller.registerPageCountChangedListener((pageCount: number) => {
    console.info('pageCount='+pageCount.toString());
  });
  // 注意:这里刚加载文档,请不要在这里立即设置PDF文档的预览方式
  this.controller.loadDocument(filePath)
    .then((loadResult: pdfService.ParseResult) => {
      console.info('loadDocument successfully, loadResult is: ' + JSON.stringify(loadResult));
    }).catch((err: BusinessError) => {
    console.error('loadDocument failed with err: ' + JSON.stringify(err));
  });
})() // 末尾的一对括号必不可少,不然异步代码块就不会被执行

以上PDF加载代码对应的PDF文档渲染效果如下图所示。

​

上面虽然使用PdfView组件及其控制器实现了PDF文档的加载功能,但实际的渲染结果会把PDF的所有页面都显示出来,而非由用户控制的一页一页浏览。那么若想实现更加精细的浏览操作,就要引入PDF服务模块pdfService了。

pdfService模块不仅支持文档加载、翻页、转存图片等常见功能,还为应用提供统一的管理PDF页面的页眉页脚、水印和背景、文档的多种批注风格和书签便捷的PDF能力。

pdfService的常用方法说明如下:

loadDocument:加载指定路径的PDF文件。
releaseDocument:释放已加载的PDF文档。
saveDocument:保存PDF文档。
createDocument:创建空白文档。
getPageCount:获取文档页数。
getPage:获取指定页码的页面。页面对象为pdfService.PdfPage类型。
insertBlankPage:在指定位置插入空白页。
deletePage:删除指定位置的PDF页。
movePage:将指定页面移到索引位置。
getMetadata:获取PDF元数据,包括作者、创建者、创建日期等。
convertToImage:把PDF文档转换为图片。

以上方法当中,getPage返回的页面对象还需进一步处理,PdfPage类型的常用方法说明如下:

getDocument:获取PDFDocument对象。
getAnnotations:获取文档批注。
addAnnotation:在当前页添加批注。
setAnnotation:在当前页设置批注。
removeAnnotation:删除当前页批注。
getIndex:获取当前页的索引。
getWidth:获取当前页的宽度。
getHeight:获取当前页的高度。
getPagePixelMap:获取当前页的图片。图片对象为image.PixelMap类型的像素图,可让Image组件提前绑定像素图对象,即可将获取的图片即时渲染在界面上。
release:释放已加载的PDF页面。

下面分别介绍如何实现PDF文档常见的几种浏览场景。

1、加载PDF文件并显示第一页内容

先给ETS页面分别声明PDF文件路径、像素图对象、PDF文档对象,如下所示:

@State filePath: string = '';
@State pixelMap: PixelMap | undefined = undefined;
private document: pdfService.PdfDocument = new pdfService.PdfDocument;

再调用PDF文档对象的loadDocument方法加载PDF文件,并调用getPage方法获取第一页的页面对象、调用页面对象的getPagePixelMap获取该页的像素图,如下所示:

// 注意filePath必须为PDF文件的应用沙箱路径
this.document.loadDocument(this.filePath, '');
let page: pdfService.PdfPage = this.document.getPage(0); //默认第一页
this.pixelMap = page.getPagePixelMap(); //设置Image组件参数

2、显示PDF文档的下一页内容

事先给ETS页面声明页码变量pageIndex,那么翻到下一页就是对pageIndex加一,再调用getPage方法获取下一页的页面对象,如下所示:

this.pageIndex++;
if (this.pageIndex >= this.document.getPageCount()) {
  promptAction.showToast({ message: '已是最后一页' })
  this.pageIndex--;
  return;
}
let page: pdfService.PdfPage = this.document.getPage(this.pageIndex); //设置页面为下一页
this.pixelMap = page.getPagePixelMap(); // 设置Image组件参数

3、显示PDF文档的上一页内容

事先给ETS页面声明页码变量pageIndex,那么翻到上一页就是对pageIndex减一,再调用getPage方法获取上一页的页面对象,如下所示:

this.pageIndex--;
if (this.pageIndex < 0) {
  promptAction.showToast({ message: '已是第一页' })
  this.pageIndex++;
  return;
}
let page: pdfService.PdfPage = this.document.getPage(this.pageIndex); //设置页面为上一页
this.pixelMap = page.getPagePixelMap(); //设置Image组件参数

4、把PDF文档的每个页面都保存为图片

先在应用沙箱内部创建待保存图片的新目录,再调用PDF文档对象的convertToImage方法,把已加载的PDF文档各页面都转为图片后保存到沙箱目录。如下所示:

// 注意:图片保存路径必须位于应用沙箱内部
fileIo.mkdir(this.imageDir);
//将整个PDF文件转为图片
let result = this.document.convertToImage(this.imageDir, pdfService.ImageFormat.PNG);
if (result) {
  promptAction.showToast({ message: 'PDF转图片成功,存储目录为:'+this.imageDir })
} else {
  promptAction.showToast({ message: 'PDF转图片失败,请检查用户权限' })
}

以上PDF操作代码对应的界面效果如下图所示。

​


©本站发布的所有内容,包括但不限于文字、图片、音频、视频、图表、标志、标识、广告、商标、商号、域名、软件、程序等,除特别标明外,均来源于网络或用户投稿,版权归原作者或原出处所有。我们致力于保护原作者版权,若涉及版权问题,请及时联系我们进行处理。
分类
HarmonyOS

暂无评论数据

加载中...

发布

地址:北京市朝阳区北三环东路三元桥曙光西里甲1号第三置业A座1508室 电话:13391790444或(010)62178877
版权所有:电脑商情信息服务集团 北京赢邦策略咨询有限责任公司
声明:本媒体部分图片、文章来源于网络,版权归原作者所有,我司致力于保护作者版权,如有侵权,请与我司联系删除

京ICP备:2022009079号-2

京公网安备:11010502051901号

ICP证:京B2-20230255