赞
踩
开发需求:
java语言与数据源结合,生成可视化图片,结合echarts 框架 将生成的图片写入到word 文档中,不采用前台生成等操作。
难点:
后台如何生成图片,这是这个需求的难点,通过调研,有许多技术,比如Graphics2D、jfreechart、PhantomJS等等,Graphics2D 生成一些简单的图片比如二维码,海报等等,jfreechart 生成图片比较硬,需要各种调试,当然也可以生成好看的图片,对于懒的我来说,已经不在考虑了。最后决定使用PhantomJS技术来解决这个需求。
开发过程:
实现这个技术,需要对这个技术有个初步的了解,在网上各种搜索,其实最后明白就是搭建个服务,我们后台直接请求这个服务生成图片,返回给我们, PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎,供我们请求进行各种操作。
安装环境:
下载对应系统地址: http://phantomjs.org/download
一. window系统:
1.配置环境变量:
系统 – 高级系统设置 – 环境变量 --系统变量 设置PATH
2.进入我们的cmd 窗口,phantomjs 即可看到效果。
3.使用一下它们提供的例子:
phantomjs e:\phantomjs-2.1.1-windows\examples\hello.js
Hello,world!
4.说明安装成功。
二. linux 系统:
1.解压压缩包:
tar xjf phantomjs-2.1.1-linux-x86_64.tar.bz2
2.设置环境变量,并使得配置文件生效:
export PATH=${PATH}:/opt/phantomjs/bin
source /etc/profile
3.phantomjs 即可看到生效
注意:phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
解决办法:
yum install fontconfig freetype2 (yum安装)
3.使用一下它们提供的例子:
phantomjs opt\phantomjs\examples\hello.js
Hello,world!
4.说明安装成功!
实现需求:
java通过连接 phantomjs 来实现后端生成echarts .生成效果如下:
首先 后端封装参数,生成option 通过http 请求得到对应的 图片 base64;
主要代码:
option.ftl:
{ xAxis: { type: 'value', show: false }, yAxis: { type: 'category', data: ${categories}, splitLine:{ show: false }, axisLine: { show: false }, axisTick:{ show: false }, axisLabel:{ fontSize: 14, fontFamily:'黑体' } }, grid:{ left: '110px', top: '0px', right: '60px', bottom: '12px' }, color: ${colorValue}, series: [{ data: ${values}, type: 'bar', barWidth: '20px', label: { show: true, position: 'right', formatter: '{b}', color: '#000', fontFamily:'黑体' } }] }
EchartsUtils工具类:
public class EchartsUtil { private static Properties configProperties; private static String url; private static final String SUCCESS_CODE = "1"; /** * * @param option * @param width * @param height * @return * @throws ClientProtocolException * @throws IOException */ public static String generateEchartsBase64(String option,String width,String height) throws ClientProtocolException, IOException { if(StringUtils.isBlank(url)){ configProperties = SpringContextHolder.getBean("configProperties"); url = MapUtils.getString(configProperties, "phantomjs.url"); } String base64 = ""; if (option == null) { return base64; } option = option.replaceAll("\\s+", "").replaceAll("\"", "'"); // 将option字符串作为参数发送给echartsConvert服务器 Map<String, String> params = new HashMap(); params.put("opt", option); params.put("width",width); params.put("height",height); String response = httpRequestUtils.post(url, params, "utf-8"); // 解析echartsConvert响应 JSONObject responseJson = JSON.parseObject(response); String code = responseJson.getString("code"); // 如果echartsConvert正常返回 if (SUCCESS_CODE.equals(code)) { base64 = responseJson.getString("data"); } // 未正常返回 else { String string = responseJson.getString("msg"); throw new RuntimeException(string); } return base64; } }
FreemarkerUtil 工具类:
public class FreemarkerUtil { public static String generateString(HttpServletRequest httpRequest, String templateFileName, String templateDirectory, Map<String, Object> datas) throws IOException, TemplateException { Configuration configuration = new Configuration(); configuration.setDefaultEncoding("UTF-8"); // 设置模板所在文件夹 String separator = File.separator; //如何区分是window 还是 liunx 系统 String filedownload = ""; if ("\\".equals(separator)) { System.out.println("windows下"); filedownload = httpRequest.getSession().getServletContext().getRealPath("/WEB-INF/resources/file") + "/"; filedownload = filedownload.replace("/", "\\"); } // liunx 下 if ("/".equals(separator)) { System.out.println("linux下"); filedownload = httpRequest.getSession().getServletContext().getRealPath("/WEB-INF/resources/file") + "/" ; filedownload = filedownload.replace("\\", "/"); } configuration.setDirectoryForTemplateLoading(new File(filedownload)); // 生成模板对象 Template template = configuration.getTemplate(templateFileName); // 将datas写入模板并返回 try (StringWriter stringWriter = new StringWriter()) { template.process(datas, stringWriter); stringWriter.flush(); return stringWriter.getBuffer().toString(); } }
测试代码块:
public void getphantomjs(){ // 变量 String[] categories = new String[] { "苹果", "香蕉", "西瓜" }; String[] color= new String[] {"#008000"}; Map <String,Object> dataMap=new HashMap<>(); List dataList = new ArrayList<>(); dataMap.put("name","B"); dataMap.put("value",40); dataList.add(dataMap); dataMap=new HashMap<>(); dataMap.put("name","AA"); dataMap.put("value",60); dataList.add(dataMap); dataMap=new HashMap<>(); dataMap.put("name","AAA"); dataMap.put("value",100); dataList.add(dataMap); Object[] values = dataList.toArray(); HashMap<String, Object> datas = new HashMap<>(); //对应option.ftl 变量 datas.put("categories", JSON.toJSONString(categories)); datas.put("values", JSON.toJSONString(values)); datas.put("colorValue",JSON.toJSONString(color)); String option = null; try { option = FreemarkerUtil.generateString(getHttpRequest(),"option.ftl", "", datas); String base64 = EchartsUtil.generateEchartsBase64(option,"555","96"); generateImage(base64, "D:\\test.png"); } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } } public static void generateImage(String base64, String path) throws IOException { BASE64Decoder decoder = new BASE64Decoder(); try (OutputStream out = new FileOutputStream(path)){ // 解密 byte[] b = decoder.decodeBuffer(base64); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) { b[i] += 256; } } out.write(b); out.flush(); } }
``
2019/04/28 新增
遗留2个问题:
1. 关于启动 phantomjs
2. linux 字体安装 生成与window一样的图片
第一个问题:
打开js 查看
其目的就是启动时加载这个 别人封装好的js插件,传入参数生成想要的结果。
(默认端口号9090)
window 启动:
phantomjs C:\Users\LENOVO\Desktop\安装phantomjs\echartsconvert\echarts-convert.js -s
linux 后台启动:
nohup phantomjs /opt/phantomjs/echartsconvert/echarts-convert.js -s &
附件echarts-convert.js 下载路径:
[https://download.csdn.net/download/weixin_38429587/11149428]
第二个问题:
Linux系统安装windos字体步骤如下:
1、复制字体
在“C:\Windows\Fonts”目录下找到所要安装字体,这里以“SIMHEI.TTF”为例。
2、上传字体至CentOS系统
在/usr/share/fonts目录下建立一个子目录,比如/HEITIFONTS. 上传“SIMHEI.TTF”字体至此目录。
3、进入此目录安装
cd /usr/share/fonts/HEITIFONTS
运行以下命令建立字体索引信息,更新字体缓存:
sudo mkfontscale
sudo mkfontdir
sudo fc-cache -fv
执行以下命令让字体生效
source /etc/profile
安装可能遇到的问题与解决办法
1.权限问题:
cd /usr/share/fonts/HEITIFONTS
chmod 755 *.ttf
2.提示 “ mkfontscale: command not found”,用yum安装: yum install mkfontscale
提示 “ fc-cache: command not found” yum install fontconfig
若需要重启服务器: reboot
查看已安装的字体: fc-list
总结:
在开发过程中,还需要进一步更改,封装等等操作,如有疑问,请留言。。。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。