`
kimmking
  • 浏览: 536363 次
  • 性别: Icon_minigender_1
  • 来自: 中华大丈夫学院
社区版块
存档分类
最新评论

jsPDF介绍与兼容IE的补丁

阅读更多

jsPDF介绍与兼容IE的补丁

KimmKing

2009429

前几天的JavaEye新闻频道介绍了jsPDF开源项目(《使用JavaScript,动态生成PDF)。

jsPDFJames Hall创建的一个在客户端使用纯JavaScript生成pdf文件的开源项目,项目在: http://code.google.com/p/jspdf/。目前只支持Safari,operaFirefox浏览器(奇怪,不支持占据绝对统治地位的IE~~~~)。

    js生成pdf?等等,pdf文件不是二进制的吗?JavaScript的一大遗憾就是不能直接操作二进制。呵呵,还真的勾起了本人对这个项目的兴趣。

    svn下了源码,呵呵,三个js文件:base64.jssprintf.jsjspdf.js。前两个都是开源的js类库。第一个看名字就知道是base64编码解码的函数库。打开文件看看,前两行就说明了出处:http://www.webtoolkit.info/。第二个还真不知道是做什么用的,c里的哪个输出函数?原来webtoolkit上也有,还真是源于c里的,格式化输出字符串的js函数。jspdf.js这个文件里的是生成pdf文件格式的函数。代码页不多,不到300行,短小精悍,使用简单,功能吗,自然也少,就两个功能addPagetextaddPage添加一个新的pdf页面。text则是在当前页面的指定位置写入文本。其实jspdf中实现了字体、长度单位、纸型等常见的参数设置,可惜的是作者没有把这些参数的设置暴露给外部调用的jsPDF对象(源代码分析以后再写吧,如果有机会的话)。可见目前的jsPDF不是一个稳定版本,还在完善中。另外作者写了一个添加图片的空方法未实现,添加图片实在是有一定的难度。

    一个典型的jsPDF应用如下:

jsPDF.init();

jsPDF.addPage();

jsPDF.text(20, 20, 'Hello world!');

jsPDF.text(20, 30, 'This is client-side Javascript, pumping out a PDF.');

jsPDF.addPage();

jsPDF.text(20, 20, 'Do you like that?');

var out = jsPDF.output();

var url = 'data:application/pdf;base64,' + Base64.encode(out);

document.location.href = url;

chrome浏览器中效果如下,呵呵,pdf出来了:

 

 

嚯嚯,看到了啥,没错,“data:application/pdf;base64,,这个东西,传说中的data url scheme,或者简称data协议。就是把数据放在后面,整个作为一个url使用,浏览器根据前缀的文件类型和编码(一般是base64),还原数据并展示,常用的例子比如小图片直接用这种方式编码到css代码中。(The "data" URL scheme: http://www.ietf.org/rfc/rfc2397.txt?number=2397)。可惜的是,IE作为一个特立独行的浏览器,一直没有实现这个标准。data协议在IE下无效。

 

IE下这么办呢?怎么能让jsPDFIE这破玩意儿下跑起来?想想,发挥下聪明才智,继承和发扬下中华民族的传统美德。

JavaScript生成pdf文件,就是说要先生成文件的文本内容,然后在新的页面打开,并让浏览器认为这个文件是pdf类型的。生成新的页面,无外乎:document.writelocation.hrefwindow.open

document.write 写出来的是HTMLJavaScript里还真是没有直接的办法让IE认为一个打开的窗口中的文档是其他的格式的。document.docType标识文档类型,只读。document.write不行,window.open一个空页面,写内容的方式也不可行。

IE不支持Data协议,那么,有没有类似的默认协议或处理方式呢?baidugooglemsdnxxxxxx,没找到。真的没有。IE可以自己定义url协议的,比如qq、迅雷、bt等等,在注册表里注册下自己写的处理程序就成。算了,这个自己写个data协议的处理程序,让用户装程序,意义不大(而且IEurl的长度限制是2083字节,随便什么base64下,都很容易超出来)。url带数据的方式也不太可行。

Data协议一般是把文件base64编码,嵌入到url里。IE下,常用的将文件嵌入到html里的技术,mht!呵呵。IE打开百度,另存为mht文件,再用记事本打开,果然base64的。不过,可惜的是,将pdfbase64写到mht文件,然后用IE打开,IE是不认的。就算IE能够识别mht中的pdf,引发的另一个问题是JavaScript生成mht需要的所有文字后,如何让IE认为这段文本是mht格式的?如果是一个文件或是url,以.mht结尾,IE认为是mht格式的。mht是个鸡肋。

最后一招,只能是写临时文件了,然后跳转到或是打开这个临时文件。base64都免了,直接存pdf文件就成了。JavaScript不支持io的,还好的是万恶又彪悍的ActiveX同学提供了需要的一切,一个系统内置的FileObjectSystem就足够用了。

修改jsPDF的思路如下:

1.   生成pdf文本

2.   判断浏览器类型

3.   IE浏览器还用原来的处理方式

4.   IE浏览器用fso取系统临时文件夹

5.   保存pdf文本为pdf文件

6.   跳转或是打开此pdf文件

需要注意的是,使用ActiveX组件需要降低IE的安全级别。如果是本地测试,需要在“工具”-Internet选项”-“安全”中降低“本地intranet”的安全性。如果是远程的web站点,则可以将站点的url添加到“可信站点”并降低次区域的安全性。运行时,按IE提示允许ActiveX运行即可。

    补丁文件:jspdf.fix.js,提供了一个统一的调用方法openPdf( pdfText, bBlank,  pdfName)pdfText为生成的pdf文本,bBlank为是href还是openpdfName表示IE下生成临时文件的文件名。


修改后的调用方式,(--就一句~~

jsPDF.init();

jsPDF.addPage();

jsPDF.text(20, 20, 'Hello world!');

jsPDF.text(20, 30, 'This is client-side Javascript, pumping out a PDF.');

jsPDF.addPage();

jsPDF.text(20, 20, 'Do you like that?');

var out = jsPDF.output();

qsoft.openPdf(out,false,'test');

IE下的效果:

 

 

 

 

 

 

分享到:
评论
25 楼 kms1989 2015-07-07  
导出pdf中文乱码怎么搞?
24 楼 kms1989 2015-06-30  
你好,请问不支持中文怎么解决?
23 楼 Cecily 2010-01-19  
请问可以用jspdf解析html标记吗,也就是说将表格也输出到pdf中?这样才可以生成图表啊
22 楼 elmar 2010-01-08  
ayeah 写道
js能做excel就好了

这个真的可以的
21 楼 elmar 2010-01-08  
Data协议真是蛋疼协议
20 楼 tipx 2010-01-07  
相当神奇的代码啊。
PDF这东西,果然还是后台后台
19 楼 kimmking 2010-01-05  
<div class="quote_title">ayeah 写道</div>
<div class="quote_div">js能做excel就好了</div>
<p> </p>
<p> 别说,还正能,</p>
<p>ie下 activex调用 Excel.Sheet或是owc中的spreadsheet,再不济就用csv或xhtml做伪excel文件</p>
<p>其他浏览器也是csv或xhtml做伪excel文件或data协议</p>
<p> </p>
<p>当然,纯js方面,zk  google的spreadsheet和jq的jqgrid不得不提。</p>
18 楼 loocao 2010-01-05  
mark.
17 楼 ayeah 2009-05-21  
js能做excel就好了
16 楼 chen115144 2009-05-17  
pior 写道
JS还真是很强大的说``但开发起来`太累了```可调试性很差``各浏览器的标准还不一样`

强烈赞同,可是不学js那Ajax怎么办?现在的客户都太挑剔了!
15 楼 tiyi 2009-05-17  
现在大家往js上走那么远真的是很恐怖。。
14 楼 struts 2009-05-16  
xingqili 写道
研究精神可嘉,可是这个东西感觉意义不大。即使js类设计的再好其功能也很难比得过用java写的这些开源pdf项目。况且js很难调试又很不稳定,谁会花时间在这上面呢

13 楼 pior 2009-05-14  
JS还真是很强大的说``但开发起来`太累了```可调试性很差``各浏览器的标准还不一样`
12 楼 bcw104 2009-05-08  
kimmking 写道
ftmouse 写道
太强大了。是否可以扩展到js报表打印上了?

js报表时啥报表?
js打印HTML
一般用隐藏不打印区域+调用webbrower来做

借用一下
11 楼 kimmking 2009-05-08  
ftmouse 写道
太强大了。是否可以扩展到js报表打印上了?

js报表时啥报表?
js打印HTML
一般用隐藏不打印区域+调用webbrower来做
10 楼 ftmouse 2009-05-08  
太强大了。是否可以扩展到js报表打印上了?
9 楼 xingqiliudehuanghun 2009-05-05  
研究精神可嘉,可是这个东西感觉意义不大。即使js类设计的再好其功能也很难比得过用java写的这些开源pdf项目。况且js很难调试又很不稳定,谁会花时间在这上面呢
8 楼 yangtse_ye 2009-05-04  
楼主强大
收藏学习
顺便再次鄙视IE一把...
7 楼 hax 2009-05-01  
楼主分析得不错。IE下要么无法实现,要么实现代价太大。

比如data协议也可以转由服务器产生(把data:...转化为http://data.example.org/...),但是如果这样,还不如直接由服务器产生pdf。

activex方案要求降低安全级别,这几乎没有实用价值,如果真要这样,还不如直接用产生pdf的控件。
6 楼 sulins 2009-04-29  
最终生成的pdf文件,对应pdf版本为1.3,简单了些。

相关推荐

Global site tag (gtag.js) - Google Analytics