1

我正在尝试使用 PDFJS 从 PDF 中提取元数据并通过 Observable 订阅获取它。

服务代码:

export interface PdfProperties {
  title: string;
  author: string;
  subject: string;
  keywords: string;
}

...

  extractPdfProperties(file: Uint8Array): any {
    const pdfPropertiesObservable = new Observable<PdfProperties>( (observer) => {

      const pdfLoading = pdfjsLib.getDocument(file);
      pdfLoading.promise.then( pdf => {
        pdf.getMetadata().then( metadata => {
          this.pdfProperties.title = metadata.info.Title;
          this.pdfProperties.author = metadata.info.Author;
          this.pdfProperties.keywords = metadata.info.Keywords;
          this.pdfProperties.subject = metadata.info.Subject;
          observer.next(this.pdfProperties);
          return this.pdfProperties;
          });
        });
    });
    return pdfPropertiesObservable;
  }

组件代码

 onFileSelect(input: HTMLInputElement) {
    const fileReader = new FileReader();
    fileReader.readAsArrayBuffer(input.files[0]);
    fileReader.onload = () => {
      const typedArray = new Uint8Array(fileReader.result as Uint8Array);
      const pdfObservable$ = this.pdfProperties.extractPdfProperties(typedArray);
      pdfObservable$.subscribe((subscriptionpdfp: PdfProperties) => { this.pdfp = subscriptionpdfp; });

    };
  }

没有错误,但 this.pdfp 一直未定义。

我究竟做错了什么 ?

在此先感谢您的帮助!

4

1 回答 1

0

from您可以使用 RxJS函数将 promise 转换为observable,而不是手动创建observable。从那里您可以应用任何 RxJS 运算符将响应通知转换为您需要的形式。

我正在使用switchMap运算符从一个可观察对象映射到另一个对象,并使用map运算符将​​通知转换为实例类型的对象PdfProperties

尝试以下

export interface PdfProperties {
  title: string;
  author: string;
  subject: string;
  keywords: string;
}

extractPdfProperties(file: Uint8Array): Observable<PdfProperties> {    // <-- return an observable
  return from(pdfjsLib.getDocument(file).promise).pipe(   // <-- convert promise to an observable
    switchMap(pdf => from(pdf.getMetadata())),    // <-- switch to `getMetadata()` promise
    map(metadata => ({                            // <-- map to object of interface type `PdfProperties`
      title: metadata['info']['Title'],
      author: metadata['info']['Author'],
      keywords: metadata['info']['Keywords'],
      subject: metadata['info']['Subject']
    } as PdfProperties))
  );
}

onFileSelect(input: HTMLInputElement) {
  const fileReader = new FileReader();
  fileReader.readAsArrayBuffer(input.files[0]);
  fileReader.onload = () => {
    const typedArray = new Uint8Array(fileReader.result as Uint8Array);
    this.pdfProperties.extractPdfProperties(typedArray).subscribe((subscriptionpdfp: PdfProperties) => {
      this.pdfp = subscriptionpdfp;
    });
  };
}
于 2020-08-25T09:52:30.253 回答