JAVA打印功能总结文档

时间:2020-12-21 05:41:44
高手请斧正,菜鸟请虚心,引用请注明出处,转发请告知作者,谢谢尊重!

 

近期农信项目后台系统客户新提出需求的其中一项涉及到“打印”功能,前期技术储备时,发现网上相关资源甚少且混杂,特别是有关web打印技术,被码农们一致称为“老大难”。现整理了几项经本人验证的可行的打印方法,包括C/S和B/S的,供码友们参考。

 

一、C/S

1.利用java.awt中提供的打印API,继承Printable实现接口方法print进行打印。

参考文献:《Java实现打印功能》-----------百度文库。

此方法实际是C/S的打印方法,但是在某些特殊情况下,B/S的打印依然可用,例如在某些特殊的管理系统,操作此系统的用户可以非常方便的设置发布此系统的服务器,那么将服务器所连接的打印机设置成用户指定的打印机,此时再将代码设置成直接打印状态(不弹出打印提示页面),就可以顺利完成打印操作。

该方法的弊端也比较明显,java.awt所提供API实现接口的方法print,最后是用Graphics2D直接输出,所以有关长篇文字的格式只能手动调整(可参考官方API文档的格式调整算法),且参数中只有一个Graphics,以至于整篇文档的字体、颜色都是统一格式,无法调整(也许是本人对Graphics实在不了解),且无法操作页眉页脚(当以Word文档格式时);优点不用说,一般的打印还是可以实现的,且Graphics能画出来的也就都能打印出来,所以,此种打印方式所适用的和不适用的情况也就比较明显了吧。

 

以下是关键代码,详细请见文件夹下printHelp.java文件中内容。

package com.hepow.cbrc.help;

 

import java.awt.BasicStroke;

import java.awt.Color;

import java.awt.Component;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

importjava.awt.Image;

importjava.awt.Toolkit;

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.print.PageFormat;

import java.awt.print.Printable;

import java.awt.print.PrinterException;

importjava.text.AttributedString;

 

publicclassprintHelpimplementsPrintable {

/**

* @param Graphic指明打印的图形环境

* @param PageFormat指明打印页格式(页面大小以点为计量单位,1点为1英才的1/721英寸为25.4毫米。A4纸大致为595×842点)

* @param pageIndex指明页号

**/

       publicintprint(Graphicsgra,PageFormatpf,intpageIndex)throws PrinterException {

           System.out.println("pageIndex="+pageIndex);

           Component c =null;

          //print string

           String test = "根据国家劳动管理规定以及本公司员工聘用办法,甲方招聘乙方为试用员<br/>工,双方在平等、自愿的基础上,经协商一致签订本试用合同,共同遵守本协议所列条款"

                + "根据国家劳动管理规定以及本公司员工聘用办法,甲方招聘乙方为试用员工,双方在平等、自愿的基础上,经协商一致签订本试用合同,共同遵守本协议所列条款"

                + "根据国家劳动管理规定以及本公司员工聘用办法,甲方招聘乙方为试用员工,双<br/>方在平等、自愿的基础上,经协商一致签订本试用合同,共同遵守本协议所列条款"

                + "根据国家劳动管理规定以及本公司员工聘用办法,甲方招聘乙方为试用员工,双方在平等、自愿的基础上,经协商一致签订本试用合同,共同遵守本协议所列条款";

           String head ="劳动合同范本(二)——试用期劳动合同范本";

              String str ="";

              String str01 ="甲方:______________________";

              String str02 ="乙方: (身份证号)______________________";

              String str03 =" 根据国家劳动管理规定以及本公司员工聘用办法,甲方招聘乙方为试用员工,双方在平等、自愿的基础上,经协商一致签订本试用合同,共同遵守本协议所列条款";

              String str033 ="基础上,经协商一致签订本试用合同,共同遵守本协议所列条款。";

              String str04 ="一、试用合同期限:试用期为个月,自_____年_____月_____日至_____年_____月_____日止。";

              String str05 ="二、根据甲方的工作安排,聘用乙方在_______________工作岗位。";

              String str06 ="三、甲方聘用乙方的月薪为_____元(含养老、医疗、住房公积金)。试用期满后,并经考核合格,可";

              String str066 ="根据平等协商的原则,签订正式劳动合同。";

              String str07 ="四、甲方的基本权利与义务:";

              String str08 ="1.甲方的权利";

              String str09 =" 有权要求乙方遵守国家法律和公司各项规章制度;";

              String str10 =" 在试用期间,乙方如严重违反劳动纪律或企业规章制度,甲方有权终止合同。乙方的行为给甲方";

              String str100 ="造成损失的,由乙方赔偿,情节严重的追究法律责任;";

              String str11 =" 试用期间,乙方由于个人原因所发生的疾病以及伤残等意外事故,乙方自行负责;";

              String str12 ="2.甲方的义务";

              String str13 =" 为乙方提供必要的工作条件;";

              String str14 =" 负责对乙方进行职业道德、业务技能及公司规章制度的教育和培训;";

              String str15 ="五、乙方的基本权利和义务。";

              String str16 ="1.乙方的权利";

              String str17 =" 享有国家法律法规赋予的一切公民权利;";

              String str18 =" 享有公司规章制度规定可以享有的福利待遇的权利;";

              String str19 =" 试用期间如变更单位,须提前一个月通知甲方,双方协商终止试用合同;";

              String str20 ="2.乙方的义务";

              String str21 =" 遵守国家法律法规、当地*规定的公民义务;";

              String str22 =" 遵守公司的各项规章制度、员工手册、行为规范的义务;";

              String str23 =" 维护公司的声誉、利益的义务。";

              String str24 ="六、甲方的其他权利、义务";

              String str25 =" 试用期间,乙方不能胜任工作或弄虚作假不符合录用条件,甲方有权提前解除本合同;";

              String str26 =" 乙方有突出表现,甲方可提前结束试用,与乙方签订正式劳动合同;";

              String str27 ="七、乙方的其他权利、义务";

              String str28 =" 试用期满,有权决定是否签订正式劳动合同;";

              String str29 =" 具有参与公司*管理、提出合理化建议的权利;";

              String str30 =" 反对和投诉对乙方试用身份不公平的歧视。";

              String str31 ="八、本合同如有未尽事宜,双方本着友好协商原则处理。";

              String str32 ="九、本合同一式两份,甲、乙双方各执一份,具有同等效力,经甲乙双方签章生效。";

              String str33 ="甲方(盖章)                     乙方(盖章)";

              String str35 ="法定代表人签字:";

              String str36 ="签约日期:_____年_____月_____日";

              String str37 ="签约地点:";

          //转换成Graphics2D

          Graphics2D g2 = (Graphics2D) gra;

          //设置打印颜色为黑色

          g2.setColor(Color.black);

         

          /*Paper paper =pf.getPaper();//得到页面格式的纸张

          paper.setSize(500,500);//纸张大小

          paper.setImageableArea(0,0,500,500); //设置打印区域的大小

          System.out.println(paper.getWidth());

          System.out.println(paper.getHeight());

          pf.setPaper(paper);//将该纸张作为格式 */

 

          //打印起点坐标

          doublex =pf.getImageableX();

          doubley =pf.getImageableY();

          

          switch(pageIndex){

             case 0:

               //设置打印字体(字体名称、样式和点大小)(字体名称可以是物理或者逻辑名称)

               //Java平台所定义的五种字体系列:SerifSansSerifMonospacedDialog DialogInput

               Font font = new Font("新宋体", Font.PLAIN, 9);

               g2.setFont(font);//设置字体

               float[]dash1 = {4.0f};

               g2.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,4.0f,dash1,0.0f));

               floatheigth =font.getSize2D();//字体高度

               /*g2.drawString(head, 3*(float)x, (float)y + 1*heigth);

               g2.drawString(str, (float)x,(float)y + 2*heigth);

               g2.drawString(str01, (float)x,(float)y + 3*heigth+2);

               g2.drawString(str02, (float)x,(float)y + 4*heigth+2);

               g2.drawString(str03, (float)x,(float)y + 5*heigth+2);

               g2.drawString(str033, (float)x,(float)y + 6*heigth+2);

               g2.drawString(str04, (float)x,(float)y + 7*heigth+2);

               g2.drawString(str05, (float)x, (float)y+ 8*heigth+2);

               g2.drawString(str06, (float)x,(float)y + 9*heigth+2);

               g2.drawString(str066, (float)x,(float)y + 10*heigth+2);

               g2.drawString(str07, (float)x,(float)y + 11*heigth+2);

               g2.drawString(str08, (float)x,(float)y + 12*heigth+2);

               g2.drawString(str09, (float)x,(float)y + 13*heigth+2);

               g2.drawString(str10, (float)x,(float)y + 14*heigth+2);

               g2.drawString(str100, (float)x,(float)y + 15*heigth+2);

               g2.drawString(str11, (float)x,(float)y + 16*heigth+2);

               g2.drawString(str12, (float)x,(float)y + 17*heigth+2);

               g2.drawString(str13, (float)x,(float)y + 18*heigth+2);

               g2.drawString(str14, (float)x,(float)y + 19*heigth+2);

               g2.drawString(str15, (float)x,(float)y + 20*heigth+2);

               g2.drawString(str16, (float)x,(float)y + 21*heigth+2);

               g2.drawString(str17, (float)x,(float)y + 22*heigth+2);

               g2.drawString(str18, (float)x,(float)y + 23*heigth+2);

               g2.drawString(str19, (float)x,(float)y + 24*heigth+2);

               g2.drawString(str20, (float)x,(float)y + 25*heigth+2);

               g2.drawString(str21, (float)x,(float)y + 26*heigth+2);

               g2.drawString(str22, (float)x,(float)y + 27*heigth+2);

               g2.drawString(str23, (float)x,(float)y + 28*heigth+2);

               g2.drawString(str24, (float)x,(float)y + 29*heigth+2);

               g2.drawString(str25, (float)x,(float)y + 30*heigth+2);

               g2.drawString(str26, (float)x,(float)y + 31*heigth+2);

               g2.drawString(str27, (float)x,(float)y + 32*heigth+2);

               g2.drawString(str28, (float)x,(float)y + 33*heigth+2);

               g2.drawString(str29, (float)x,(float)y + 34*heigth+2);

               g2.drawString(str30, (float)x,(float)y + 35*heigth+2);

               g2.drawString(str31, (float)x,(float)y + 36*heigth+2);

               g2.drawString(str32, (float)x,(float)y + 37*heigth+2);

               g2.drawString(str33, (float)x, (float)y+ 39*heigth+2);

               g2.drawString(str, (float)x,(float)y + 43*heigth);

               g2.drawString(str35, (float)x,(float)y + 44*heigth+2);

               g2.drawString(str36, (float)x,(float)y + 45*heigth+2);

               g2.drawString(str37, (float)x,(float)y + 46*heigth+2);*/

             

               FontRenderContextfrc =g2.getFontRenderContext();

               TextLayout layout = new TextLayout(test,font,frc);

               AttributedString text = new AttributedString(test);

               text.addAttribute(TextAttribute.FONT,font);

               LineBreakMeasurerlineBreaker =new LineBreakMeasurer(text.getIterator(),frc);

               doublewidth =pf.getImageableWidth();                                        //每行字符显示长度()

               Point2D.Double pen = new Point2D.Double (100,y+3*heigth);                    //首字符的基线位于用户空间中的 (x, y)位置处

               while ( (layout =lineBreaker.nextLayout((float)width)) != null){

                  layout.draw(g2, (float)x, (float)pen.y);

                  pen.y +=layout.getAscent();

               }

             returnPAGE_EXISTS;

             default:

             returnNO_SUCH_PAGE;

          }

     }

}

 

调用时:

//获取打印服务对象方法1

Book book =new Book();

PageFormat pageFormat =new PageFormat();        //设置成竖打

pageFormat.setOrientation(PageFormat.PORTRAIT);

//通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。

Paper pager =new Paper();                       

pager.setSize(590,840);                          //纸张大小

//A4(595 X 842)设置打印区域,其实00应该是7272,因为A4纸的默认X,Y边距是72

pager.setImageableArea(72,72, 590, 840);        

pageFormat.setPaper(pager);

// PageFormat Printable添加到书中,组成一个页面

book.append(new printHelp(),pageFormat);        

PrinterJob job = PrinterJob.getPrinterJob();     //获取打印服务对象

job.setPageable(book);                           //设置打印类

try {

//Boolean a = job.printDialog();//显示打印提示窗口

//if(a) {

job.print();

//}

 

} catch (Exceptione) {

e.printStackTrace();

}

 

//获取打印服务对象方法2

PrinterJob job = PrinterJob.getPrinterJob();

PageFormat pageFormat =job.defaultPage();//得到默认页格式

job.setPrintable(new printHelp());//设置打印类

 

try {

//Boolean a = job.printDialog();//显示打印提示窗口

//if(a) {

job.print();

//}

} catch (PrinterExceptione) {

e.printStackTrace();

}

 

以上方法的弊端催生了关于打印的另一种思路,那就是利用Java操作Word(或其他文件),然后让Word去打印这种曲线救国思路。一开始我真的以为这是个好想法,但是后来我发现确实只是个好的“想法”而已,我可以用java POI实现对Word内容的读取写入,但是我实现不了通过java让Word自己去触发打印动作(网上资料说java不支持这种方法<纯代码方式实现>,可作者依然坚信这种方法是有大神可以实现的)。

对于该技术研究到此时算是遇到了瓶颈,作者不免在办公室里小发牢骚目的是寻求身边其他码友的帮助,此时王琦(本社IOS码神)帮我找到了网上的一份资源,让我不禁感慨码界里还是神多。不再啰嗦,请看:

 

2.史上最强大Java Word(文件)打印方案

参考文献:(1)《史上最强大Java Word打印方案》------- http://blog.csdn.net/ylz2007/article/details/41172653

(2)http://*.com/questions/2446721/how-to-get-print-out-of-a-ms-word-file-from-java-application

 

publicvoidprintWordFile(Stringfilename){

try{

Runtime.getRuntime().exec("cmd.exe /c start /min winword " +filename+" /q /n /f /mFilePrint/mFileExit");

}catch(Exceptione){

logger.info("打印异常:" +e.getMessage());}}

 

调用代码:

printWordFile("D:\\Users\\Desktop\\tomcat部署文档-new.docx");

 

这个的具体解释我就不再多说了,C/S打印中终极中的终极,曲线中的曲线!

 

小结:

利用com组件进行打印功能的实现由于本人没有亲试过,所以也就不敢造次,还请路过的你亲自研究。

 

二、B/S

1.最直接,最科普的打印方式:window.print()以及WB.execWB()

用window.print()可以直接打印整个页面的内容,也可以打印指定部分的内容。这个是比较科普的方式,但是,其功能之简陋也是比较科普的。

网页WB.ExecWB控件打印方法:

4,1保存网页  

4,2保存网页(可以重新命名)  

6,1直接打印  

6,2直接打印  

7,1打印预览 

7,2 打印预览  

8,1选择参数  

8,2选择参数  

10,1查看页面属性  

10,2查看页面属性  

17,1全选  

17,2全选  

22,1重新载入当前页  

22,2重新载入当前页

 

<OBJECT   classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2    height=0   id=WebBrowser    width=0></OBJECT>   

   <input   name=Button   onClick=document.all.WebBrowser.ExecWB(1,1)    type=button    value=打开>  

   <input   name=Button    onClick=document.all.WebBrowser.ExecWB(2,1)    type=button    value=关闭所有>  

   <input   name=Button   onClick=document.all.WebBrowser.ExecWB(4,1)    type=button    value=另存为>    

   <input   name=Button   onClick=document.all.WebBrowser.ExecWB(6,1)    type=button    value=打印>  

   <input   name=Button   onClick=document.all.WebBrowser.ExecWB(6,6)    type=button    value=直接打印>  

   <input   name=Button   onClick=document.all.WebBrowser.ExecWB(8,1)    type=button    value=页面设置>  

   <input   name=Button    onClick=document.all.WebBrowser.ExecWB(10,1)    type=button    value=属性>  

   <input   name=Button   onClick=document.all.WebBrowser.ExecWB(17,1)    type=button    value=全选>  

   <input   name=Button   onClick=document.all.WebBrowser.ExecWB(22,1)    type=button   value=刷新>  

   <input   name=Button   onClick=document.all.WebBrowser.ExecWB(45,1)    type=button    value=关闭>

 

开篇里提到web 打印是“老大难”,这个难度究竟如何?这么说吧,有一个公司为了解决WEB打印的问题,专门组织了一个强大的团队,并得到全国1000多家软件公司的技术支持,经N年呕心沥血,制作出了“露肚皮”,开发团队称:“她是全国1000多家软件公司的智慧结晶,诞生7年了,几乎每个功能细节都蕴藏着无数开发者的期待和汗水”。

2. 作者推荐:WEB开发必选伴侣 ——LODOP

泰安梦泰尔软件有限公司旗下产品,Lodop(标音:劳道谱,俗称:露肚皮)是专业WEB控件,用它既可裁剪输出页面内容,又可用程序代码直接实现复杂打印。控件功能强大,支持页面打印、报表打印、条码打印、图表打印、套打等,简单易用。

<script language="javascript"src="<s:url value="/style/script/LodopFuncs.js"/>"></script>

<object  id="LODOP_OB" classid="clsid:2105C259-1E0C-4534-8141-A753534CB4CA" width=0 height=0>

<embed id="LODOP_EM"type="application/x-print-lodop" width=0 height=0></embed>

</object>

function prn3_preview(){

LODOP=getLodop();

LODOP.PRINT_INIT("打印控件功能演示_Lodop功能_全页");

LODOP.ADD_PRINT_HTM(0,0,"100%","100%",document.getElementById("print").innerHTML);

LODOP.PREVIEW();

};

 

几行简单的JS,便实现了复杂的WEB打印。

其具体使用方法以及例子请见LODOP文件夹内的文件。

 

 

总结:如果上天可以给我一个机会再来一次的话,我会对你说三个字“我爱你”。如果非要把这份爱加上一个期限,我希望是一万年!