JavaScript实现html转pdf的三种方法详解

2024-03-01 0 986
目录
  • 方案选型
  • 准备工作
  • wkhtmltopdf
  • putteteer
  • html2canvas + jspdf
  • 方案对比

近期项目需要实现将 html 页面转换成 pdf 报告的需求,经过一番调研以及结合过往经验,发现了有如下三种技术方案,本篇文章主要内容是基于这三种不同方案的 demo 实现及对比。

方案选型

  • html2canvas + jspdf
  • wkhtmltopdf
  • node + puppeteer

准备工作

利用 chatgpt 生成一个报告的 html 模板,每页包含了一个表格和一个由 echarts 生成的柱状图。实际项目中基本也是这样的内容,文字 + charts,所以用这个来测试具有一定的参考意义,生成的 html 模板如下:

<!DOCTYPE html>
<html lang=\”en\”>
<head>
<meta charset=\”UTF-8\” />
<meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\” />
<title>Report Page</title>
<!– ECharts库 –>
<script src=\”https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js\”></script>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.page {
margin-bottom: 40px;
}
.chart {
width: 600px;
height: 400px;
margin-top: 20px;
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
text-align: left;
padding: 8px;
border-bottom: 1px solid #ddd;
}
</style>
</head>
<body>
<div class=\”page\” id=\”page1\”>
<h2>Page 1 – Data and Chart</h2>
<table>
<tr>
<th>Item</th>
<th>Value</th>
</tr>
<tr>
<td>Item 1</td>
<td>100</td>
</tr>
<tr>
<td>Item 2</td>
<td>200</td>
</tr>
<!– 更多列表数据 –>
</table>
<div id=\”chart1\” class=\”chart\”></div>
</div>

<div class=\”page\” id=\”page2\”>
<table>
<tr>
<th>Item</th>
<th>Value</th>
</tr>
<tr>
<td>Item 1</td>
<td>100</td>
</tr>
<tr>
<td>Item 2</td>
<td>200</td>
</tr>
<!– 更多列表数据 –>
</table>
<h2>Page 2 – Data and Chart</h2>
<!– 类似的列表和图表占位符 –>
<div id=\”chart2\” class=\”chart\”></div>
</div>

<div class=\”page\” id=\”page3\”>
<table>
<tr>
<th>Item</th>
<th>Value</th>
</tr>
<tr>
<td>Item 1</td>
<td>100</td>
</tr>
<tr>
<td>Item 2</td>
<td>200</td>
</tr>
<!– 更多列表数据 –>
</table>
<h2>Page 3 – Data and Chart</h2>
<!– 类似的列表和图表占位符 –>
<div id=\”chart3\” class=\”chart\”></div>
</div>

<script>
// ECharts 图表示例
var chart1 = echarts.init(document.getElementById(\’chart1\’));
var option1 = {
title: {text: \’ECharts 示例 1\’},
tooltip: {},
xAxis: {data: [\’类别1\’, \’类别2\’, \’类别3\’, \’类别4\’]},
yAxis: {},
series: [{type: \’bar\’, data: [5, 20, 36, 10]}]
};
chart1.setOption(option1);

// 为page2和page3重复上面的过程,设置不同的option配置
var chart2 = echarts.init(document.getElementById(\’chart2\’));
chart2.setOption(option1);
var chart3 = echarts.init(document.getElementById(\’chart3\’));
chart3.setOption(option1);
</script>
</body>
</html>

使用 http-server 在 html 页面目录下启动一个 web 服务器(没有 http-server, 参考这里安装 www.npmjs.com/package/http-server)

http-server . -p 9090

访问 http://127.0.0.1:9090/report.html,即可看到对应的报告模板页面,如下:

JavaScript实现html转pdf的三种方法详解

wkhtmltopdf

到这里 wkhtmltopdf.org/downloads.html 下载系统对应版本的安装包,然后安装好

执行如下命令,即可生成 pdf

wkhtmltopdf http://127.0.0.1:9090/report.html report.pdf

查看生成的 pdf 内容,能正常显示,看起来也没啥问题

JavaScript实现html转pdf的三种方法详解

实际报告肯定是有多页的,接下来我们尝试一下看看如何分页。在 page1 和 page2 元素后分别加入一个

元素,对应的 class 如下:

.page-break-after {
page-break-after: always;
}

然后再次执行转换命令,得到的 pdf 如下:

JavaScript实现html转pdf的三种方法详解

问题

偶尔会卡在某个进度不动,不知道为啥

JavaScript实现html转pdf的三种方法详解

执行时间不稳定,时快时慢

putteteer

安装就不多说明了,自行 google。安装好后,同样让 chatgpt 生成一段测试的代码,如下:

const puppeteer = require(\’puppeteer\’);

async function savePageAsPDF(url, outputPath) {
// 启动浏览器
const browser = await puppeteer.launch();
// 打开新页面
const page = await browser.newPage();
// 导航到指定URL
await page.goto(url, { waitUntil: \’networkidle2\’ });
// 保存页面为PDF
await page.pdf({ path: outputPath, format: \’A4\’ });
// 关闭浏览器
await browser.close();
console.log(`PDF已保存到:${outputPath}`);
}

// 调用函数保存网页为PDF
savePageAsPDF(\’http://127.0.0.1:9090/report.html\’, \’report1.pdf\’).catch(console.error);

执行转换脚本

node index.js

得到的 pdf 内容如下,看起来也没啥问题

JavaScript实现html转pdf的三种方法详解

html2canvas + jspdf

引入 html2canvas 和 jspdf 相关脚本

<script src=\”https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.2/html2canvas.min.js\”></script>
<script src=\”https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js\”></script>

添加下载按钮及转换函数

<button onclick=\”convertToPDF()\”>Convert to PDF</button>

<script>
async function addPage(id, pdf) {
const element = document.getElementById(id);

// 使用 html2canvas 渲染指定元素
const canvas = await html2canvas(element, {scale: 2});
const imgData = canvas.toDataURL(\’image/png\’);

// 使用 jsPDF 创建PDF文档
const imgProps = pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
// const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
const pdfHeight = (imgProps.height / imgProps.width) * pdfWidth;
// const pdfHeight = pdf.internal.pageSize.getHeight();
console.log(imgProps.width, pdfWidth, pdfHeight, pdf.internal.pageSize.getHeight());
pdf.addImage(imgData, \’JPEG\’, 0, 0, pdfWidth, pdfHeight, \’NONE\’, \’FAST\’);
}

async function convertToPDF() {
const pdf = new window.jspdf.jsPDF();

await addPage(\’page1\’, pdf);
pdf.addPage();
await addPage(\’page2\’, pdf);
pdf.addPage();
await addPage(\’page3\’, pdf);

pdf.save(\’converted.pdf\’);
}
</script>

访问页面,点击按钮即可下载 pdf 了,内容如下:

JavaScript实现html转pdf的三种方法详解

方案对比

wkhtmltopdf,依赖后端,配置比较灵活,但是速度好像不稳定

pupeteer,依赖后端,生成的 pdf 比较准确,质量也还可以

html2canvas + jspdf,纯前端实现,依赖少

以上就是JavaScript实现html转pdf的三种方法详解的详细内容,更多关于JavaScript html转pdf的资料请关注悠久资源网其它相关文章!

您可能感兴趣的文章:

  • JavaScript+Java实现HTML页面转为PDF文件保存的方法
  • 纯js实现html转pdf的简单实例(推荐)
  • Nodejs中使用phantom将html转为pdf或图片格式的方法
  • JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
  • Javascript实现html转pdf高清版(提高分辨率)
  • vue使用html2canvas和jspdf将html转成pdf
  • js将html页面转为pdf两种方法

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 JavaScript JavaScript实现html转pdf的三种方法详解 https://www.u-9.cn/biancheng/javascript/181976.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务