目录

PdfView组件如何实时显示编辑后的PDF文件

问题现象

PdfView组件加载一个PDF文件,对这个文件做编辑操作,如何使编辑后的效果在PdfView组件里体现?

效果预览

背景知识

解决方案

以加载一个PDF文件,为其添加背景色为例:

import { common } from '@kit.AbilityKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { pdfService, PdfView, pdfViewManager } from '@kit.PDFKit';
import { systemDateTime } from '@kit.BasicServicesKit';

@Entry
@Component
struct PdfAddBgc {
  private controller: pdfViewManager.PdfController = new pdfViewManager.PdfController();
  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  @State filePath: string = '';
  @State curPage: number = 0;

  aboutToAppear(): void {
    let dir: string = this.context.filesDir;
    // 确保在工程目录src/main/resources/rawfile里存在test.pdf文档
    this.filePath = dir + '/test.pdf';
    let res = fs.accessSync(this.filePath);
    if (!res) {
      let content: Uint8Array = this.context.resourceManager.getRawFileContentSync('rawfile/test.pdf');
      let fdSand: fs.File | null = null;
      try {
        fdSand =
          fs.openSync(this.filePath, fs.OpenMode.WRITE_ONLY | fs.OpenMode.CREATE | fs.OpenMode.TRUNC);
        fs.writeSync(fdSand.fd, content.buffer);
      } catch (e) {
        console.error('fs.openSync failed error is : ', JSON.stringify(e));
      } finally {
        if (fdSand !== null) {
          fs.closeSync(fdSand.fd);
        }
      }
    }
    (async () => {
      let loadResult: pdfService.ParseResult = await this.controller.loadDocument(this.filePath);
      console.log('loadResult is ', loadResult);
      if (pdfService.ParseResult.PARSE_SUCCESS === loadResult) {
        this.controller.setPageZoom(1);
        // 监听滑动到第几页
        this.controller.registerPageChangedListener((pageIndex: number) => {
          this.curPage = pageIndex;
        });
      }
    })();

  }

  build() {
    Column({ space: 5 }) {
      Row() {
        Button('添加背景色').onClick(() => {
          // pdfDocument.saveDocument不支持编辑加载的文件,拷贝一份用来编辑
          let tempDir = this.context.tempDir;
          let tempEditFilePath = tempDir + `/tempEdit${systemDateTime.getTime()}.pdf`;
          fs.copyFileSync(this.filePath, tempEditFilePath);
          let pdfDocument: pdfService.PdfDocument = new pdfService.PdfDocument();
          // 编辑PDF文件时使用临时文件过渡
          let loadResult = pdfDocument.loadDocument(tempEditFilePath);
          if (pdfService.ParseResult.PARSE_SUCCESS === loadResult) {
            let pageCount = pdfDocument.getPageCount();
            let bgInfo: pdfService.BackgroundInfo = new pdfService.BackgroundInfo();
            bgInfo.backgroundColor = 20;
            bgInfo.isOnTop = true;
            bgInfo.rotation = 0;
            bgInfo.scale = 1;
            bgInfo.opacity = 0.3;
            bgInfo.verticalAlignment = pdfService.BackgroundAlignment.BACKGROUND_ALIGNMENT_TOP;
            bgInfo.horizontalAlignment = pdfService.BackgroundAlignment.BACKGROUND_ALIGNMENT_LEFT;
            bgInfo.horizontalSpace = 1;
            bgInfo.verticalSpace = 1;
            pdfDocument.addBackground(bgInfo, 0, pageCount, true, false);
            // 将添加背景色后的内容保存到源文件
            pdfDocument.saveDocument(this.filePath);
            // 释放PdfView组件中编辑前的PDF文件
            this.controller.releaseDocument();
            // 将通过pdfService编辑好的PDF文件加载到PdfView组件中
            this.controller.loadDocument(this.filePath, '', this.curPage);
          }
        })
      }
      .height('10%')

      PdfView({
        controller: this.controller,
        pageFit: pdfService.PageFit.FIT_NONE,
        showScroll: false
      })
        .height('90%')
        .id('pdfview_app_view')
        .layoutWeight(1);
    }
    .width('100%')
    .height('100%')
  }
}

常见FAQ

Q:编辑PDF文件后,重新进入页面,PdfView组件里还是展示的编辑前的效果。

A:编辑PDF文件后要及时保存,需要调用PdfView组件绑定的controller的saveDocument方法。

Q:编辑PDF文档的页面时,需要用到包括拆页、合页、旋转、缩放、创建等能力。

A:参考pdfService与PdfView能力比较;编辑能力可参考pdfService。