在 Angular 6 中将 HTML 转换为 PDF [关闭]

Posted

技术标签:

【中文标题】在 Angular 6 中将 HTML 转换为 PDF [关闭]【英文标题】:Convert HTML to PDF in Angular 6 [closed] 【发布时间】:2019-03-05 16:47:00 【问题描述】:

我有一个组件(Angular 6),它是几个组件的集合。这会产生一个长 html(我使用的是 Bootstrap 4)。现在我想将此 HTML 转换为 PDF。我进行了广泛搜索,发现了许多适用于 jsPDF 的解决方案。要求是在 HTML 中生成清晰的布局(以便用户可以选择、复制等)。但是我找到的解决方案要么尝试手动添加文本行,这在我的场景中是不可能的;或者他们将 HTML 转换(光栅化?)为图像格式。另外,我想保留 HTML 的格式、字体和样式。

到目前为止,我已经尝试过:this 和 this。

【问题讨论】:

【参考方案1】:

经过一番努力,我和我的团队针对我们自己的 Angular HTML 到 PDF 问题提出的最佳解决方案包括将原始 HTML 发送到我们的 Java API,然后使用带有 Java 包装器 (@987654322) 的 wkhtmltopdf (https://github.com/wkhtmltopdf/wkhtmltopdf) @)。克服了一些问题(比如确保服务器安装了正确的字体;一切都正确编码;找出分页符并让它们工作),我们能够准确地复制我们的页面并使用我们的 Angular HTML 作为通用模板(根据不同的场景变化)。这不是一条容易的路,但是一旦弄明白了,它就会在企业级的生产环境中产生很好的效果。

应该注意的是,我们也尝试了 jspdf(和其他库)并得出了与您类似的结论:他们只是没有做我们需要他们做的事情。希望这会有所帮助。

【讨论】:

您如何将原始 HTML 发送到您的 API? @Meqwz 已经有一段时间了,但我相信我们将其作为 64 位编码的 POST 正文发送。【参考方案2】:

尝试为此使用后端服务,例如 Thymeleaf 或 itextpdf 与 Spring Boot。

【讨论】:

【参考方案3】:

到目前为止,我能想到的最佳解决方案。

您必须从 npm 安装以下软件包

html2canvas

jspdf

import * as jsPDF from 'jspdf';
import html2canvas from 'html2canvas';

htmltoPDF()

    // parentdiv is the html element which has to be converted to PDF
    html2canvas(document.querySelector("#parentdiv")).then(canvas => 

      var pdf = new jsPDF('p', 'pt', [canvas.width, canvas.height]);

      var imgData  = canvas.toDataURL("image/jpeg", 1.0);
      pdf.addImage(imgData,0,0,canvas.width, canvas.height);
      pdf.save('converteddoc.pdf');

  );


更新:

想出了另一个解决方案。我无法将其分解为 A4 大小的页面,但我能够制作一个 pdf 文件。

包:

dom-to-image

jspdf

import domtoimage from 'dom-to-image';
import * as jsPDF from 'jspdf';



            downloadPDF()
            

              var node = document.getElementById('parentdiv');

              var img;
              var filename;
              var newImage;


              domtoimage.toPng(node,  bgcolor: '#fff' )

                .then(function(dataUrl) 

                  img = new Image();
                  img.src = dataUrl;
                  newImage = img.src;

                  img.onload = function()

                  var pdfWidth = img.width;
                  var pdfHeight = img.height;

                    // FileSaver.saveAs(dataUrl, 'my-pdfimage.png'); // Save as Image

                    var doc;

                    if(pdfWidth > pdfHeight)
                    
                      doc = new jsPDF('l', 'px', [pdfWidth , pdfHeight]);
                    
                    else
                    
                      doc = new jsPDF('p', 'px', [pdfWidth , pdfHeight]);
                    


                    var width = doc.internal.pageSize.getWidth();
                    var height = doc.internal.pageSize.getHeight();


                    doc.addImage(newImage, 'PNG',  10, 10, width, height);
                    filename = 'mypdf_' + '.pdf';
                    doc.save(filename);

                  ;


                )
                .catch(function(error) 

                 // Error Handling

                );



            

【讨论】:

这会将 PDF 直接保存到浏览器窗口。当 html2canvas 方法返回它自己的 promise 方法时,你如何将它分配给 Angular6 Observable?【参考方案4】:

首先安装以下内容: 1) npm 安装 jspdf 2) npm install html2canvas

稍后导入并使用以下代码

 public captureScreen() 
      const data = document.getElementById('invoice');
      html2canvas(data).then(canvas => 
      const imgWidth = 208;
      const pageHeight = 295;
      const imgHeight = canvas.height * imgWidth / canvas.width;
      const heightLeft = imgHeight;
      const contentDataURL = canvas.toDataURL('image/png');
      const pdf = new jspdf('p', 'mm', 'a4'); 
      const position = 0;
      pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
      pdf.save('invoice.pdf'); 
      );
      

【讨论】:

【参考方案5】:

以下代码已用于我的项目并为我工作

第 1 步:运行以下命令安装 npm 包

> npm install jspdf
> npm install html2canvas

第 2 步:在 app.components.ts 中导入已安装的包。我没有在 constructor() 中导入那些包

> import * as jspdf from 'jspdf';
> import html2canvas from 'html2canvas';

第 3 步:为必须导出为 PDF 的 HTML div 指定一个 ID。添加一个激活该功能的按钮。

<div id="MyDIv" style="margin-left: 45px;" class="main-container">

</div>
<div class="icon_image " title="Share As PDF" (click)="exportAsPDF('MyDIv');"><img src="assets/img/pdf.png"></div>

第四步:编写生成PDF的代码如下

exportAsPDF(div_id)
  
    let data = document.getElementById(div_id);  
    html2canvas(data).then(canvas => 
      const contentDataURL = canvas.toDataURL('image/png')  
      let pdf = new jspdf('l', 'cm', 'a4'); //Generates PDF in landscape mode
      // let pdf = new jspdf('p', 'cm', 'a4'); Generates PDF in portrait mode
      pdf.addImage(contentDataURL, 'PNG', 0, 0, 29.7, 21.0);  
      pdf.save('Filename.pdf');   
    ); 
  

【讨论】:

此代码需要来自 html 文件的 0 个参数。还是你在 .ts/.js 文件中省略了参数? 另外,代码pdf.addImage(contentDataURL, 'PNG', 0, 0, 29.7, 21.0)的格式是什么?【参考方案6】:

第 1 步:安装所需的软件包

npm install jspdf jspdf-autotable

第 2 步:导入已安装的包以使用

 import jsPDF from 'jspdf';
 import 'jspdf-autotable';

第 3 步:如果您的数据有图片,请将图片转换为 Base64

tabledata = [
    img: 'https://i.picsum.photos/id/258/536/354.jpg',
    name: 'Joseph',
    domain: 'Angular 9'
  ,
  
    img: 'https://i.picsum.photos/id/258/536/354.jpg',
    name: 'Vani',
    domain: 'Angular 8'
  , 
    img: 'https://i.picsum.photos/id/258/536/354.jpg',
    name: 'Raj',
    domain: 'React.js'
  ,
];

以上是图片转换为base64的数据。 转换函数如下所示:

convertImagetoBase64(url, callback) 
    const xhr = new XMLHttpRequest();
    xhr.onload = () => 
      const reader = new FileReader();
      reader.onloadend = () => 
        callback(reader.result);
      ;
      reader.readAsDataURL(xhr.response);
    ;
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();

在我们绑定到 HTML 中的表格之前,让我们将图像 URL 转换为 base64。

this.tabledata.forEach(elem => 
  this.convertImagetoBase64(elem.img, (b64Img) => 
    elem.img = b64Img;
);

现在将数据绑定到表。如果您不想在前端显示表格,只需将样式设置为不显示,如下代码所示:

<table id="imgTable" style=”display:none”>
<thead>
    <tr><th>Name</th>
    <th>Domain</th>
    <th>Image</th>
    </tr>
</thead>
<tbody>
    <tr *ngFor="let data of tabledata">
        <td>data.name</td>
        <td>data.domain</td>
        <td><img src="data.img"   /></td>
    </tr>

</tbody>
</table>
<button (click)="generatePdf()">Generate Pdf</button>

Generate Pdf 函数如下所示:

app.component.ts

generatePdf()
 doc.autoTable(
  html: '#imgTable',
  bodyStyles:  minCellHeight: 20 ,
  theme: 'grid',
  styles:  valign: 'middle', overflow: 'linebreak', halign: 'center', minCellHeight: 21 ,
  pageBreak: 'avoid',
  columnStyles: 
    2:  cellWidth: 22, minCellHeight: 22 ,
  ,
  headStyles:  fillColor: '#f2f2f2', textColor: '#000', fontStyle: 'bold', lineWidth: 0.5, lineColor: '#ccc' ,
  didDrawCell: (data) => 
    if (data.column.index === 2 && data.cell.section === 'body') 
      const td = data.cell.raw;
      const img = td.getElementsByTagName('img')[0];
      // let dim = data.cell.height - data.cell.padding('vertical');
      // let textPos = data.cell.textPos;
      doc.addImage(img.src, data.cell.x + 1, data.cell.y + 1, 19, 19);

    
  
);
 doc.save('yourpdfname.pdf');

pdf 生成示例如下所示:

更多PDF格式无表访问 helperscript.com

【讨论】:

【参考方案7】:

试试这个code 在 Angular 11 中将 HTML 页面转换为 PDF

安装依赖项:

npm install jspdf npm install html2canvas

更新 app.component.ts 文件

import  Component, OnInit, ElementRef, ViewChild  from '@angular/core';
import * as jspdf from 'jspdf';
import html2canvas from 'html2canvas';

@Component(
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
)
export class AppComponent 
    title = 'html-to-pdf-angular-application';
    public convetToPDF() 
        var data = document.getElementById('contentToConvert');
        html2canvas(data).then(canvas => 
            // Few necessary setting options
            var imgWidth = 208;
            var pageHeight = 295;
            var imgHeight = canvas.height * imgWidth / canvas.width;
            var 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
        );
    

更新 app.component.html 文件

<div>
   <strong>How To Convert HTML Page To PDF In Angular 11? - phpcodingstuff.com</strong>
</div>
<div>
   <input type="button" value="Convert" (click)="convetToPDF()"/>
</div>
<div>
   <table id="contentToConvert">
      <tbody>
         <tr>
            <th>Company</th>
            <th>Contact</th>
            <th>Country</th>
         </tr>
         <tr>
            <td>A Company</td>
            <td>Robert look</td>
            <td>Germany</td>
         </tr>
         <tr>
            <td>B Company</td>
            <td>Chnage</td>
            <td>Mexico</td>
         </tr>
         <tr>
            <td>C Company</td>
            <td>Mantodal</td>
            <td>Austria</td>
         </tr>
         <tr>
            <td>D Company</td>
            <td>Heltenosolu</td>
            <td>UK</td>
         </tr>
         <tr>
            <td>E Company</td>
            <td>tatumore</td>
            <td>Canada</td>
         </tr>
         <tr>
            <td>F Company</td>
            <td>verlose</td>
            <td>Italy</td>
         </tr>
      </tbody>
   </table>
</div>

享受这个Packages

【讨论】:

【参考方案8】:

我遇到了html2canvas 的问题,因此不得不使用html-to-image。我不知道为什么,但无论我尝试什么,html2canvas 都会呈现空白图像。 html-to-image 虽然轻松地给了我正确的渲染。

用作:

var node = <HTMLElement>document.getElementById('export');

htmlToImage.toPng(node)
           .then(function (dataUrl) 
                var img = new Image();
                img.src = dataUrl;

                var doc = new jsPDF('p', 'mm', 'a4');
                const bufferX = 5;
                const bufferY = 5;
                const imgProps = (<any>doc).getImageProperties(img);
                const pdfWidth = doc.internal.pageSize.getWidth() - 2 * bufferX;
                const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
                doc.addImage(img, 'PNG', bufferX, bufferY, pdfWidth, pdfHeight, undefined, 'FAST');
                doc.save('Bill_'+new Date().toDateString()); 
            )
            .catch(function (error) 
                console.error('oops, something went wrong!', error);
            );

【讨论】:

以上是关于在 Angular 6 中将 HTML 转换为 PDF [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在javascript中将数字转换为数组| angular7的打字稿[重复]

在 Angular 7 中将 Json 转换为对象

如何在 Angular 2 中将对象转换为 JSON 列表?

在Angular8中将HTTP响应json转换为打字稿对象

如何在 vc 6.0 中将对象转换或分配为 Variant 类型

如何在 Angular 中将 csv 或 excel 文件转换为 sql 输入数组?