zoukankan      html  css  js  c++  java
  • pdf流文件的展示、下载、打印;html转为pdf

    背景:合同(后台返回pdf流文件)展示、下载、打印,基于angular4

    场景区分:

    1、checkout页面 —— post接口,入参为offering、shippingInfo、invoice等(body),返回生成合同的pdf流文件;

    2、orderList、orderDetail页面 —— get接口,入参contentId(生成合同在内容管理保存对应的id,url),返回对应合同的pdf流文件。

    需求补充说明:

    在一个弹出dialog,合同展示在中间部分,footer部分为 下载、打印等按钮。

    实现核心:

    1、展示:

    1> package.json中

      "dependencies": {

       "ng2-pdf-viewer": "^3.0.8",

       "pdfjs-dist": "^1.9.426" 

         }

    2> html

    展示:

      <pdf-viewer *ngIf ="contract.stc" [src]="contract.src" [render-text]="true"  (after-load-complete)="afterLoadComplete($event)" (error)="loadContractError($event)" ></pdf-viewer>

    下载:

      <a id="contract_download" class="fl mar1d5r mat6" [href]='sanitize(contract.src)' [download]="contract.name" *ngIf="contract.isLoadSuccess" >
        <svg class="hlds-icon fillWhite icon2r">
          <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="./assets/theme/default/icons/omniIcon-sprite/svg/symbols.svg#downLoad"></use>
        </svg>
      </a>

    打印:
      <a class="fl mat6" (click)="print()" *ngIf="contract.isLoadSuccess">
        <svg class="hlds-icon fillWhite icon2r" >
          <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="./assets/theme/default/icons/omniIcon-sprite/svg/symbols.svg#print"></use>
        </svg>
      </a>
      <iframe #iframe [src]="contract.url" style='display:none;' *ngIf="contract.isLoadSuccess" ></iframe>

    3>ts文件

      import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, ViewChild, ElementRef } from '@angular/core';
      import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';

      import { ConstantService } from '../../../../service/constant.service';
      import { MessageService } from "../../../../service/message.service";
      import { NormalHttpService } from "../../../../service/normal-http.service";

      import { SmartrecCommonService } from '../../../bizcommon/service/smartrec.service';
      import { OrderService } from '../../service/order.service';

      declare var $: any;

      @Component({
        selector: 'app-order-contract',
        templateUrl: './contract.component.html',
        styleUrls: ['./contract.component.css']
       })
      export class ContractComponent implements OnInit, OnChanges {
        /*contractInfo : any = {
          isGenerated : true,
          orderId: '',
          orderInfo : {} //the param that generate contract
        }*/
      @ViewChild('iframe') iframe: ElementRef;
      @Input() contractInfo : any ;
      @Output() acceptContractState = new EventEmitter<any>();

      contract : any = {
        src : '',
        url : '',
        totalPage : 1,
        page : 1,
        isLoading : true,
        isLoadSuccess: false
      }

      constructor(
       private sanitizer: DomSanitizer,
       private messageService: MessageService,
       private normalHttpService: NormalHttpService,
       private smartrecCommonService: SmartrecCommonService,
       private orderService: OrderService
      ) { }

      ngOnInit() {
      }

      ngOnChanges(change: SimpleChanges) {
        if(this.contractInfo && this.contractInfo.isGenerated && change.contractInfo.currentValue.orderInfo){
         this.contract.isLoadSuccess = false;
         this.generateContract();
          }
        if(this.contractInfo && !this.contractInfo.isGenerated && this.contractInfo.orderId) {
          this.queryContract();
        }
      }

      generateContract() {
       if(!this.contract.isLoadSuccess){
        this.contract.src = '';
        this.contract.isLoading = true;
        let header = this.normalHttpService.expandHeader({}, true);
        let url = this.normalHttpService.makeRequestUrl(`/order/order/${ConstantService.API_VERSION}/contract`);
        let xhr = new XMLHttpRequest();
        xhr.open("POST", url, true);
        xhr.responseType = "blob";
        for(let key in header) {
          xhr.setRequestHeader(key, header[key]);
        }
        xhr.send(JSON.stringify(this.contractInfo.orderInfo));
        xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
          let blob = new Blob([xhr.response], {type: 'application/pdf'});
          this.contract.src = URL.createObjectURL(blob);
          this.contract.name = 'contract.pdf';
          this.contract.url = this.sanitizer.bypassSecurityTrustResourceUrl(this.contract.src);
        }
      }.bind(this);
      }
    }

      queryContract() {
       this.contract.src = '';
       this.orderService.queryContractId(this.contractInfo.orderId).then((res) => {
        if (res.code !== 0) {
          this.messageService.errorAlert('Query contractId is failed !');
          return;
        }
        if (res.data.contentId) {
          this.contract.src = this.smartrecCommonService.getContentUrlById(res.data.contentId);
        }
       })
      }

      afterLoadComplete(pdf: any) {
        this.contract.totalPage = pdf.pdfInfo.numPages;
        this.contract.isLoading = false;
        this.contract.isLoadSuccess = true;
      }

      loadContractError(event: any) {
        this.contract.isLoading = false;
        this.contract.isLoadSuccess = false;
        this.messageService.errorAlert('Contract failed to load !');
      }

      agree() {
        this.acceptContractState.emit({
          isAgree : true,
          isLoadSuccess : this.contract.isLoadSuccess
        })
      }

      disAgree() {
        this.acceptContractState.emit({
          isAgree : false,
          isLoadSuccess : this.contract.isLoadSuccess
        })
      }

      print() {
        let getMyFrame = this.iframe.nativeElement.contentWindow || this.iframe.nativeElement.contentDocument;
        getMyFrame.print();
      }

      changePage(event) {
       const pageHeight = $('.ng2-pdf-viewer-container').height() / this.contract.totalPage;
       this.contract.page = Math.ceil($(event.target).scrollTop()/pageHeight);
      }

      sanitize(url:string){
        return this.sanitizer.bypassSecurityTrustUrl(url);
      }
    }

    备注:

    1.打印内容在弹框内如何实现:首先,打印调用的是window.print()方法。利用iframe标签,将弹框内容的路径,转移到iframe的src属性上,相当于为打印内容新开辟了一个window,最后回归到调用window.print()方法。

    参考:
    1.https://github.com/VadimDez/ng2-pdf-viewer //展示打印思路

    2.https://stackoverflow.com/questions/38457662/iframe-inside-angular2-component-property-contentwindow-does-not-exist-on-typ/50508477 //pdf局部打印思路

    3.http://kriscan.oschina.io/blog/2017/05/26/20170526/  //链接安全问题解决

    拓展:

    1.如何将html内容转换为pdf:a.html2cavas将页面内容screenshot下来;b.jsPdf将screenshot转换为pdf。

     

    
    


  • 相关阅读:
    通用权限管理设计 之 数据库结构设计
    jQuery LigerUI 插件介绍及使用之ligerDateEditor
    jQuery LigerUI 插件介绍及使用之ligerTree
    jQuery LigerUI V1.01(包括API和全部源码) 发布
    jQuery liger ui ligerGrid 打造通用的分页排序查询表格(提供下载)
    jQuery LigerUI V1.1.5 (包括API和全部源码) 发布
    jQuery LigerUI 使用教程表格篇(1)
    jQuery LigerUI V1.0(包括API和全部源码) 发布
    jQuery LigerUI V1.1.0 (包括API和全部源码) 发布
    nginx keepalived
  • 原文地址:https://www.cnblogs.com/lyue1404/p/9342518.html
Copyright © 2011-2022 走看看