需求定义
我们的答题系统有一个子功能是统计全班学生测试后每一道题目的正确率,效果如下:
现在有个新的需求:将这个div所展示的内容导出为pdf文档
方案设计
html2canvas+jsPDF
通过html2canvas将DOM元素渲染成canvas image
通过jsPDF将image保存为pdf
相关依赖:
html2canvas:
<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js"></script>
jsPDF:
<script src="https://cdn.bootcss.com/jspdf/1.3.4/jspdf.debug.js"></script>
代码实现
function div2pdf(){
scroll(0,0); //把页面移到最顶端,使得每次获取图片的位置都是一样的
// 这个dom元素是要导出pdf的div容器,即要生成PDF的div
var element = $("#main5");
// 获得该容器的宽
var w = element.outerWidth()+25;
// 获得该容器的高,这里用scrollHeight才能获取真实的高度
var h = element.get(0).scrollHeight;
// 获得该容器到窗口顶部的距离
var offsetTop = element.offset().top;
// 获得该容器到窗口最左的距离
var offsetLeft = element.offset().left;
var canvas = document.createElement("canvas");
// 将画布宽&&高放大两倍,目的在于保存更高清的图片
canvas.width = w * 2;
canvas.height = h * 2;
var context = canvas.getContext("2d");
var scale = 2;
context.scale(2, 2);
context.translate(-offsetLeft, -offsetTop);
//html2canvasd的配置项
var opts = {
scale: scale,
canvas: canvas,
width: w,
height: h,
useCORS: true,
background: '#ffffff'
}
html2canvas(element.get(0), opts).then(function (canvas) {
// 得到canvas画布的单位是px 像素单位
var contentWidth = canvas.width
var contentHeight = canvas.height
// 将canvas转为base64图片
var pageData = canvas.toDataURL('image/jpeg', 1.0)
// 设置pdf的尺寸,pdf要使用pt单位 已知 1pt/1px = 0.75 pt = (px/scale)* 0.75,2为上面的scale 缩放了2倍
var pdfX = (contentWidth + 10) / 2 * 0.75
var pdfY = (contentHeight + 500) / 2 * 0.75 // 500为底部留白
// 设置内容图片的尺寸,img是pt单位
var imgX = pdfX;
var imgY = (contentHeight / 2 * 0.75); //内容图片这里不需要留白的距离
// 初始化jspdf 第一个参数方向:默认''时为纵向,第二个参数设置pdf内容图片使用的长度单位为pt,第三个参数为PDF的大小,单位是pt
var PDF = new jsPDF('', 'pt', [pdfX, pdfY])
// 将内容图片添加到pdf中,因为内容宽高和pdf宽高一样,就只需要一页,位置就是 0,0
PDF.addImage(pageData, 'jpeg', 0, 0, imgX, imgY)
//设置today作为文件命名
var day = new Date();
day.setTime(day.getTime());
var today = day.getFullYear()+"-" + (day.getMonth()+1) + "-" + day.getDate();
PDF.save('Accuracy_of_questions_'+today+'.pdf')
})
}
最终效果
如果按照标准的a4纸张大小进行分页,那么就会出现文字被上下两页给截断的问题。所以这里整个pdf只输出为非标准的一页。
参考资料
Javascript 将html转成pdf,下载,支持多页哦(html2canvas 和 jsPDF)
jsPDF 导出html为pdf内容截断终极解决方案
评论区