Java后台报表尝试了不少,最终发现了一款,并且是开源的,简表地址:http://www.jatools.com/jor/。问题的引入:该报表支持嵌套,钻去,应对excel相似的报表,足够了。可是,报表的图表特别难看,因此想改一下,结合如今流行的图表Echart, 访问地址:http://echarts.baidu.com/, 开源了这个解决方案,和你们一块儿完善这个报表。javascript
Jor 报表的设计:使用awt 展现报表,最终使用的是graphics 对象,而后使用jreport 等开源组件,实现导出pdf,导出word ,导出excel 等。html
Echrt 的引入,Echart 是javascript 组件,而后执行javascript,使用echart 的getDataURL能够获得Echart 展现的图片的base64 编码,这样,结合读取图片,展现grahics ,就能够展现出来,而后顺便导出等等。Js这部分,能够根据绑定的数据源,动态写js 方法,修改html 文件,而后展现便可。java
方案1:git
使用HtmlUnit组件,即http://htmlunit.sourceforge.net/。 展现html ,加载js,而后导出base64编码。大体源码以下:github
final WebClient webClient = new WebClient(BrowserVersion.CHROME); final HtmlPage page = webClient.getPage("http://localhost:8000/line2.html"); System.out.println(" // 1 启动JS "); webClient.getOptions().setJavaScriptEnabled(true); System.out.println("// 2 禁用Css,可避免自动二次请求CSS进行渲染 "); webClient.getOptions().setCssEnabled(false); System.out.println("// 3 启动客户端重定向 "); webClient.getOptions().setRedirectEnabled(true); System.out.println("// 4 js运行错误时,是否抛出异常"); webClient.getOptions().setThrowExceptionOnScriptError(false); System.out.println("// 5 设置超时 "); webClient.getOptions().setTimeout(50000); System.out.println(" 容许绕过SSL认证 "); webClient.getOptions().setUseInsecureSSL(true); System.out.println(" 容许启动注册组件 "); webClient.getOptions().setActiveXNative(true); System.out.println(" //等待JS驱动dom完成得到还原后的网页 "); webClient.waitForBackgroundJavaScript(5000); webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); webClient.getCookieManager().setCookiesEnabled(true); webClient.setAjaxController(new NicelyResynchronizingAjaxController()); webClient.addWebWindowListener( new WebWindowListener() { @Override public void webWindowOpened(WebWindowEvent webWindowEvent) { System.out.println("windows opened"); } @Override public void webWindowContentChanged(WebWindowEvent webWindowEvent) { System.out.println("windows changed"); } @Override public void webWindowClosed(WebWindowEvent webWindowEvent) { System.out.println("windows closed"); } }); try { Thread.sleep(10000); }catch (Exception exp) { } final HtmlDivision div = page.getHtmlElementById("text2"); //执行按钮出发的js事件 ScriptResult sr = page.executeJavaScript("javascript:getData();"); try { String fileStr = ""; String test = sr.getJavaScriptResult().toString(); byte[] b = new BASE64Decoder().decodeBuffer(test); // 生成图片 OutputStream out = new FileOutputStream(new File(fileStr + "\\test.png")); out.write(b); out.flush(); out.close(); }catch (Exception exp) { exp.printStackTrace(); } }catch (Exception exp) { exp.printStackTrace(); }
结果: 不行,执行不了js,缘由没有深刻研究。web
方案2:c#
JDIC,https://www.ibm.com/developerworks/cn/java/j-jdic/ ,JDIC 是java 组件,能够展现html,执行javascript。windows
代码以下:浏览器
//BrowserEngineManager bem = BrowserEngineManager.instance(); // bem.setActiveEngine(BrowserEngineManager.IE); //IBrowserEngine be = bem.getActiveEngine(); //URL url = new URL("http://www.hao123.com"); URL url = new File("http://localhost.:8000/line2.html").toURI().toURL(); final WebBrowser browser = new WebBrowser(); //browser = be.getWebBrowser();//new WebBrowser(); browser.addWebBrowserListener(new WebBrowserListener() { public void downloadStarted(WebBrowserEvent event) { System.out.println("27"); } public void downloadCompleted(WebBrowserEvent event) { System.out.println("30"); } public void downloadProgress(WebBrowserEvent event) { System.out.println("33"); } public void downloadError(WebBrowserEvent event) { System.out.println("36"); } public void documentCompleted(WebBrowserEvent event) { System.out.println("39"); browser.executeScript("alert('文档下载完毕!')"); String res = browser.executeScript("getData"); System.out.println(res); } public void titleChange(WebBrowserEvent event) { System.out.println("43"); } public void statusTextChange(WebBrowserEvent event) { System.out.println("46"); } public void windowClose(WebBrowserEvent webBrowserEvent) { System.out.println("49"); } public void initializationCompleted(WebBrowserEvent arg0) { System.out.println("52"); } }); browser.setURL(url); JFrame f = new JFrame(); f.setTitle("浏览器"); f.setSize(800,600); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //f.getContentPane().add(browser1); f.getContentPane().add(browser); f.setVisible(true); }
结果: 代码跑不起来,dll 都是32 位,没有办法使用,因此放弃。echarts
方案3:
使用c# winform 的webbrowser 控件,加载html, 而后执行js脚本。
代码:
private void init() { InitializeComponent(); CleanTempFiles(); webBrowser1.AllowWebBrowserDrop = false; webBrowser1.WebBrowserShortcutsEnabled = false; webBrowser1.IsWebBrowserContextMenuEnabled = false; webBrowser1.Navigate(htmlurl + "?random=" + DateTime.Now.ToString("yyyyMMddHHmmss"), null, null, null); } private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { try { var doc = this.webBrowser1.Document; var ele = doc.GetElementById("text2"); Console.WriteLine(ele.InnerText); // 读取base64 , 而后转换为图片,保存 string base64 = ele.InnerText.Split(',')[1]; byte[] arr = Convert.FromBase64String(base64); MemoryStream ms = new MemoryStream(arr); Bitmap bmp = new Bitmap(ms); //bmp.Save(txtFileName + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); //bmp.Save(txtFileName + ".bmp", ImageFormat.Bmp); //bmp.Save(txtFileName + ".gif", ImageFormat.Gif); //bmp.Save(txtFileName + ".png", ImageFormat.Png); // bmp.Save(imageGuid + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); bmp.Save(imageGuid + ".png", System.Drawing.Imaging.ImageFormat.Png); ms.Close(); }catch(Exception exp) { Console.WriteLine(exp.ToString()); } finally { Application.Exit(); } }
结果: 可行, 导出图片成功, 因此采用。
接下来要作:
1, 实现全部图表,代码中只实现了linechart,其余,饼图,什么的都须要更改。
2, 增长脚步选项,直接在界面中设置js代码,高度定制。
开源地址: