the
contents you don’t want to print
如果需要设置不打印区域,加入如下样式:
其实就是引用了noprint样式的控件不打印;
下面是media的相关
media类型是CSS属性媒体类型,用于直接引入媒体的属性。其语法格式如下:
@media screen | print | projection | braille |
aural | tv | handheld | all
参数说明
screen:指计算机屏幕。
print:指用于打印机的不透明介质。
projection:指用于显示的项目。
braille:盲文系统,指有触觉效果的印刷品。
aural:指语音电子合成器。
tv:电视类型的媒体。
handheld:指手持式显示设备。
all:用于所有媒体。
2.使用微软提供的active控件打印
实现过程:先修改浏览器的安全级别,使浏览器接受此active控件(有必要用程序修改注册表,具体实现例子以下有链接),然后进行各项打印设置,最后调用客户端打印机打印。
这种办法可以应付绝大多数报表打印功能。对于打印的各种设置,如页眉页脚,分页打印等等都能支持,而且实现方式很简单。主要面临的问题有两个:
1,
需要手动设置浏览器,active控件也可能被个别杀毒软件误报(在修改注册表时~~)。
2,
浏览器的兼容性问题。对于WebBrowser.ExecWB(param1,param2)的参数设置,不同浏览器要求不同,同一浏览器不同版本参数也不同。笔者试了几个例子,在IE下可以运行,并且打印效果较好,但是试了下谷歌,火狐,直接无效(可能是active控件的原因,估计有解决方案),由于涉及的参数较多,时间所限没有深入尝试。
3,
Webbronser是IE内置的控件,使用IE浏览器无需用户做任何操作(好吧,安全级别设置还是要滴),但是其他浏览器的支持估计要费一番周折。
相关资料:
好吧在加个小例子:
<DIV align=center>
<OBJECT id=wb height=0 width=0
classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2
name=wb>OBJECT>
<INPUT οnclick=javascript:printit() type=button value=打印 name=button_print />
<INPUT οnclick=javascript:printsetup();
type=button value=打印页面设置 name=button_setup />
<INPUT οnclick=javascript:printpreview();
type=button value=打印预览 name=button_show />
DIV>
<SCRIPT language=javascript>
function printsetup(){
// 打印页面设置
wb.execwb(8,1);
}
function printpreview(){
// 打印页面预览
wb.execwb(7,1);
}
function printit()
{
if (confirm('确定打印吗?'))
{
wb.execwb(6,6);
}
}
SCRIPT>
三,使用其它软件自带的打印功能实现打印
用公布的javaAPI调用(此处以microsoft word例,当然,wps之类的软件也公布了java操作的API)。
目前项目里就是用的这种办法打印。
一般而言,这种打印方式只能在服务端(用户允许网站写入本地数据的方式只能是cookie,而且,不可能允许也不支持类似office这种缓存文件到本地)当然也可以远程调用打印机,。这里暂不描述。
由于调用的是其他软件的打印功能,对于打印过程中的各项问题都转移到了其他软件上,对应的优势当然也是其他软件打印功能的优势了,这里不赘述。
分析
优点:
第三方软件基本是经过良好测试的,所以他们的打印功能一般也是非常好用且人性化的。
使用office模板,可以很灵活地做出复杂的报表。稳定,功能强大,这两点基本确定了大多数复杂的文件打印是用这种方式,不过在某些场景中这种方式也许没法接受,这里列举出其劣势,根据实际场景选择。
缺点:
1,由于是在服务器端的打印,打印的即时设置也只能在服务器端。当客户端并发调用打印功能时,打印机采用的办法是加入多个任务到打印机。可以想象,当并发量很大时,打印机里被加入了一长串任务,及时性当然不好;另外,打印机所能支持的最大任务数有限;当并发打印超过了此设置时会有问题;
2,当需要部署到其他环境时(比如linux),需要在linux上安装office;这里的问题是:第三方软件可能没有发布linux版本或者其发布包所依赖的环境跟项目不匹配。(这种方式跨平台有风险啊)
3,对于项目中所遇到的问题:每次写一个文件到服务器,导致硬盘空间消耗变大;个问题好解决:在打印完成后调用一个方法删除临时文件;或者开一个线程,在系统无人使用时删除临时目录;另外,项目中打印缓存文件是放C盘的;这种做法不推荐,因为盘符只在windows中叫C:/ 。好一点的办法是在项目中开一个缓存目录,写入和删除缓存文件都是在项目内进行的;理论上,项目不应该依赖于其它不属于项目目录(为特定环境添加的配置除外)
相关资料
由于项目中本身就是用的这种方式,所以在这里不给出使用示例,不过注意在新配置环境或者更换jdk时,记得把在jacob的发布包中找到:
然后根据操作系统位数选择dll文件,复制到项目所使用的jdk的bin目录里
这里给出一篇介绍稍微全面的文档的地址:
四,使用java自带的打印功能
分析
Jdk在1.4以前没有打印相关包,在1.4以后开始加入java.awt.print。可以使用java.awt包其他样式设置打印报表的格式,使用print包的接口实现打印;这种打印方式的大致工作原理是:首先根据设置在内存中生成需要打印的报表备用;然后jdk会搜寻打印打印服务;在找到服务后调用print逐句将内存中的报表内容打印完毕;
注意这里是jdk搜寻打印服务,也就是说,可以借助jdk本身的跨平台性实现打印的跨平台;另外,jdk运行环境是服务器端,所以这种打印只会是在服务器端的打印;对于打印设置,由于PrinterJob(java打印服务对象)所接受的是一个
book对象,那么,当需要用户手动进行打印设置时,在浏览器端肯定需要用到java applet;不过并不是每一款浏览器都支持java,支持java的浏览器,也并不是总是允许applet程序运行;事实上,applet运行的限制很大,这会导致的问题是打印设置通常用户没法选择。还有,目前还没找到使用报表模板生成book对象的方法,所以报表格式的设置全部是在代码里;对于打印格式不能尽善尽美;
如果以上问题可以接受,使用jdk的打印是一个不错的选择;
相关资料
这里给出一个简单的实现,注意使用jdk1.4以后的版本
package
com.my.print;
import
java.awt.BasicStroke;
import
java.awt.Color;
import
java.awt.Component;
import
java.awt.Font;
import
java.awt.Graphics;
import
java.awt.Graphics2D;
import
java.awt.Image;
import
java.awt.Toolkit;
import
java.awt.RenderingHints;
import
java.awt.font.FontRenderContext;
import
java.awt.font.LineBreakMeasurer;
import
java.awt.font.TextAttribute;
import
java.awt.font.TextLayout;
import
java.awt.geom.Point2D;
import
java.awt.image.BufferedImage;
import
java.awt.print.Book;
import
java.awt.print.PageFormat;
import
java.awt.print.Paper;
import
java.awt.print.Printable;
import
java.awt.print.PrinterException;
import
java.awt.print.PrinterJob;
import
java.text.AttributedString;
import
javax.swing.JApplet;
public
class PrintTest implements Printable {
public static void main(String[] args) {
// 通俗理解就是书、文档
Book book = new Book();
// 设置成竖打
PageFormat pf = new PageFormat();
pf.setOrientation(PageFormat.PORTRAIT);
// 通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
Paper p = new Paper();
p.setSize(309,500 );// 纸张大小
p.setImageableArea(72, 72, 590, 840);// A4(595 X
// 842)设置打印区域,其实0,0应该是72,72,因为A4纸的默认X,Y边距是72
pf.setPaper(p);
// 把 PageFormat
和 Printable
添加到书中,组成一个页面
book.append(new PrintTest(), pf);
// 获取打印服务对象
PrinterJob job = PrinterJob.getPrinterJob();
// 设置打印类
job.setPageable(book);
try {
// 可以用printDialog显示打印对话框,在用户确认后打印;也可以直接打印
boolean a=job.printDialog();
if(a)
{
job.print();
}
} catch (PrinterException e) {
e.printStackTrace();
}
}
public int print(Graphics gra, PageFormat pf, int
pageIndex)
throws PrinterException {
System.out.println("pageIndex=" + pageIndex);
Component c = null;
// print string
String str = "这个是打印的内容";
// 转换成Graphics2D
Graphics2D g2 = (Graphics2D) gra;
// 设置打印颜色为黑色
g2.setColor(Color.black);
// 打印起点坐标
double x = pf.getImageableX();
double y = pf.getImageableY();
switch (pageIndex) {
case 0:
// 设置打印字体(字体名称、样式和点大小)(字体名称可以是物理或者逻辑名称)
// Java平台所定义的五种字体系列:Serif、SansSerif、Monospaced、Dialog 和 DialogInput
Font font = new Font("新宋体", Font.PLAIN, 9);
g2.setFont(font);// 设置字体
// BasicStroke bs_3=new BasicStroke(0.5f);
float[] dash1 = { 2.0f };
// 设置打印线的属性。
// 1.线宽
2、3、不知道,4、空白的宽度,5、虚线的宽度,6、偏移量
g2.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 2.0f, dash1, 0.0f));
// g2.setStroke(bs_3);//设置线宽
float heigth = font.getSize2D();// 字体高度
System.out.println("x=" + x);
// -1- 用Graphics2D直接输出
// 首字符的基线(右下部)位于用户空间中的
(x, y) 位置处
// g2.drawLine(10,10,200,300);
Image src = Toolkit
.getDefaultToolkit()
.getImage(
"D:\\EclipseWorkSpace3.1\\Kfc-wuxi\\WebRoot\\image\\KFC.jpg");
g2.drawImage(src, (int) x, (int) y, c);
int img_Height = src.getHeight(c);
int img_width = src.getWidth(c);
//
System.out.println("img_Height="+img_Height+"img_width="+img_width)
// ;
g2.drawString(str, (float) x, (float) y + 1 * heigth +
img_Height);
g2.drawLine((int) x, (int) (y + 1 * heigth + img_Height +
10),
(int) x + 200, (int) (y + 1 * heigth + img_Height +
10));
g2.drawImage(src, (int) x,
(int) (y + 1 * heigth + img_Height + 11), c);
return PAGE_EXISTS;
default:
return NO_SUCH_PAGE;
}
}
}
其他拓展请参与sun的api;