Angular 2如何显示.pdf文件

31

我有一个Angular2应用程序,希望用户能够在浏览器中下载和打开PDF文件。

是否有可用的Angular2模块或组件可以使用?


你尝试过使用<object></object>吗? - Devidas Kadam
我已经开始收集https://pdfviewer.net/alternatives上所有可用的选项。目前,该网站的大部分内容都是关于我的库(ngx-extended-pdf-viewer)的。我很快会深入介绍其他替代方案。 - Stephan Rauh
10个回答

29

你有没有看过这个模块https://www.npmjs.com/package/ng2-pdf-viewer

记得在模块中进行声明,像这样:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms'; 
import { HttpModule } from '@angular/http';

import { PdfViewerComponent } from 'ng2-pdf-viewer'; 
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
    PdfViewerComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

是的,但它不起作用。当我在HTML文件中使用此组件的选择器名称时,它会出现错误。是否有其他组件或模块可用? - Ricky
请您能否提供一段代码片段以及您所遇到的错误? - Benji Lees
你是否已将“pdf-viewer”添加到模块声明中? - Benji Lees
好的,我刚刚在本地设置好了并且它可以工作。所以我很确定这个模块是有效的。我很乐意将带有示例 PDF 的示例推送上去。或者,您是否可以分享组件和模块代码的片段? - Benji Lees
请看这里 https://github.com/benjaminlees/angular-pdf。只需拉取并运行npm install即可。然后在运行ng-serve并转到端口4200之前,请确保您已全局安装了angular-cli。 - Benji Lees
显示剩余3条评论

25

ng2-pdf-viewer表现不错,但我希望PDF的显示效果像这个页面上https://pdfobject.com/static.html

不幸的是,我有一个PDF流而不是直接的PDF(链接结尾没有.pdf),如下:https://***********.idshost.fr/ws/********xfer/ws/download/3ca3dfa2-e89d-4f98-bcf2-55ad62bacfc6

响应结果如下(只粘贴了一部分):

%PDF-1.3 %Äåòåë§ó ÐÄÆ 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xTÍÛ6¼û)æØE[²ì89$i½=°×Ë@"µ"e}ôÉKõY:¬,]§k©ùfæwø;,÷^@yÄQ²é>Ù£ÿ¼â£1l ¶Ñj-âTßâ1üJ,>à æ{Ü©¦Ô6@¢

有类似以下的头文件

HTTP/1.1 200 OK
Date: Fri, 05 May 2017 11:00:32 GMT
Server: Apache-Coyote/1.1
Content-Disposition: attachment; filename="1/B_FILENAME*****.pdf"
Content-Type: application/pdf
Content-Length: 34723
Keep-Alive: timeout=5, max=96
Connection: Keep-Alive

我听说将content-disposition从attachment改为inline会让浏览器尝试打开它而不是下载,但我无法访问服务器,所以没有尝试。

我的PDF文件无法显示,出现空白视图或错误“无法加载PDF文档”(但对于某些罕见的带有<object>和<embed>的PDF文件可以正常工作,但对于未知原因的<iframe>不能)。

最终找到了一些有效的方法,也许可以帮助一些人,以下是代码(angular2):

.ts文件


    import {DomSanitizer,SafeResourceUrl} from '@angular/platform-browser'
    import {Headers} from "@angular/http/src/headers";
    import {ResponseContentType} from "@angular/http/index";

        //somewhere...
        this.getConsultationDocumentPDF(this.inputDataFile.hash).subscribe(
                        (data:any) => { // data type is Response, but since _body is private field i changed it to any

                            var file3 = new Blob([data._body], {type: 'application/pdf'});
                            this.dataLocalUrl = this.domSanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(file3));


                        },
                        error => {
                            console.log(error);
                        }
                    );

        public getConsultationDocumentPDF (pHash:string):Observable<Response> {
            return this.http.get(
                "https://***********.idshost.fr/ws/********xfer/ws/download/"+pHash,
                {
                    headers: new Headers({
                        "Access-Control-Allow-Origin": "*",
                        "Authorization": "Bearer "
                    }),
                    responseType:ResponseContentType.ArrayBuffer // YOU NEED THAT
                }
            );

        }

.html文件(任何一个都可以,iframe对我来说具有更多的功能,例如打印)


    <div *ngIf="dataLocalUrl != undefined">
        <h5>iframe whit local url</h5>
        <iframe width="500" height="600" [attr.src]="dataLocalUrl" type="application/pdf"></iframe>
        <h5>object whit local url</h5>
        <object [attr.data]="dataLocalUrl" type="application/pdf" width="100%" height="100%"></object>
        <h5>embed whit local url</h5>
        <embed [attr.src]="dataLocalUrl" type="application/pdf" width="100%" height="100%">
    </div>

希望这能帮助到一些人!

谢谢,这比 PDF 阅读器好多了。对我来说,所有三种解决方案都可以打印。了解它们之间的优缺点会很有帮助。 - Doomenik
1
我遇到了以下错误: 错误:在资源URL上下文中使用了不安全的值。有人能帮助我吗? - MPPNBD
不安全的值通常与净化有关,您是否忘记使用此函数 this.domSanitizer.bypassSecurityTrustResourceUrl() 了? @MPPNBD - Ambroise Rabier
1
@AmbroiseRabier,你好!我按照你说的做了,但是在构建项目后出现了“无法加载PDF文档”的错误。 - Pantera
@Pantera 也许你的PDF文件已经损坏了,响应是否与我粘贴的内容相似? - Ambroise Rabier
我尝试使用bypassSecurityTrustResourceUrl(url)方法,虽然不安全的警告已经消失了,但PDF文件仍被拒绝。 - Haifeng Zhang

6

尝试这个:

<embed src="/assets/pdf/pr.pdf" 
    style="width: 100%;height: 500px" 
    type="application/pdf">
< p >嵌入标签可以放置在模板中的任何位置。根据需要更改style属性和src。 < /p >

1
<embed>已经被弃用。这个W3资源推荐使用<object> https://www.w3docs.com/snippets/html/which-tag-is-better-to-use-embed-or-object.html。 - James

4
尝试使用 ng2-pdfjs-viewer(https://www.npmjs.com/package/ng2-pdfjs-viewer)。在构建 pdf 强应用时,它被证明是迄今为止最易于使用和最可靠的 - 你可以获得完整的图像查看器和许多附加功能 - 打印预览、自动下载、在新标签中打开、缩放、滚动、转到页面/命名目标、旋转文档等。它可以处理 PDF 流和实际 PDF 文件。如果您正在围绕在 Angular 中通过 web 浏览器提供 PDF 构建,该软件包将非常有帮助。

输入图像描述

  1. 安装
    $ npm install ng2-pdfjs-viewer --save

  2. 添加到应用程序模块

import { PdfJsViewerModule } from 'ng2-pdfjs-viewer'; // <-- Import PdfJsViewerModule module

@NgModule({
  imports: [
    PdfJsViewerModule // <-- Add to declarations
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. 使用它。
    <ng2-pdfjs-viewer pdfSrc="mydoc.pdf"></ng2-pdfjs-viewer>

当我在我的HTML组件中使用第3行时,会出现一个错误,提示`ng2-pdfjs-viewer'不是已知元素。你能展示一下更多的例子吗? - CatarinaRuna

2
我使用了ng2-pdf-viewer库来查看PDF文件内容,但当我们在内部网络环境中部署时,它无法连接链接https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/es5/build/pdf.worker.js以获取许可证,而该库受Apache许可证的保护不适用于商业用途

我决定使用object标签data属性,将PDF数据以base64格式从服务器读取。

我分享给那些关心此事的人。

从API读取PDF内容如下:

let content = DataHelper.getDataFromAPI();

点击显示内容按钮时使用。
 showData() {
    let content = DataHelper.getDataFromAPI();

    this.pdfContent =
      URL.createObjectURL(this.b64toBlob(content, 'application/pdf')) +
      '#toolbar=0&navpanes=0&scrollbar=0&view=FitH';

    this.pdfview.nativeElement.setAttribute('data', this.pdfContent);
  }

在HTML文件中使用对象标签,如下:
<button (click)="showData()">Show PDF Content</button>
<object #pdfview
[data]=''
type="application/pdf"
width="100%"
height="800px"
>
</object>

演示链接https://stackblitz.com/edit/angular-ivy-tdmieb


2
如果你想要带有高档工具栏的PDF阅读器,那么可以使用ngx-extended-pdf-viewer。它拥有所有必要的选项,例如打印、下载、页面导航等。
使用该库的方法:
  1. 使用npm i ngx-extended-pdf-viewer --save安装该库
  2. 将以下脚本添加到您的angular.json文件中

    "scripts": [ "node_modules/ngx-extended-pdf-viewer/assets/pdf.js", "node_modules/ngx-extended-pdf-viewer/assets/pdf.worker.js", "node_modules/ngx-extended-pdf-viewer/assets/viewer.js" ]

  3. 将"NgxExtendedPdfViewerModule"添加到您模块文件的导入部分

  4. 在您的组件中这样显示:

<ngx-extended-pdf-viewer src="'assets/example.pdf'" useBrowserLocale="false"> </ngx-extended-pdf-viewer>


2

试试这个。请将 filename.pdf 替换为您实际的路径和文件名。

 <object data="filename.pdf" width="100%" height="100%" type='application/pdf'>
   <p>Sorry, the PDF couldn't be displayed :(</p>
   <a href="filename.pdf" target="_blank">Click Here</a>
 </object>

0
你可以使用 Angular 的文件查看器包。
此包支持pdfpngjpegmp4格式。
安装:
npm i @taldor-ltd/angular-file-viewer ng2-pdf-viewer

使用方法:

AngularFileViewerModule 添加到你的模块导入中。

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AngularFileViewerModule } from '@taldor-ltd/angular-file-viewer';

import { AppComponent } from './app/app.component';

@NgModule({
  imports: [BrowserModule, AngularFileViewerModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})

class AppModule {}

platformBrowserDynamic().bootstrapModule(AppModule);

然后在您的组件中使用它

(PDF示例)

import { Component } from '@angular/core';

import { FileMimeType } from '@taldor-ltd/angular-file-viewer';

@Component({
  selector: 'app-root',
  template: `
    <tld-file-viewer [src]="src" [type]="type"></tld-file-viewer>
  `
})
export class AppComponent {
  src = 'http://www.africau.edu/images/default/sample.pdf';
  type = FileMimeType.PDF;
}

阅读更多内容


0

如果您想显示一个base64的pdf,您可以使用我的组件https://www.npmjs.com/package/ng2-image-viewer

它适用于angular 2+,并呈现Base 64图像、URL图像和Base 64 PDF,易于实现,您只需要:

1)运行npm install ng2-image-viewer --save

2)在您的angular-cli.json文件中添加以下代码:

"styles": [
     "../node_modules/ng2-image-viewer/imageviewer.scss"
],
"scripts": [
     "../node_modules/ng2-image-viewer/imageviewer.js"
],

3) 导入 ImageViewerModule

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,

    // Specify your library as an import
    ImageViewerModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

4)现在你可以按照自己的意愿使用它:

<!-- You can now use your library component in app.component.html -->
<h1>
  Image Viewer
</h1>
<app-image-viewer [images]="['iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==', 'https://picsum.photos/900/500/?random']"
[idContainer]="'idOnHTML'"
[loadOnInit]="true"></app-image-viewer>

这是一个演示 Ng2-Image-Viewer Showcase
更多信息请查看上面的链接 :)

0

这对我有用。我的错误是将responseType:ResponseContentType.ArrayBuffer放在头文件中,而不是里面:

{
     headers: new Headers({
        "Access-Control-Allow-Origin": "*",
        "Authorization": "Bearer "
     }),
     responseType:ResponseContentType.ArrayBuffer // YOU NEED THIS LINE
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接