Java打印程序设计.docx
Java打印程序设计1 MeF在我的的实际I:作中,常常须要实现打印功健.但由于历史缘由,JaVa供应的打印功能始终都比拟弱.事实上般初的Jdk根本不支持打印,宜到MkI.1才引入了很轻欧的打印支持.所以.在以前用Java/AppleVJSP/SerVtet设计的程序中,较困难的打印都是通过调用ACUVeXQCX控件或者VBNC程序来实现的,特别麻烦,事实上,SUN公司也始终致力于JaVa打卬功能的完善,而Java2平台那么用绻行r一个强他的打印模式的开端,该打印模式以Java2D图形包充分结合成体,更令人蚁招的是,新发布的jdk1.4那么供应了套完整的“Java打印效劳APr(JaVaPrintSerViCeAPI),它对已有的打印功能是主动的补充.利用它,我们可以实现大局部实际应用再求,包括打印文字、图形、文件及打印预览等等。本文将通过一个详细的程序实例率说明如何设计JaVa打印程序以实现这些功能.并对不同版本的实现方法进展分析比拟.吊电大家能从中获得一些有益的提示.2 Java中的打印2.1 Java的打印APlJava的打印API主要存在包中.而jdk1.4新增的类那么主要在在于javax.print包及其相应的子包和中.共中Javaxpnnt包中主要包含打FlJ效劳的相关类,而那么包含打印事务的相关定义.那么包括打印效劳的可用解性列表等.22如何实现打印要产生个打印,至少很要考虑两条:殖吃个打印效劳对象.这可通过三种方式实现I在Wkl.4之前的版本,必须要坡现接1.l或潮过TOOh1.getDefaUltToOlkiH).gelPnnUob来茨将打印效劳对象:在jdk1.4中那么可以通过来ft找定位个打印效劳时型.须要开场一个打卬工作.这也有儿种实现方法:在jdk1.4之前可以通过java.awt.print.PrintJob(jdk1.1供应的,现在1.l经很少用Tj调用Print或PrintAll方法开场打印工作:也可以通过的PrintDiaIOg显示打印对话框.然后通过Pdnl方法开场打印:在jdk1.4中那么可以通过的PnntDiaIog显示打印对话框,然后谡用Pnnt疗法开场个打印工作.2.3打印机对话柢Printable的打印对话框开场打印工作之前,可以通过PrinterJobprintDiaIog来显示一个打印对话框,它给用户一个时机以选择应当打印的页码范用,弁可供用户变更打印设置.它是一个本地对话框.于实上,当从一个PrintabIe对象进展一个打印工作时,打卬对象并不知道须要打印多少页.它只是不停地商用print方法,只要Prin方法返回Printable.PAGE-E×ISTS值.打印工作就不停地产生打印页,直到Pnnl方法返回PnntabIe.NO_SUCH_PAGE时.打印I:作才停侬.由于打印工作只有在打印完成后才进屣精确的页数计鸵,所以在对话框上的页码范国是尚未初始化的1,9999我仃可以通过构建个对望传递给打印对敞:也可以通过指定的格式让仇须要打印的页数并传递给打印对象使其精确地知道要打印多少页.2 3.2ServiceUI的打印对话框与Printable的对话极不同的是,.jdk1.4供应ServiceUI的打印机对话板的然省行为已经用新的API更改了:籍有状况下对话框不显示,我归必需运用ServiceUI类调用PrintDiaJog方法创立如卜,所示的打印对话框.3 JaVa打印程序设计实例3.1 打卬文本3.1.1 应用场景假设我们须要打印个窗体的某个文本编辑域(可能只有几行,也可能包含多页)的内容,并且俗页公多打卬54行,如何实现嗯?312诉决方法根木思路如下:首先我们须要实现PrintabIe接口,然后依据彩页G多54行的格式计。共须要打印多少页,当打印文本的按钿被点击时,执行相应的打FlJ动作.打印文本的详细操作可通过Graphics2D的drawString方法来实现.1.实HePrintabIe接1.JrGraphic指明打印的图形环境:PageFormat指明打印页格熄页面大小以点为计量单位,1点为1英寸的1/72,1英寸为25.4亳米,A4尔大致为595×842点):page指明页号Vpublicintprint(Grapicsg,PageFormatpf.intpage)throwsPrinterExceptionGrapics2Dg2=(Graphics2D)g;g2.setPaint(Colorblack);"设置打印色为黑色if(page>=PAGES)当打印页号大于须瞿打印的总页数时,打印工作完毕returnPrintable.NO_SUCH_PAGE;g2.tra11slate(pf.getlmageableX(),PtgetlmageabIeY();转换坐标.瑜定打印边界drawCuentPageTe×t(g2.pf.Page打印当前页文本returnPrintable.PAGE_EXISTS;存在打卬页时,接着打印工作)广打印指定页号的详细文本内容/privatevoiddrawCurrentPageTe×t(Graphics2Dg2.PageFormatpf,intpage)Strings=getDrawText(prinlSlr)pagM:狭得苜前页的待打印文本内容狭得默认字体及相应的尺寸FontRenderContextntext=g2.getFontRenderConteXt();Fontf=area,getFont();StringdrawText;floatascent=16:给定字符点阵intk,i=f.getSize()1lines=0;while(s.ength()>0&&lines<54)何页限定在54行以内(k=SjndeXOfon,);获得每个回车符的位置if(k!=-1)存在回车符(lines+=1;"计见行数drawTxt=s.subslrir>g(O.k):狭尔班行文本g2.drawString(drawTe×t.O.ascent);详细打印板一行文木.同时走纸移位if(SSUbString(k+1),length()>0)s=s.substring(k1);敌取尚未打印的文本ascent+=i;else不存在回车符(lines+=1;"计犯行数drawTe×t=s;获得征行文本g2.drawStrig(drawTextO.agent);详细打印每一行文本.同时走纸移位s=-;文本己完毕)广将打卬目标文木按页存放为字符率publicStringgetDrawTe×t(Strings)(Stnng(drawText=newStringPAGES;依抠页数初始化数组for(inti=0;i<PAGES;i+)drawTexti=数组元素初始化为空字符小intk.suffix=0,lines=0;while(s.legth()>0)(if(lines<54)"不锣,页时(k=s.indexf('n');if(k!=1)"存在回车符(lines+=1;行数取加计算该页的详细文本内容,存放到相应下标的数组元素drawTe×t(suffi×=drawTextsfxs.substring(O,k÷1);if(s.substring(k+1).length()>O)s=s.substring(k+1);)else(lines+=1;/行数我加“格文本内容存放到相应的数加元素drawTe×t(suffi×=drawTextsuffixs;s=":)else己淌-JiiBj(lines=0;行数统计清零SUffiX+;故抓下标加1)returndrawText;2,计算须要打印的总页数publicintgetPagesCont(StringcurStr)(intpage=0;intposition,count=0;Stringstr=curStr;w网StrIengthO>0)“文本尚未计算完毕(position=str.indexf('n');计同乍符的位置count=1;统计行数if(positionI=-1)str=slr.substring(postion+1);截取尚未计算的文本elsestr=”;文木己计尊完毕)if(ut>0)page=count/54+1;"以总行数除以54获得总页数returnpage;返同管打印的总页数3.1、 以jdk1.4以前的版本实现打印动作按钿监听.并完成详细的打印操作privatevoidprintTextAction()PrintStr=area.ge11xt().lnm():获得双要fjFIJ的11标文本if(printStr=null&&pnntStr.lenglh()>O)当打FlJ内容不为空时(PAGES=getPagesCont(printStrj;获得打卬总页数PnnterJobmyPrUob=P11nterJob.gtPnntrJob();我得默认打印作业PageFormatPageFOrmal=myPrtJob.defaultPage();茨得以认打印页面格式myPrtJobsetPrintable(this,pageFormat);"设翼打El)工作if(myPrUob.printDDtog()显示打印对话框(trymyPrtJob.print();进展捋页的详细打印操作)CatCh(PrinterEXCePtiOnpe)p.pnntStackTrac();)else假如打印内容为空时,提示用户打印将取消JOptionPane.showConfirmDialog(null,"Sorry,PrinterJobisEmpty,PrintCancelled!","Empt/.JoPtiOnPaneQEFAU1.T_OPTION,JOPtionPane.WARNING.MESSAGE);)3.2、 以JdkI.4新版本供应的APl实现打印动作按钮监听.并完成详细的打FlJ悚作privatevoidprintText2Action()PrintFIag=0:打印标记清零PrintStr=area.ge11xl().trim()力获得次要打印的目标文本if(printStr!=null&&pri11tStr.le11gth()>0)当打印内容不为空时(PAGES=getPagesCont(printStr):获得打卬总页数指定打印输出格式DocFIavorflavor=DocFlavorSERVICE-FORMATTED-PRlNTAB1.E;“定位默认的打卬效劳PrintServiceprintservice=PrintSerViCe1.OokUPjoOkUPDefaUitPrintSerViCe();创立打印作业DocPrintJobjob=prin(Service.createPrinUob);设跟打卬磁性PrintReqUestAttributeSetpras=newHashRrintRequestAttributeSetO;DocAttributeSetdas=newHashDocAttributeSetO;指定打印内容Docdoc=newSimpleDoc<this,flavor,das);不显示打印对话板.干脆进展打印工作tryjob.print(doc.PraS);进展好页的详细打印操作catch(PrintExceptk>npe)pe.pri11tStackTrace();else假如打印内容为空时,提示用户打印将取消JOptionPae.showConfirmDialog(null.,Sorry,PrinterJobisEmpty.PrintCancelled!"."Empty".JoPtionPaneQEFAU1.T_OPTION,JoPUOnPane.WARNING.MESSAGE);)3.2 打印预览应用场景大多少通业应用都须要供应打印预览机肥,它可以让我们在加薛上看到页面,这样就不会因为不应爱的打印结果而奢侈纸张.假设我的在打印上节所说的文本之前,须要先进展打印预览.郝么该怎么实现呢?界而实现图示如下:(NeXl预览下一页.PreVIeW预览前一页,CloSe那么关闭预览)解决方法根本思路:虽然Java2平台的打印APl并不供应标准的打印预览对话框,倒是自己来进戕设计也并不困愁,正常状况卜,Print方法将页面环境绘制到个打印机图形环境上,从而实现打印.而事实上,print方法并不能或正产生打印虹闻,它又足将待打印内容绘制到图形环境上,所以,我们可以忽视掉屏幕图形环境,经过适当的缩放比例.使整个打印页容纳在一个屏幕矩形里.从而实现精诚的打印预览.在打卬预览的设计实现中,主要须要解汰两个向物,第一.如何将打印内容按相宜的比例绘制到屏幕:其次,如何实现前后翻页.下面我给出这两个问题的详细实现方法,完整的实现谙修新附件中的PrintPreviewDiaIogjava文件。厂将待打印内容按比例绘IM到价值7publicvoidPaintCOmPOnent(GraPhiCSg)super,paintComponent(g);Graphics2Dg2=(Graphics2D)g:PageFormatpf=PrinterJob.getPrinterJob().defaultPage();花。,页面格式doublexoff;在屏卷上页面初始位置的水平偏移doubleyoff:在群筋上贞而初始位腔的垂直偏移doublescale:在扉传上适合页面的比例doublep×=pf.getVidth();页面宽度doublepy=pf.getHeight();页面高度doublesx=getWidth()-1;doublesy三getHeight()-1:if(pxpy<sxsy)scale=sy/py;“计烧比例×off=05*(sx-scale*px);水平偏移5yoff=0;else(scale=sx/px;"计JJ比例xoff=0;yoff=0.5*(sy-scale,py):垂直偏移5)g2.translate(float)×off,(AoatJyoff);转换坐标g2.scale(float)scale,(fk>at)scale);Rectangle2Dpage=newRectangle2D.Double(0,0,px.py):绘制页面如形g2.SetPaint(CoIorwhHe);设K页面背景为臼色g2.fill(page);g2.setPanI(CoIOr.black);“设置页面文字为黑色g2.draw(pag);trypreview.print(g2.pf,CUrrentPage);整示指定的预览页面)catc(PrinterExceptionp)g2.draw(new1.ine2D.Double(0,O.px.py);g2.draw(nev/1.ine2D.Dobe(0.px.O.py);)广预览指定的页面/publicvoidviewPage(intPOS)intne%vPage=CurrentPage+pos;指定页面在实标的范用内if(O<=nev/Page&&newPage<preview.getPagesCont(pri11tStr)CurrentPage=newPage:将指定页面贼俏为当l贞repaint();)这样.在按下Nexl”按钮时,只须要同用CanVaS.vewPage(1):而在按下'PrevieW按钿时,只须要调用CanVaS.ViewPage(M)即可实现预览的前后翻页.3.3 打印图形应用场景在实际应用中,我们还须要打卬图形。,tfJ,我们有时须要将一个JaVaAPPlet的完整界面或个陶用程序窗体及其所包含的全部组件都打印舟来.又应当如何实现呢?解决方法根木思路如下:在Java的Component类及其派生类中都供应了print和PrintAll方法,只要设置好帐性就可以干脆商用这两个方法,从而实现对姬件及图形的打印.广打印指定的帝体及其包含的坦件7privatevoidPrintFrameAetiOn()Toolkitkit=Toolkt.getDfaullToolkit();【:具箱Properbesprops=newProprtes();propsput("awtprintPrinter","durango");设置打印属性propsput("awtprintnumCopies","2,);if(kit=null)(获得工具箱自带的打印时象PrintJobprintjob=kit.getPrintJob(this,"PrintFrame*,props);if(printjobI=null)Graphicspg=PrintJob.gelGraphics():次将打印对型的图形环境if(pg!=null)try(this.printAII(pg);打印该窗体及其全部的组件)finallypg.dispose();注销图形环境)PrintJOb.end();/完毕打印作业)3.4 打印文件应用场景在许多实际应用状况下,我归可能都须要打卬用户指定的某一个文件,该文件可能是图形文件,1GIF.JPEG等等;也可能是文木文件,如TXT、Java文件等等:还可能是困难的PDF、DOC文件等等.那么对于这样的打印薪求,我们又应当加何实现呢?解决方法根本思路:在jdk1.4以前的版本.要实现这样的打印功能将特别麻燎和困难,甚至是不可思议的.但幸运的是.jdk1.4的打印效劳API供陶了一整警的打印文件旗的美和方法.利用它们.我们可以特别便利快徒地实现各种各样不同类型文件的打FlJ功能.下面给出一个通用的处理方法.八打印指定的文件/privatevoidprint()构造一个文件选推器,默认为当前书目J=newJ(SystemProperties.USER_DIR);intstate=(this);"弹出文件选择对话框if(state=)假如用户选定了文件(=():求得选择的文件构建打印恳求国性集PnntRequestAttnbuteSetpras=newKashRnntRequeslAttributeSetO:设置打卬格大,因为未确定文件类型,这电送并AUTOSENSEDocFIavorflavor=DocFlavor,INPUT_STREAM.AUTOSENSE;查找全部的可用打印效劳PnntServicePnnISerViceo=PrinISerViCe1.oOkUp.lOOkUPPrintSerVICeS(flavor,pras);“定位默认的打印效劳PrintServicedefaultservice=Printservice1.ookup100kupDefaultPrintService();“5示打印对话框PnntServiceservice=ServiceUI.pritDalog(null,200,200.MntService,defaultservice,flavor,pras);if(service!=null)(WyDocPrintJobjob=ServicexreatePrinUobO;创立打印作业fis=11ew(file);构造恃打印的文件流DocAttributeSetdas=newHashDocAttributeSetO:Docdoc=newSmpleDoc(fis.flavor,das):建立打印文件格式job.print(doc,pras);H进展文件的打印)catch(E×ceptione)e.pritStackTrace();)在上面的例如中,因尚未确定文件的类型,所以格指定文件的打印格式定义为.力实上,假如在进展打卬之前,就己确定地知道文件的格式,如为GIF,就应定义为DocFlavor.lNPUT_STREAM.GIF:如为PDF.就陶当定义为:如为纯ASCIl文件,就可以定义为.等等,jdk1.4的供应了极为K富的文fT流类型,你可以依据详细的应用需求进展相宜的选林。详细的API每考文档可见本文的参考资料34完毕语以上是本人在两年多J2EE应用开发中.总结的关于用JaVa进展打印程序设计的些经验,希里能给大家一些启示和律益.尽管目前用Java来实现打印功能与用Microsoft的MFCAPl相比的确有更多的麻烦,O!jdk1.4的推出,对JaVa以前较弱的打印动能是一个极好的补充,信任大家假如能的很好地理解用文所述的打印程序设计实例,并加以应用和拓展,应当可以解决H前大局部应用的实际编程何遨,而殖着JaVa的进步开械和克外,必将更好地充溢其根底类库及打印API,佑任用Java实现鸟级打印功能也将越来越不成为我们这些Java痴迷者头痛的何的