jsPDF参考:https://github.com/parallax/jsPDF
html2canvas参考:https://github.com/niklasvh/html2canvas 或者 https://html2canvas.hertzen.com
思路
- 使用html2canvas将选中DOM生成截图对象
- 将截图对象借助jsPDF导出为PDF文件
代码
这是一个示例,内容都放在了单个页面进行静态引用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>协议</title>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js"></script>
</head>
<style>
body {
/* font-family: Arial, sans-serif; */
text-align: center;
margin-top: 50px;
}
.contentBox {
text-align: left;
margin: 0vh 8vw;
}
h1 {
color: #333;
}
p {
font-size: 20px;
line-height: 1.5;
}
.canvasBox {
border: #333 0.5px solid;
height: 85vh;
}
</style>
<body>
<div id="xieyi" class="canvasBox">
<h1>协议</h1>
<p>在此文本中,我们将声明有关事项的协议。</p>
<p>请仔细阅读以下条款,并在同意后继续使用我们的服务。</p>
<h2>条款一:服务使用</h2>
<div class="contentBox">
<p><strong>1、服务使用:</strong>本协议规定了您使用我们服务的条款和条件。</p>
</div>
<h2>条款二:隐私保护</h2>
<div class="contentBox">
<p><strong>1、隐私保护:</strong>我们将保护您的个人信息和隐私。</p>
</div>
</div>
<button onclick="exportPDF()" style="margin: 2%;">保存</button>
</body>
<script>
// 获取时间
function getDateTime() {
let myDate = new Date();
let year = myDate.getFullYear();
let month = myDate.getMonth() + 1;
let day = myDate.getDate();
let hours = myDate.getHours();
let minutes = myDate.getMinutes();
let seconds = myDate.getSeconds();
let time = `${year}-${month}-${day}-${hours}_${minutes}_${seconds}`;
return time;
}
function exportPDF() {
var contentBox = document.getElementById('xieyi');
// console.log(contentBox.offsetHeight)
let domHeight = contentBox.offsetHeight;
let maxHeight = 64257;
html2canvas(contentBox, {
useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
scale: (maxHeight / domHeight) > 1 ? 1 : (maxHeight / domHeight)
}).then((canvas) => {
const contentWidth = canvas.width;
const contentHeight = canvas.height;
let pageHeight = contentWidth / 592.28 * 841.89;
let leftHeight = contentHeight;
//页面偏移
var position = 0;
//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
var imgWidth = 595.28; // A4 宽度
var imgHeight = 592.28 / contentWidth * contentHeight; // A4总高度
var pageData = canvas.toDataURL('image/jpeg', 1);
var pdf = new jsPDF('p', 'pt', 'a4');
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG2000', 10, 10, imgWidth - 20, imgHeight);
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG2000', 10, position + 10, imgWidth - 20, imgHeight)
leftHeight -= pageHeight;
position -= 841.89;
//避免添加空白页
if (leftHeight > 0) {
pdf.addPage();
}
}
}
let fileName = "XXX协议" + getDateTime();
pdf.save(fileName);
})
}
</script>
</html>
效果
因为计算了生成截图对象时的宽高,所以相对适配
宽高参考
'a0': [2383.94, 3370.39],
'a1': [1683.78, 2383.94],
'a2': [1190.55, 1683.78],
'a3': [841.89, 1190.55],
'a4': [595.28, 841.89],
'a5': [419.53, 595.28],
'a6': [297.64, 419.53],
'a7': [209.76, 297.64],
'a8': [147.40, 209.76],
'a9': [104.88, 147.40],
'a10': [73.70, 104.88],
'b0': [2834.65, 4008.19],
'b1': [2004.09, 2834.65],
'b2': [1417.32, 2004.09],
'b3': [1000.63, 1417.32],
'b4': [708.66, 1000.63],
'b5': [498.90, 708.66],
'b6': [354.33, 498.90],
'b7': [249.45, 354.33],
'b8': [175.75, 249.45],
'b9': [124.72, 175.75],
'b10': [87.87, 124.72],
'c0': [2599.37, 3676.54],
'c1': [1836.85, 2599.37],
'c2': [1298.27, 1836.85],
'c3': [918.43, 1298.27],
'c4': [649.13, 918.43],
'c5': [459.21, 649.13],
'c6': [323.15, 459.21],
'c7': [229.61, 323.15],
'c8': [161.57, 229.61],
'c9': [113.39, 161.57],
'c10': [79.37, 113.39],
'dl': [311.81, 623.62],
'letter': [612, 792],
'government-letter': [576, 756],
'legal': [612, 1008],
'junior-legal': [576, 360],
'ledger': [1224, 792],
'tabloid': [792, 1224],
'credit-card': [153, 243]