Angular2 - 使用 jspdf 从 HTML 生成 pdf

Angular2 - Generate pdf from HTML using jspdf

对于我正在处理的项目,我需要能够生成用户当前所在页面的 PDF,为此我将使用 jspdf。因为我有 HTML 需要生成 PDF,所以我需要 addHTML() 函数。关于这个的话题很多,说

You'll either need to use html2canvas or rasterizehtml.

我选择使用 html2canvas。这就是我的代码目前的样子:

import { Injectable, ElementRef, ViewChild } from '@angular/core';
import * as jsPDF from 'jspdf';
import * as d3 from 'd3';
import * as html2canvas from 'html2canvas';

@Injectable ()
export class pdfGeneratorService {

  @ViewChild('to-pdf') element: ElementRef;

  GeneratePDF () {
    html2canvas(this.element.nativeElement, <Html2Canvas.Html2CanvasOptions>{
      onrendered: function(canvas: HTMLCanvasElement) {
        var pdf = new jsPDF('p','pt','a4');

        pdf.addHTML(canvas, function() {
          pdf.save('web.pdf');
        });
      }
    });
  }
}

调用此函数时,出现控制台错误:

EXCEPTION: Error in ./AppComponent class AppComponent - inline template:3:4 caused by: You need either https://github.com/niklasvh/html2canvas or https://github.com/cburgmer/rasterizeHTML.js

这是为什么?我给了一个 canvas 作为参数,它仍然说我需要使用 html2canvas.

我发现有效的是添加:

<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>

到 index.html 文件(可能在其他地方)。

然后我使用了:

const elementToPrint = document.getElementById('foo'); //The html element to become a pdf
const pdf = new jsPDF('p', 'pt', 'a4');
pdf.addHTML(elementToPrint, () => {
    doc.save('web.pdf');
});

其中不再在代码中使用 html2canvas。
然后您可以删除以下导入:

import * as html2canvas from 'html2canvas';

这样试试:

GeneratePDF () {
    html2canvas(this.element.nativeElement, <Html2Canvas.Html2CanvasOptions>{
      onrendered: function(canvas: HTMLCanvasElement) {
        var pdf = new jsPDF('p','pt','a4');    
        var img = canvas.toDataURL("image/png");
        pdf.addImage(img, 'PNG', 10, 10, 580, 300);
        pdf.save('web.pdf');
      }
    });
  }

仍在尝试将 Html div 转换为 pdf 的任何人都可以选择使用 html2pdf,只需几行,您就可以轻松完成所有操作。

var element = document.getElementById('element-to-print');
html2pdf(element);

如果有人不喜欢使用 cdn 脚本并且想使用更多 (angular) 方式,这对我有用 Angular 6:

使用这种方式会在编辑器中为您提供更好的支持和自动完成功能,并且会帮助您避免依赖 cdn 脚本(如果您想避免它们,就像我一样)

基于 & 因为我很难找到那个答案,我正在重新分享其中所说的内容并帮助我在 Angular 6 中使用 jsPDF(所有功劳转到此答案的原作者)

你应该运行这些命令:

npm install jspdf --save

typings install dt~jspdf --global --save

npm install @types/jspdf --save

在angular-cli.json中添加以下内容:

"scripts": [ "../node_modules/jspdf/dist/jspdf.min.js" ]

html:

<button (click)="download()">download </button>

组件 ts:

import { Component, OnInit, Inject } from '@angular/core';
import * as jsPDF from 'jspdf'
@Component({
  ...
  providers: [
    { provide: 'Window',  useValue: window }
  ]
})
export class GenratePdfComponent implements OnInit {

  constructor(
    @Inject('Window') private window: Window,
    ) { }

  download() {

        var doc = new jsPDF();
        doc.text(20, 20, 'Hello world!');
        doc.text(20, 30, 'This is client-side Javascript, pumping out a PDF.');
        doc.addPage();
        doc.text(20, 20, 'Do you like that?');

        // Save the PDF
        doc.save('Test.pdf');
    }
}

这样使用stackblitz example

import {jsPDF} from 'jspdf';

@ViewChild('content', {static: false}) content: ElementRef;


public downloadPDF() {
   const doc = new jsPDF();

   const specialElementHandlers = {
      '#editor': function (element, renderer) {
       return true;
       }
   };

   const content = this.content.nativeElement;

   doc.fromHTML(content.innerHTML, 15, 15, {
      width: 190,
     'elementHandlers': specialElementHandlers
   });

   doc.save('fileName.pdf');
}

对于这个问题的新手,提示是你要注意你使用的jspdf是什么版本:

1.xx:

你需要先安装html2canvas

   npm install html2canvas

然后将其添加到 angular.json

中的脚本部分
//.angular.json  
 "scripts": [ 
               // make sure you have the correct path 
               "node_modules/html2canvas/dist/html2canvas.min.js"
            ]  
   // let data = this.htmlData.nativeElement; if you use it with @ViewChild('htmlData') 
    htmlData:ElementRef;
    let data = document.body;
    html2canvas(data).then(canvas => {
    // Few necessary setting options
    const imgWidth = 208;
    const pageHeight = 295;
    const imgHeight = canvas.height * imgWidth / canvas.width;
    const heightLeft = imgHeight;

    const contentDataURL = canvas.toDataURL('image/png')
    let pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF
    var position = 0;
    pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)
    pdf.save('new-file.pdf'); // Generated PDF
    });

2.xx:

1.xx 和 2.xx 之间有几个重大变化:

Removed APIs that were previously marked as deprecated. Namely: addHTML, fromHTML, html2pdf, addSvg, addButton, addTextField, addChoiceField, cellInitialize, setFontStyle, setFontType, clip_fixed.

所以之前的代码变成:

 // let data = this.htmlData.nativeElement; if you use it with @ViewChild('htmlData') 
 htmlData:ElementRef;
 let data = document.body;
    let options : any = {
      orientation: 'p',
      unit: 'px',
      format: 'a0',
      };
    let doc = new jsPDF(options);
     doc.html(data.innerHTML, {
      callback: function (doc) {
            doc.save("angular-demo.pdf");
          },
      margin:15,
      x: 10,
      y: 10
    });
  }

demo

请注意,在版本 2.xx 中,您不需要通过 npm 安装 html2canvas,甚至不需要包含脚本(在 angular.json 或 index.html 中),因为这是在内部动态完成。