4.
documents : document,
5.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
6.
var
jcp = getJCP();
8.
if
(how ==
'
打印预览
'
)
9.
jcp.printPreview(myDoc,
false
);
10.
else
if
(how ==
"
打印预览
(
显示进度条
)"
) {
11.
jcp.printPreview(myDoc,
true
);
12.
}
else
if
(how ==
'
弹出打印机选择对话框打印
'
) {
13.
jcp.print(myDoc,
true
);
14.
}
else
15.
jcp.print(myDoc,
false
);
//
不弹出对话框打印
17.
}
4.
getJCP().getPrinters(function(printers) {
5.
// printers
是取到的打印机列表,是一个字符串数组,每个元素表示一个打印机的名称
6.
var
printerlist
=
document
.getElementById('printer-list');
7.
//
填充到一个
select
中
8.
for (
i
=
0
; i
<
printers.length
; i++)
9.
printerlist.options[i + 1] = new Option(printers[i], printers[i]);
10.
printerlist.options[0]
.selected
=
true
;
11.
})
12.
}
13.
function doPrint() {
14.
var
printer
=
document
.getElementById('printer-list').value;
15.
var
myDoc
= {
16.
settings : {
17.
//
设置要输出的打印机
18.
printer : printer
19.
},
20.
documents : document,
21.
copyrights : '
杰创软件拥有版权
www.jatools.com'
22.
};
23.
jcp.print(myDoc, false); //
不弹出对话框打印
24.
}
25.
<script>
26.
...
27.
<body
onload
=
"loadPrinters()"
>
28.
...
29.
<select
id
=
"printer-list"
></select>
30.
...
利用
getPrinters
方法,使用户可以在
<select>
中选择输出打印机,同时,可以使用
js
的
cookie
方法,将用户最后一次选择的打印机,记录在
cookie
中,在下次打印时用
js
自动从
cookie
中取得上次使用的的打印机,设置到
<select>
默认选项中,这种方法让可以让用户,免去每次选择打印机的麻烦。
1.
//
取得
<select>
元素,用来放置可用纸张列表
2.
var
paperlist = document.getElementById(
"papers"
);
3.
//
取得虚拟打印机的可用纸张,
4.
getJCP().getPapers(
"Microsoft XPS Document Writer"
,
function
(papers) {
5.
for
(i = 0; i < papers.length; i++)
6.
//
将纸张名称,填充到
<select>
中
7.
paperlist.options[i + 1] =
new
Option(papers[i].name, papers[i].name);
8.
});
getPapers
返回的是一个
Object
对象数组,其中
name
属性是纸张名称。
某些打印机不能紧贴纸张边缘打印,这时,你不能把边距设得太小了,太小了会不起作用。
自动生成自定义纸张
有时,需要打印一些发票、快递单、发货单等,这些单据的大小,并不是标准的
A4
,
A5
之类,在默认的打印机驱动中,也不会内置这些纸张类型,所以在打印这类单据时,需要事先创建好相应大小的纸张,即所谓的自定义纸张。
如果使用浏览器来打印这些网页,那么,需要手工在控制面板,设备与打印机中,设置好这些规格的纸张,然后,再在系统页面选择对话框中,选用这个纸张。
使用
JCP
不需要这些手工设置,只需要在程序中,设置好纸张的高、宽即可,如下:
1.
var
myDoc = {
2.
settings : {
3.
paperWidth
: 200,
//
自定义纸张,
宽度为
200mm
4.
paperHeight
: 150
//
高度为
150mm
5.
// paperName : "A4", //
设置了
paperWidth,paperHeight
,就不要设置
paperName
了,二选一
6.
},
7.
documents : document,
8.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
9.
};
当
JCP
解析到
myDoc.settings
的
paperWidth
,
paperHeight
属性时,会自动到打印机的可用纸张中,查询是否有此规格的纸张,如果有,则选用之,如果没有则自动生成一个纸张并选用之。
自动生成的纸张名称为
jcp [
paperWidth
] x [
paperHeight
]
有些打印机,不支持自定义纸张,特别是一些激光打印机。判断打印机是否可以自定义纸张,可用
JCP
的
isCustomPaperSupported
方法
不要同时指定
paperName
和
paperWidth
,
paperHeight
,如果同时指定,则后者将被忽略。
设置打印份数
可以用
myDoc.settings.copies
属性,指定打印份数:
1.
var
myDoc = {
2.
settings : {
3.
copies : 3,
//
打印三份
4.
collate :
true
//
逐份打印,即以
1,2,3,...,1,2,3,... ,1,2,3,...
顺序打印
5.
},
6.
documents : document,
7.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
8.
};
9.
getJCP().print(myDoc);
可以用
collate
指定打印顺序:
true
,逐份打印,即
1
,
2
,
3
,
...
,
1
,
2
,
3
,
...
,
1
,
2
,
3
,
...
false
,为逐页打印,即
1
,
1
,
1
,
2
,
2
,
2
,
3
,
3
,
3
,
...
指定打印页
可以用
myDoc.settings
的
pageFrom
和
pageTo
属性,指定要打印的页面,如:
1.
var
myDoc = {
2.
settings : {
3.
pageFrom : 2,
4.
pageTo : 3
5.
},
6.
documents : document,
7.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
8.
};
9.
getJCP().print(myDoc);
5.
documents : document,
6.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
//
版权声明必须
7.
};
8.
getJCP().print(myDoc);
以上为双面打印,且为左侧装订。
当你的打印机不支持双面打印时,此设置无效。检测打印机是否支持双面打印,可以参照
getPrinterCapability
预设打印参数到注册表
想像一下,有这样的需求:既要允许用户自己设置打印机,纸张,又能让用户不必每次都去设置这些参数,以简化打印操作,我们可以利用
JCP
保存打印参数到注册表的功能来实现。
JCP
保存打印设置到注册表,就是将打印参数,如打印机、纸张类型、边距等,事先保存到注册表,并以一个
ID
标记,以后,直接打印时只要告诉
JCP
这个
ID
,
JCP
就会到注册表中找到对应的设置来打印了。以下是打印设置保存到注册表中的样子:
所有的打印设置,被保存在
HKEY_CURRENT_USER\Software\jatools\jatoolsPrinter
下,左侧注册项名称是设置
ID
,右侧是具体的打印设置。
假设给用户的界面是这样的:
2.
var
settings = {
3.
printer : document.getElementById(
'printer-list'
).value,
//
设置选中的打印机
4.
paperName : document.getElementById(
'paper-list'
).value,
//
设置选中的纸张
5.
orientation : document.getElementById(
'portrait'
).checked ? 1 : 2,
//
方向
6.
marginLeft : parseFloat(document.getElementById(
'leftmargin'
).value),
//
边距
7.
marginTop : parseFloat(document.getElementById(
'topmargin'
).value),
8.
marginRight : parseFloat(document.getElementById(
'rightmargin'
).value),
9.
marginBottom : parseFloat(document.getElementById(
'bottommargin'
).value)
10.
}
11.
getJCP().setLastSettings(
"
订单
"
, settings);
12.
}
代码先从界面上收集到设置的参数,放到一个
js
对象中,然后用
JCP
的
setLastSettings
方法将设置保存到注册表,该方法的第一个参数是设置
ID
,在直接打印代码中要用到,第二个参数是具体设置。
直接打印按钮要执行的代码:
1.
function
doPrint() {
2.
var
myDoc = {
3.
settingsId :
'
订单
'
,
//
引用设置
id
4.
documents : document,
5.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
6.
};
7.
getJCP().print(myDoc,
false
);
//
不弹出对话框打印
8.
}
直接打印时,不设置具体的打印参数,而代之以通过设置
myDoc. settingsId
的方式,让
JCP
使用保存在注册表中的设置,如果在注册表中,没有这个设置,
JCP
会使用系统的默认设置,如默认打印机,默认纸张等。
可以保存在注册表中的打印参数包括:
1.
var
myDoc = {
2.
settingsId:
"
订单
"
,
//
打印预览窗口中,点击打印后,将打印参数保存到注册表项目
订单
中
3.
documents : document,
4.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
getJCP().printPreview(myDoc,false);
4.
documents : document,
5.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
6.
};
7.
getJCP().print(myDoc,
false
);
//
不弹出对话框打印
8.
}
保存设置功能,通常用在以下两种情况:
(
1
)一个套打系统,由于各客户端打印机不同,或者进纸盒的位置不同,或者其他原因,可能引起打印出来的票据位置发生偏移,用户希望能根据自己打印机的状况,自行调整边距以纠正位置,但不希望每次打印前,都进行一次手工调整。
(
2
)一个客户端配置了多台打印机,分别用于打印不同类型的文档,用户不希望每次打印一个文档前,选择一次打印机;
对于第一种情况,你可以这样解决:
1.
页面中设置两个按钮,一个
"
直接打印
"
,一个
"
打印预览
"
;
2.
当客户发现位置有偏移时,可以点击
"
打印预览
"
按钮,调整左、上边距,并打印这个页面;
3.
如果发现位置还不理想,则重复第
2
步,如果正确,则下一次打印这个票据时,只需点击
"
直接打印
"
即可保证位置正确。
对于第二种多种打印机的情况,你可以这样解决:
1.
页面中设置两个按钮,一个
"
直接打印
"
,一个
"
打印预览
"
;
2.
第一次打印时,可以点击
"
打印预览
"
按钮,选择你想要的打印机进行打印;
3.
则下一次打印这个票据时,只需点击
"
直接打印
"
即可保证输出到正确的打印机。
提一点建议:因为
"
打印预览
"
按钮不常用,最好不要跟
"
直接打印
"
按钮并排放在一起,以避免干扰。
保存设置参数的工作原理是怎样的
?
JCP
是如何保留设置参数的,有些用户感觉困惑,下面介绍一下保留与加载打印参数的工作原理。
保存设置参数原理:
1.
客户打印一个文档到打印机后;
2. JCP
触发打印完成事件;
3. JCP
响应打印完成事件,查询本次打印是否有
myDoc.settingsId
属性,如果有,则保存本次打印的配置参数到注册表
(
如果注册表中存在该
id
设置,则替换以前设置
)
。
所以,保存打印参数的前提是:已经输出到打印机,并且设置了
myDoc.settingsId
。
有些用户,只在
JCP
的预览窗口中设置了边距等,而不实际打印,这样,
JCP
是不会保留你的设置的。
加载打印参数原理:
1.
客户在预览或打印前,
JCP
检查是否有
myDoc.settingsId
属性;
2.
如果有
myDoc.settingsId
属性,
JCP
尝试从注册表中读入该
id
相关的配置参数,如果存在,则用该配置参数来设置打印机(即忽略
myDoc.settings
里的设置),转第
4
步;
3.
根据用户的
myDoc.settings
里的设置,设置打印参数;
4.
根据设置,启动打印或打印预览。
删除注册表中的打印设置
你可以调用
clearSettings
方法,清除注册表中的打印设置项,如下:
1.
//
清除注册表中
id
为
mysettings1
的打印参数项
2.
getJCP().clearSettings(
"mysettings1"
,
function
(result) {
3.
console.log(
"
成功
?"
+result);
4.
})
你可以调用
getSettingsIds
取得注册表中的所有
settingsId
:
1.
getJCP().getSettingsIds(
function
(settings) {
2.
// settings
是一个字符串数组,表示在注册表中记录的所有
setttingsId
3.
for
(i = 0; i < settings.length; i++)
4.
console.log(settings[i]);
5.
})
1.
<div
id
=
'zc-page1'
>
资产负债表
,
第一页
(div#zc-page1)
</div>
2.
<div
id
=
'zc-page2'
>
资产负债表
,
第二页
(div#zc-page2)
</div>
3.
<div
id
=
'zc-page3'
>
资产负债表
,
第三页
(div#zc-page3)
</div>
4.
<br/>
5.
<div
id
=
'xj-page1'
>
现金流量表
,
第一页
(div#xj-page1)
</div>
6.
<div
id
=
'xj-page2'
>
现金流量表
,
第二页
(div#xj-page2)
</div>
7.
<div
id
=
'xj-page3'
>
现金流量表
,
第三页
(div#xj-page3)
</div>
怎么样让
JCP
区别打印?答案是使用
pagePrefix
属性,如下所示:
1.
var
myDoc = {
2.
pagePrefix :
"zc-"
,
//
仅打印
id
以
zc-
开始的页面
,
即
zc-page1,zc-page2,...
3.
documents : document,
4.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
5.
};
6.
getJCP().print(myDoc);
pagePrefix
+
page
+
页序号构成可打印
div
的
id
,
如本例前缀为
'
zc-
'
,则找到以
'
zc-page1'
为
id
的
div
作为文档首页,
该属性默认值为空。
不显示文档,直接指定url打印
2.
//
打印页面
page1,page2,...
在
url
:
pages.htm
指定的一个文档中
,
3.
documents :
"pages.htm"
,
4.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
//
版权声明必须
5.
};
6.
getJCP().print(myDoc);
你可以将
documents
属性设置成一个字符串,表示你想打印一个
URL
上的页面,该
URL
返回的页面中,有
id
为
page1
、
page2…
这样的
div
。
JCP
的
print
方法会自动请求这个
URL
上的页面,并打印之。
本例中,
URL
设置到
pages.htm
,看上去是一个服务端的静态文件,实际上,你也可以使用任何语言,框架产生的
HTML
文档流,比如
jsp
、
php
、
asp
等,也可以在
URL
上指定参数。
将
documents
设置为
document
,则打印页面
page1
、
page2…
必须已经显示在本文档中,而设置到
URL
,则意味着打印内容不必显示出来,就可以打印,设想这样的用户场景:
用户在一个订单列表中,勾选需要打印的订单,然后,按打印按钮进行打印,这时,你可以将用户勾选到的
id
作为参数,设置到
documents
:
1.
var
myDoc = {
2.
//
选择了
1,2,5
号订单,那么,后台返回
page1,page2,page3,
分别表示
1,2,5
号订单内容
3.
documents :
"getOrders.jsp?orders=1,2,5"
,
4.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
5.
};
6.
getJCP().print(myDoc);
你的服务端程序
getOrders.jsp
,解析
orders
参数,并返回相应的页面内容。
URL
返回的页面内,必须有
id
为
page1
的
div
,否则,
JCP
报不存在可打印的页错误。
打印预览一个隐藏的文档
有时,打印内容已经在当前文档
document
中,你可以将它们设置到一个隐藏的容器中,仍然可以用
JCP
打印出来:
1.
var
myDoc
= {
2.
documents : document,
3.
copyrights : '
杰创软件拥有版权
www.jatools.com'
4.
};
5.
getJCP().print(myDoc);
6.
...
7.
<div
style
=
""
>
8.
<div
id
=
'page1'
>
第一页
(div#page1)
</div>
9.
<div
id
=
'page2'
>
第二页
(div#page2)
</div>
10.
<div
id
=
'page3'
>
第三页
(div#page3)
</div>
11.
<div
id
=
'page4'
>
第四页
(div#page4)
</div>
12.
<div
id
=
'page5'
>
第五页
(div#page5)
</div>
13.
<div
id
=
'page6'
>
第六页
(div#page6)
</div>
14.
</div>
15.
...
不要将
,设置到
page div
上,这样会出现打印出空白页的情况。
打印<iframe>的页面
你可以打印
iframe
中的内容,只要该
iframe
里面包含
page1
,
page2
,
...
这样的打印
div
页面:
1.
<script>
2.
...
3.
var
myDoc
= {
4.
//
打印一个
iframe
里面的页面,该
iframe
的
id
为
myframe
5.
documents : document.getElementById("myframe").contentWindow.document,
6.
copyrights : '
杰创软件拥有版权
www.jatools.com'
7.
};
8.
getJCP().print(myDoc);
9.
</script>
10.
...
11.
<iframe
id
=
'myframe'
src
=
'pages.htm'
></iframe>
12.
...
可以用类似
document.getElementById("IFRAMEID").contentWindow.document
这样的形式,取得
iframe
里的
document
对象。
注意,打印
iframe
前,应该确保其已经加载完成,所以,如果你需要动态指定
iframe
的
src
属性时,应该在文档加载完成后,再调用
JCP
进行打印,如:
1.
function
main() {
2.
//
加载完成后,再打印
3.
loadFrame(
"getpages.jsp"
, doPrint);
4.
}
5.
function
doPrint() {
6.
var
myDoc = {
7.
documents : document.getElementById(
"myframe"
).contentWindow.document,
8.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
9.
};
10.
getJCP().print(myDoc);
11.
}
12.
function
loadFrame(src, callback) {
13.
//
加载完成后,回调
callback
14.
var
loaded =
function
() {
15.
callback();
16.
}
17.
var
frame = document.getElementById(
"myframe"
);
18.
if
(frame.attachEvent) {
19.
frame.attachEvent(
"onload"
, loaded);
20.
}
else
{
21.
frame.onload = loaded;
22.
}
23.
frame.src = src;
24.
}
3.
//
用
html
指定每页的
html
,数组,每个元素表示一页
4.
html : [
'<span>
我是老大,哈哈
!
</span>'
,
'<span id="second">
我是老二
!
</span>'
],
5.
style :
"span#second{font-size:150%;}"
//
可以用
style
指定所有页面的
css
6.
},
7.
//
当只有一页时,可以直接以字符串指定,如:
8.
//documents: {html:'<span>
我是老大!
</span>'},
9.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
10.
};
11.
getJCP().print(myDoc);
你可以将
documents
设置到一个
Object
对象,其属性
html
可以为一个字符串数组,表示每页中显示的内容,当只有一页时,
html
可以直接设置为一个
html
字符串。
如果你还想指定公用的
css
,可以同时指定
style
属性,此属性非必须。
打印指定的 HTML,可同时指定 page div 属性
上例打印
html
时,有个问题,就是不能指定
div
page1
上的属性,比如
style
等,如果你想指定
div
页上的属性,可以使用
pages
属性,如下所示:
1.
var
myDoc = {
2.
documents : {
3.
pages :
'<div id=page1 style="background-color:lightgray"><span>
我是老大,哈哈
!
</span></div><div id=page2><span id="second">
我是老二
!
</span></div>'
,
4.
style :
"span#second{font-size:150%;}"
//
可以用
style
指定所有页面的
css
5.
},
7.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
//
版权声明必须
8.
};
9.
getJCP().print(myDoc);
4.
documents : [
'sample1.htm'
,
'sample2.htm'
],
5.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
6.
};
7.
getJCP().print(myDoc);
本例将
sample1.htm
,和
sample2.htm
上的
page1
,
page2...
一次性打印出来,次序是先打印
sample1.htm
的页面,再打印
sample2.htm
上的页面。
以此方式指定的多个打印文档,在打印预览
printPreview
时,也是显示在一起的
.
sample1.htm
,
sample2.htm
,都必须有
page1
开始的
div
,页数可以不定,如:
sample1.htm
1.
<div
id
=
page1
>
...
</div><div
id
=
page2
>
...
</div>
正确的
sample2.htm
:
1.
<div
id
=
page1
>
...
</div>
错误的
sample2.htm
,没有
page1 div
,
JCP
会报不存在可打印的页:
1.
<div
id
=
page3
>
...
</div>
除了可以一次性打印不同的
URL
上的文档,还可以打印不同方式指定的打印内容,参照下节。
3.
document,
//
本文档中的
page1,page2,...,
4.
'sample1.htm'
,
// url
5.
{
6.
html : [
'<span>
我是老大,首先出场!
</span>'
,
'<span id="second">
我是老二,跟上!
</span>'
],
//
用
html
指定每页的
html
,数组,每个元素表示一页
7.
style :
"span#second{font-size:150%;}"
//
可以用
style
指定所有页面的
css
8.
}],
9.
copyrights :
'
杰创软件拥有版权
www.jatools.com'
//
版权声明必须
10.
};
11.
getJCP().print(myDoc);
本示例顺序打印以下三个文档:
1.
document
,即本页面上的
page1
、
page2...
;
2.
再打印
URL
,
sample1.htm
上的
page1
、
page2...
;
3.
最后打印
html
上指定的
html
。
以此方式指定的多个打印文档,在打印预览
printPreview
时,也是显示在一起的
.