将WEB页面直接导出为pdf文件是经常会用到的一个功能,尤其是各种报表系统。总结了一下目前几种主流的做法:

  1. 在后端用代码生成pdf文件,比如iText一类;

  2. 在后端抓取页面并生成pdf文件,比如phantomjs一类;

  3. 在前端用js直接生成pdf文件;

方案3的优势在于前端直接生成,所见即所得。今天要探索的就是html2canvas和jspdf,前者用于将页面元素render生成canvas,后者用于将canvas生成pdf文档。需要注意的是,这种方法对IE系列支持不好。

html2canvas的主页:http://html2canvas.hertzen.com/

jspdf的主页:https://parall.ax/products/jspdf

两者的使用都比较简单,网上的文章很多,但是对于长网页导出,jspdf是不支持分页的,目前有一种做法是addImage时控制起始纵坐标为负值,然后超出页面底边的自动隐藏,就达到显示上的分页效果了,但这种方法无法给pdf页面留页边距,因此本文主要针对分页与页边距进行探索。

基本思路是对得到的canvas进行切割,按A4纸大小并留边距后的比例进行剪裁,切出一页一页的内容来,再分别加到pdf中。上个DEMO:

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试PDF导出</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="js/html2canvas.min.js"></script>
<script src="js/jspdf.min.js"></script>
<style>
html,body { margin:0; padding:0; }
#page ul { padding:0;list-style:none; }
#page li { line-height:110px;color:#fff;padding-left:10px; }
.c0 { background-color:#ea644a; }
.c1 { background-color:#f1a325; }
.c2 { background-color:#38b03f; }
.c3 { background-color:#03b8cf; }
.c4 { background-color:#bd7b46; }
.c5 { background-color:#8666b8; }
</style>
<script>
function exportPdf() {
var element = document.getElementById("page");
html2canvas(element, {
logging:false
}).then(function(canvas) {
var pdf = new jsPDF('p', 'mm', 'a4'); //A4纸,纵向
var ctx = canvas.getContext('2d'),
a4w = 190, a4h = 277, //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
imgHeight = Math.floor(a4h * canvas.width / a4w), //按A4显示比例换算一页图像的像素高度
renderedHeight = 0; while(renderedHeight < canvas.height) {
var page = document.createElement("canvas");
page.width = canvas.width;
page.height = Math.min(imgHeight, canvas.height - renderedHeight);//可能内容不足一页 //用getImageData剪裁指定区域,并画到前面创建的canvas对象中
page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);
pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)); //添加图像到页面,保留10mm边距 renderedHeight += imgHeight;
if(renderedHeight < canvas.height)
pdf.addPage();//如果后面还有内容,添加一个空页
delete page;
}
pdf.save('content.pdf');
});
} function generateData() {
var html = [];
html[html.length] = '<ul>';
for(var i = 0;i < 20;++i) {
html[html.length] = '<li class="c';
html[html.length] = i % 6;
html[html.length] = '">这是第';
html[html.length] = i;
html[html.length] = '行</li>';
}
html[html.length] = '</ul>';
document.getElementById('page').innerHTML = html.join('');
}
</script>
</head>
<body onload="generateData()">
<button onclick="exportPdf()">导出pdf</button>
<div id="page"></div>
</body>
</html>

核心的是exportPdf这个方法 ,感兴趣的同学可以参考。生成的pdf效果如图,可以看到分页和页边距效果:

页面直接导出为PDF文件,支持分页与页边距的更多相关文章

  1. 把页面上的图表导出为pdf文件,分享一种请求下载文件的方法

    最近客户提出一个需求,就是把页面上的图表导出为pdf文件. 找了很多资料.终于有了点头绪.最主要是参考了HighCharts的做法.http://www.hcharts.cn/ 实现原理:把页面图表的 ...

  2. Django分析之导出为PDF文件

    最近在公司一直忙着做exe安装包,以及为程序添加新功能,好久没有继续来写关于Django的东西了….难得这个周末清闲,来了解了解Django的一些小功能也是极好的了~ 那今天就来看看在Django的视 ...

  3. Studio for Winforms FlexGrid:导出到 PDF 文件

    本篇文章主要介绍如何导出 FlexGrid 到 PDF 格式文件.本文源于论坛用户,有多个用户提出如何把 FlexGrid 导出到 PDF 文件的需求.在这里共享给大家. 当前,ComponentOn ...

  4. 文本导出到pdf文件

    程序中数据导出是经常有的需求,今天学习把文本导出到pdf文件.主要是用QPrinter,QPainter TextEditToPdf::TextEditToPdf(QWidget *parent, Q ...

  5. 文本导出到pdf文件(使用QPrinter和QPainter和QTextDocument)

    程序中数据导出是经常有的需求,今天学习把文本导出到pdf文件.主要是用QPrinter,QPainter TextEditToPdf::TextEditToPdf(QWidget *parent, Q ...

  6. react框架下,在页面内加载显示PDF文件,关于react-pdf-js的使用注意事项

    react框架下,在页面内加载显示PDF文件,关于react-pdf-js的使用注意事项 之前做了一个需求,在注册账号的时候,让用户同意服务条款, 服务条款是一个PDF文件, 这就需要在react内加 ...

  7. 怎样把PDF文件中的一页提取出来

    现在随着网络科技的发展在网上找资源找文件就像家常便饭一样,但是有很多文件下载完成之后只有几页是需要的这时候就很困惑了,这么多怎么才能看完啊.这样为了不浪费时间可以将有用的一页提取出来,进行使用,那怎样 ...

  8. 【php导出pdf文件】php将html 导出成pdf文件(MPDF60),支持完美分页,注意是完美!!

    1.使用 MPDF60 包 2.防止中文乱码:修改MPDF/MPDF60/config.php中 $this->autoLangToFont = true; $this->autoScri ...

  9. freemarket+itext+springboot将html静态页面渲染后导出为pdf文件

    1.maven依赖 <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf& ...

随机推荐

  1. MySQL入门——在Linux下安装和卸载MariaDB

    MySQL入门——在Linux下安装和卸载MariaDB 摘要:本文主要学习了如何在Linux系统中安装和卸载MariaDB数据库. 查看有没有安装过MariaDB 使用命令查看有没有安装过: [ro ...

  2. java基础第十七篇之网络编程和装饰者模式

    1:网络概述 1.1 网络的发展Net 1964年,美国人---> 阿帕网--->以太网Internet 1.2 网络的通信协议 windows电脑,android手机,Mac平板---& ...

  3. 你不知道的JS第一卷

    这两天,开始看你不知道的JavaScript,第一卷.

  4. CarTool 使用,获取图片资源

    程序:gitHub: 项目地址 使用方法: 1.拿到资源包 在itunes里找到喜欢的应用,然后下载,直接将app拖到桌面.得到一个一个ipa资源包,如图 2.将资源包改成zip格式 3.解压zip资 ...

  5. BayaiM__MYSQL千万级数据量的优化方法积累__初级菜鸟

      -----------------------------------------------------------------------------———————-------------- ...

  6. mssql sqlserver 使用SSMS运行sql脚本的六种方法分享

    摘要: 下文讲述五种运行sql脚本的方法,如下所示: 实验环境:sql server 2008 R2 在一次会议讨论中,大家咨询我使用SSMS运行sql脚本的方法,下文我将依次举例讲述sql脚本的运行 ...

  7. Python—版本和环境的管理工具(Pipenv)

    pipenv简介 虚拟环境本质是一个文件,是为了适应不同的项目而存在.pipenv相当于virtualenv和pip的合体. 整合了 pip+virtualenv+Pipfile,能够自动处理好包的依 ...

  8. jacoco统计自动化代码覆盖率

    jacoco统计自动化代码覆盖率 1. 简介 1.1. 什么是Jacoco Jacoco是一个开源的代码覆盖率工具,可以嵌入到Ant .Maven中,并提供了EclEmma Eclipse插件,也可以 ...

  9. 关于destoon6.0下的ngnix伪静态

    关于destoon6.0下的ngnix伪静态配置 ##rewrite nginx rewrite '(.*)\.(asp|aspx|asa|asax|dll|jsp|cgi|fcgi|pl)(.*)' ...

  10. day82_10_31celery的使用

    1.缓存 当一些数据需要固定地且频繁访问数据库时,需要使用到接口缓存. 以轮播图为例,每个用户都会访问首页,首页的轮播图长时间不会改变,所以可以使用cache,将固定数据保存到缓存中(redis),第 ...