在 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 2 中将对象转换为 JSON 列表?