最近有一个展示pdf文件的需求,而且还要展示合同中的签章,所以查了好多资料,先是用了pdf.js,但是在安卓手机闪退,所以又尝试了ng2-pdf-viewer这个插件,虽然在ios手机上签章展示不出来,最后还是使用了pdf.js,但我还是想把这次尝试的过程记录下来。来吧,进入正题
第一步,安装ng2-pdf-viewer
npm install ng2-pdf-viewer --save
安装之后让我们看一下它的目录结构
第二步,在项目中新建页面
ionic g page pdf-viewerPage
第三步,在app.module.ts添加代码,只贴出添加的代码
import {PdfViewerModule} from 'ng2-pdf-viewer';
import {PdfViewerPage} from "../pages/pdf-viewer/pdf-viewer";
@NgModule({
declarations: [
PdfViewerPage
],
imports: [
PdfViewerModule,
],
entryComponents: [
PdfViewerPage
],
})
第四步,html和ts中的写法
html
<ion-content (ionScroll)="scrollEvent($event)">
<pdf-viewer [src]="pdfUrl"
[show-all]="true"
[original-size]="false"
[zoom]=1
[render-text]="false"
[autoresize]="true"
style="display: block;"
(after-load-complete)="afterLoad($event)"
></pdf-viewer>
</ion-content>
ts代码
if (res.code == 2000) {
this.url = res.data;
this.pdfSrc = {
url: url,
// withCredentials: true
};
afterLoad(pdf) {
// 获取pdf文件总页数
this.totalPage = pdf.numPages;
}
import { Component, NgZone,ElementRef } from "@angular/core";
import { NavController, ModalController, NavParams } from "ionic-angular";
import { DomSanitizer } from "@angular/platform-browser";
import { Keyboard } from "@ionic-native/keyboard";
import { detailService } from "./detial.service";
@Component({
templateUrl: "detail.html",
providers: [detailService]
})
export class contractDetail {
url: any = "";
pdfSrc: any;
totalPage: any;
buttonShow: boolean = true;
show: boolean = false;
type: string = "";
contractId: string = "";
channel: string = "";
constructor(
public navCtrl: NavController,
public modalCtrl: ModalController,
public sanitizer: DomSanitizer,
private keyboard: Keyboard,
public navParams: NavParams,
public detailService: detailService,
public storage: Storage,
public ngzone: NgZone,
private funcs: Funcs,
public elementRef: ElementRef,
) {
// 这是重点
(<any>window).PDFJS.workerSrc = 'assets/js/pdf.worker.min.js';
}
ngDoCheck() {
}
ngOnInit() {
this.getDetail();
}
ionViewWillLoad() {
}
ionViewDidLeave() {
window.stop();
}
getDetail() {
this.detailService.getDetail(this.contractNo).then(res => {
if (res.code == 2000) {
this.url = res.data;
this.pdfSrc = {
url: this.url,
// withCredentials: true
};
});
}
scrollEvent(event) {
let hei1 = document.body.clientHeight;
let hei2 = this.elementRef.nativeElement.querySelector('pdf-viewer').clientHeight;
this.ngzone.run(() => {
this.show = false;
let top = event.scrollTop; //当前滑动的距离
if (height2 <= height1 + top) {
this.buttonShow = false;
}
})
}
// 获取pdf加载完成之后的总页数,然后判断只有一页的时候不展示提示语
afterLoad(pdf) {
this.totalPage = pdf.numPages;
if(this.totalPage <= 1){
this.show = false;
this.buttonShow = false;
}
}
}
一切准备ok之后开始踩坑之路了,具体如下:
1.首先我要展示合同中的电子签章,所以要注释掉pdf.worker.min.js中的隐藏签章的地方,这个pdf.worker.min.js和pdfjs中的pdf.worker.min.js是一样的文件,可以说是同一个。所以注释掉签章部分,具体请看我另外一篇博客:工作学习总结-pdf.js的采坑和运用
2.pdf.worker.js这个文件,我很纳闷安装这个插件的时候,会自动安装pdfjs‑dist插件,他却通过CDN远程调用pdf.worker.js。还好插件的说明文档给了相关提示,查阅源码的时候发现果然如此。(借用的)
所以我在当前页面代码中添加了这样一行代码(重点)
// 这是重点
(<any>window).PDFJS.workerSrc = 'assets/js/pdf.worker.min.js';
这个就相当于使用的是本地的pdf.worker.min.js,而不是cdn外联的。
可以看一下npm中对ng2-pdf-viewer的说明,npm链接地址是https://www.npmjs.com/package/ng2-pdf-viewer
Set custom path to the worker
By default the worker is loaded from cdnjs.cloudflare.com.
In your code update path to the worker to be for example /pdf.worker.js
(<any>window).pdfWorkerSrc = '/pdf.worker.js';
This should be set before pdf-viewer component is rendered.
但是最后还是有个问题,就是在项目中在ios手机上签章显示不出来,问题所在又没有找到,所以这个方案就没有用,但是在自己写的demo里面签章是可以显示出来的,可能是项目中的一些插件影响了,这个后期研究的时候再补充。