JAVA的Web打印方式(PageOffice、POI、jacob,html打印等)
2013-04-29 20:26 David&R 阅读(9931) 评论(0) 编辑 收藏 举报之前因为需要,去学习了几种WEB报表的打印方式,发现用Java直接去操作Word、Excel还是不那么方便,下面就简单介绍几种;
1、用浏览器自带的打印功能直接打印;
这种方式是最直接的,方便的,不需要加什么插件jar包,只要前台在一个 div 中模仿着报表的格式去设置界面布局,然后把数据动态的填充进去,再调用JavaScript打印函数,就可以实现界面的局部打印功能。(如果不想让报表div在界面中显示出来可以隐藏之)PS:不过直接在前台界面打印还是会遇到意想不到的情况,不同浏览器的问题,反正我就遇到不同浏览器打印出来的报表排版不一的情况,用的 时候需要注意。
eg:
div布局
<div id="printdiv" style="display:none;"> <table id="tableid" class="main" cellspacing="0" cellpadding="0" border="1" bordercolor="#000000" align="center" width="800px;"> /****** your code ******/ </table>
</div>
JavaScript部分:(自己根据需要选择触发响应的JS函数)
function windowprint() { var f = document.getElementById("printdiv"); f.style.display = ""; window.print(); f.style.display = "none"; } function myPrint(obj){ var newWindow=window.open("打印窗口","_blank"); var docStr = obj.innerHTML; newWindow.document.write(docStr); newWindow.document.close(); newWindow.print(); newWindow.close(); }
2、使用第三方插件完成报表打印编辑(这里介绍PageOffice 和 Jacob)
先说PageOffice,这是国产货,其强大之处在于其对Word的处理和它的在线编辑能力,最大的不足就是要收费(不过也不知道怎么收,下载的包里有自带的试用码,也不管先用着玩玩)
准备:去官网下载java版本的包(http://www.zhuozhengsoft.com/download.html),解压后需要把PageOffice.cab和pageoffice.jar两个包放到WEB-INF/lib中去还要在你的web.xml中加入以下部分:
<!-- PageOffice Begin --> <servlet> <servlet-name>poserver</servlet-name> <servlet-class>com.zhuozhengsoft.pageoffice.poserver.Server</servlet-class> </servlet> <servlet-mapping> <servlet-name>poserver</servlet-name> <url-pattern>/poserver.do</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>poserver</servlet-name> <url-pattern>/pageoffice.cab</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>poserver</servlet-name> <url-pattern>/popdf.cab</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>poserver</servlet-name> <url-pattern>/sealsetup.exe</url-pattern> </servlet-mapping> <servlet> <servlet-name>adminseal</servlet-name> <servlet-class>com.zhuozhengsoft.pageoffice.poserver.AdminSeal</servlet-class> </servlet> <servlet-mapping> <servlet-name>adminseal</servlet-name> <url-pattern>/adminseal.do</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>adminseal</servlet-name> <url-pattern>/loginseal.do</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>adminseal</servlet-name> <url-pattern>/sealimage.do</url-pattern> </servlet-mapping> <mime-mapping> <extension>mht</extension> <mime-type>message/rfc822</mime-type> </mime-mapping> <context-param> <param-name>adminseal-password</param-name> <param-value>123456</param-value> </context-param> <!--<context-param> <param-name>posealdb-driver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param> <context-param> <param-name>posealdb-url</param-name> <param-value>jdbc:mysql://localhost:3306/sample</param-value> </context-param> <context-param> <param-name>posealdb-username</param-name> <param-value>root</param-value> </context-param> <context-param> <param-name>posealdb-password</param-name> <param-value>admin</param-value> </context-param>--> <!-- PageOffice End -->
然后就可以直接用了
eg:直接贴一个Struts2下使用的Demo好了
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.apache.struts2.interceptor.*; import com.opensymphony.xwork2.ActionSupport; import com.zhuozhengsoft.pageoffice.*; public class WordDemo extends ActionSupport implements ServletRequestAware, ServletResponseAware{ private static final long serialVersionUID = -758686623642845302L; private HttpServletRequest request; private HttpServletResponse response; private String message = ""; public void setServletRequest(HttpServletRequest request) { this.request = request; } public void setServletResponse(HttpServletResponse response) { this.response = response; } public String getMessage(){ return message; } public String openword() throws Exception { PageOfficeCtrl poCtrl1 = new PageOfficeCtrl(ServletActionContext.getRequest()); poCtrl1.setServerPage("poserver.do"); //此行必须 // 加载控件,可以显示在在线编辑栏中 poCtrl1.addCustomToolButton("保存", "SaveDocument()", 1); poCtrl1.addCustomToolButton("-", "", 0); poCtrl1.addCustomToolButton("打印", "ShowPrintDlg()", 6); poCtrl1.addCustomToolButton("-", "", 0); poCtrl1.addCustomToolButton("全屏切换", "SetFullScreen()", 4); poCtrl1.addCustomToolButton("-", "", 0); poCtrl1.addCustomToolButton("加盖印章", "AddSeal()", 5); poCtrl1.addCustomToolButton("手写签批", "AddHandSign()", 5); poCtrl1.addCustomToolButton("验证印章", "VerifySeal()", 5); poCtrl1.setSaveFilePage("saveword.action"); // 打开WebRoot/doc/test.doc模版
poCtrl1.webOpen("doc/test.doc", OpenModeType.docNormalEdit, "张三"); poCtrl1.setTagId("PageOfficeCtrl1"); //此行必须 return "openword_"+SUCCESS; } public String saveword() throws Exception { FileSaver fs = new FileSaver(request, response); request.setAttribute("FileSaver", fs); String fileName = "\\maker" + fs.getFileExtName(); fs.saveToFile(request.getSession().getServletContext().getRealPath("doc/")+ fileName);//fs.getFileName() fs.showPage(150, 150); message = "保存文件至服务器成功!"; return "saveword_"+SUCCESS; } }
还可以在模版中设置书签指定动态替换,不过需要注意一点的是在返回的JSP界面中<body>中需要加入
<po:PageOfficeCtrl id="PageOfficeCtrl1" />
关于具体的,可以参考他的文档,是中文的文档,而且官网还可以下载很多Demo参考,没什么可以说的了,PS:不过就是感觉它在网页中直接打开word速度有点慢,不过这可能是微软问题。。
B:jacob
简单的看了一下,又是要加jar包,还要把它那dll文件放到你的系统路径下,感觉好烦的样子,具体怎么做网上也能找到,不再赘述。
eg:(贴一个小例子)
import com.jacob.activeX.ActiveXComponent; import com.jacob.com.Dispatch; import com.jacob.com.Variant; public class JacobTest { public static void main(String[] args) { //启动word,生成一个ActivexComponent对象 ActiveXComponent app = new ActiveXComponent("Word.Application"); //要转换的word文件 String inFile = "D:\\demo.doc"; //要报存的目标文件 String tpFile ="D:\\demo1.doc"; boolean flag = false; Dispatch xlo = app.getObject(); String oldText="1234"; String newText="test"; boolean visible=false; String bookMarkKey1="LB_KJGG"; String bookMarkKey2="PO_Sex"; try { //设置word不可见 app.setProperty("Visible", new Variant(visible)); //log.info("设置word不可见成功!"); System.out.println("设置word不可见成功!"); Dispatch docs = app.getProperty("Documents").toDispatch(); Dispatch doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[]{inFile, new Variant(false), new Variant(true)}, new int[1]).toDispatch(); //打开word文件 //在word2003的vba文档中application有UserName属性。 String userName=app.getPropertyAsString("UserName"); System.out.println("用户名:"+userName); Dispatch selection=app.getProperty("Selection").toDispatch(); //得到一个组件 System.out.println("Selection"); Dispatch find = app.call(selection, "Find").toDispatch(); //查找什么文本 Dispatch.put(find, "Text", oldText); //替换文本 Dispatch.call(find,"ClearFormatting"); Dispatch.put(find, "Text", oldText); Dispatch.call(find, "Execute"); Dispatch.put(selection, "Text", newText); // Dispatch.call(app, "SaveAs", inFile); System.out.println("replace"); //把指定的值设置到指定的标签中去 Dispatch activeDocument=app.getProperty("ActiveDocument").toDispatch(); System.out.println("activedocument"); Dispatch bookMarks = app.call(activeDocument, "Bookmarks").toDispatch(); System.out.println("bookmarks"); boolean bookMarkExist1=Dispatch.call(bookMarks,"Exists",bookMarkKey1).toBoolean(); boolean bookMarkExist2=Dispatch.call(bookMarks,"Exists",bookMarkKey2).toBoolean(); if(bookMarkExist1==true){ System.out.println("exists bookmark!"); Dispatch rangeItem = Dispatch.call(bookMarks, "Item",bookMarkKey1).toDispatch(); System.out.println("range item!"); Dispatch range = Dispatch.call(rangeItem, "Range").toDispatch(); System.out.println("range !"); //取标签的值 String bookMarkValue=Dispatch.get(range,"Text").toString(); bookMarkValue="hello"; if(bookMarkValue!=null){ Dispatch.put(range, "Text", new Variant(bookMarkValue)); } }else{ System.out.println("not exists bookmark!"); } //保存文件 Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] {tpFile, new Variant(0)} , new int[1]); //作为word格式保存到目标文件 Variant f = new Variant(false); Dispatch.call(doc, "Close", f); flag = true; } catch (Exception e) { e.printStackTrace(); } finally { app.invoke("Quit", new Variant[] {}); } } }
3、还有一个技术,POI,其实第一个就学的这个。对Excel的处理还行,对word的处理,读取还过的去,但是写入,尤其是写入图片,不知道能么办,而且用起来好麻烦。(真是想不通都搞了10来年的技术了,还这样。。)
eg1:(向word中插入一段文本)
import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.hwpf.model.io.HWPFFileSystem; import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.DocumentEntry; import org.apache.poi.poifs.filesystem.POIFSFileSystem; /* * 可以向word中插入文本 * */ public class TestWrite4 { public static void main(String[] args) throws Exception { HWPFFileSystem files = new HWPFFileSystem(); try { String str = "This is our first doc file Jojiiiiiiiiiiii….We Got IT..But not sure !!"; str += "rn这是我的第一个doc例子!"; byte b[] = str.getBytes(); ByteArrayInputStream bais = new ByteArrayInputStream(b); POIFSFileSystem fs = new POIFSFileSystem(); DirectoryEntry directory = fs.getRoot(); DocumentEntry de = directory.createDocument("WordDocument", bais); FileOutputStream ostream = new FileOutputStream("d:\\testCreate.doc"); fs.writeFilesystem(ostream); bais.close(); ostream.close(); } catch (IOException e) { e.printStackTrace(); } } }
还有一些具体的功能操作,以及对于Excel的操作,推荐一个网站介绍的比较好。http://word.apachepoi.com/
还在网上看到可以通过 Applet方式完成报表的打印,不过没去研究过。。