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。

     

    
    


  • 相关阅读:
    洛谷 P2695 骑士的工作
    洛谷 P2839 畅通工程
    hdu_5742_It's All In The Mind
    hdu_5734_Acperience
    hdu_5738_Eureka(脑洞)
    hdu_5724_Chess(组合博弈)
    Codeforces Round #363 (Div. 2)D. Fix a Tree(并查集)
    Codeforces Round #363 (Div. 2) B. One Bomb (水题)
    Codeforces Round #363 (Div. 2) C. Vacations(DP)
    hdu_5723_Abandoned country(最小生成树)
  • 原文地址:https://www.cnblogs.com/lyue1404/p/9342518.html
Copyright © 2011-2022 走看看