ureport2+Headless开启报告自动生成之旅
公司之前产品采用java纯后端dynamicsReport报表工具,这里简单介绍下,它的charts是基于jfeecharts,通过xml设置报表模板,美观度相对较差,有点支持生成pdf、word、html格式输出,我个人觉得也就pdf看的过去,Html生成后体积太大,word有强烈的拼接感,而且html和word二次编辑都很不友好,以至于我们公司一个报表需要两种开发模式(前端展现和后端导出)。
最近领导发现来源的ureport2,感觉感觉一亮,下发最高文件“盘它”。经过2天的艰苦奋战总结去下特点:
1、设计器不支持组件拖拉拽
2、设计器采用excel表格形式,对于复杂报表,开始设计之前需要经过精细的单元格宽高的预算和设计。
3、不支持复合图表(例如柱状图+曲线图复合)
4、不支持后端直接生成Pdf或者word格式的报表,因为chart需要浏览器渲染后生成图片回传到报表服务器。
5、数据源配置不支持选择数据库类型,需要手动填入驱动类型以及Url。
有问题自然需要解决,由于uteport是开源项目,所以只要肯投入一切都不是问题!!!
第一个问题可以忽略不计...
第二个问题,这个硬伤对于设计报表的人来说太痛苦了,而且无法解决的问题,忍着吧!
第三个问题,ureport图表绘制采用chart. js,需要react前段+java后端协调二次开发,慢慢来,领导还想换成echarts呢!
先说第五个问题,由于ureport提供三种数据源,通过第二种spring bean和第三种内置数据源的方式可以搞定。
第四个问题也就是本章要讲的内容,ureport想要导出带有chart的报表,首先需要浏览器渲染,但是作为后端程序总不能搞幽灵事件自动打开浏览器渲染再关闭吧,会吓到客户的。
浏览器无头模式完美解决这个问题。当然也有弊端:需要安装浏览器。
就目前了解有三种方式可以实现:
chrome headless+selenium、Firefox headless+selenium和PhantomJS,
应该还有一个puppteer这么个东西,没有研究。
public static void generateReport(String fileName) {
WebDriver webDriver = null;
try {
String url = "http://127.0.0.1:8081/ureport/preview?_u="+fileName;
String osName = System.getProperties().getProperty("os.name");
if (osName.contains("Windows")) {
System.setProperty("webdriver.chrome.driver", "D:\\driver\\chromedriver.exe");
}
ChromeOptions chromeOptions = new ChromeOptions();
// 设置 chrome 的无头模式
chromeOptions.setHeadless(Boolean.TRUE);
// linux 下让Chrome在root权限下跑
chromeOptions.addArguments("--no-sandbox");
// Chrome正在受到自动软件的控制 不显示提示语
chromeOptions.addArguments("disable-infobars");
Map<String, Object> chromePrefs = new HashMap<String, Object>();
chromePrefs.put("download.default_directory", "/opt/ureportfiles");
chromeOptions.setExperimentalOption("prefs", chromePrefs);
// 启动一个 chrome 实例
webDriver = new ChromeDriver(chromeOptions);
webDriver.get(url);
Thread.sleep(5000);
url = "http://127.0.0.1:8081/ureport/pdf?_u=file:test.ureport.xml";
webDriver.get(url);
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (webDriver != null) {
//退出 chrome
webDriver.quit();
}
}
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
</dependency>
目前存在的问题就是通过headless渲染什么时候完成,这个没有搞定,通过设置线程等待时间曲线救国。