...
在项目的使用过程中,有一些数据不能直接从关系或者多维数据库中获取,可能需要从另外一些途径获取又或者需要一些特殊的处理。
Smartbi中的查询和多维分析无法完成此功能,因此提供了Java查询二次开发接口允许项目进行定制性的开发。 为了应对这种需求,Smartbi
提供了一个可以根据需要扩充的Java查询方式,可以根据实际情况开发来满足您的需求。
本方案是在Smartbi中添加自定义的Java查询类,并使Smartbi正确的展示数据的过程。 下面讲解一下具体的实现步骤:
- 按照使用smartbi提供工具创建扩展包的说明,新建扩展包项目MyJavaQueryProj,如果是使用cmd脚本创建,配置如下图:
- 解压smartbi.war到临时目录
- 将临时目录中的/WEB-INF/lib/smartbi-FreeQuery.jar及其它依赖包复制到扩展包项目jar、smartbi-Common.jar等smartbi依赖包复制到扩展包项目MyJavaQueryProj的lib-compile目录,并添加该目录下所有jar为项目的依赖包(如果要添加的jar不是smartbi.war中的jar,但是自定义javabean需要使用,则需要将jar包复制到MyJavaQueryProj的src/web/META-INF/lib目录,添加该目录下所有jar为项目的依赖包lib目录,该目录下的jar在打包扩展包时将一同打包)
在MyJavaQueryProj项目中新建一个类com.proj.MyJavaQuery,并实现接口
IJavaQueryData
.ISimpleData
(该接口声明返回该类返回的数据量比较少,Smartbi会自动读取所有数据并支持计算字段、排序、聚合、条件的功能)
- 编译项目,运行/MyJavaQueryProj/build.xml将项目打包为扩展包MyJavaQueryProj.ext,如下图
注:Eclipse等IDE编译用的JDK必须与Smartbi服务器运行的JDK使用同一个版本 - 执行后刷新MyJavaQueryProj项目,可以看到新增一个dist目录,目录下MyJavaQueryProj.ext文件就是生成的扩展包
- 按照扩展包部署的方法,部署MyJavaQueryProj.ext到smartbi
- 重启服务器重启smartbi应用服务器
- 在【管理】→【系统管理】的“数据源”节点右键新建Java数据源在【定制管理】→【数据管理】的“数据源”节点右键新建Java数据源
- “Java数据源”上右键“新建Java查询对象”在类名中输入正确的Java查询实现类全名(如com.proj.MyJavaQuery)并获取默认配置MyJavaQuery)并获取默认配置,可自定义修改配置
修改文件名配置为E:\test.csv - 点击获取参数与结果集并保存
保存后就可以在【定制管理】→【数据集定义】的“Java查询”中使用对应的Java查询对象新建Java查询 - 保存后就可以在【定制管理】→【数据集定义】的“Java查询”中使用对应的Java查询对象新建Java查询,拖动Java查询字段到表达式编辑器,然后保存Java查询
- 保存Java查询到指定目录后,可以基于java查询新建分析
这里是一个CSV文件查询的例子源码。
代码块 | ||||||
---|---|---|---|---|---|---|
| ||||||
package com.proj; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import smartbi.freequery.metadata.IJavaQueryData; import smartbi.freequery.metadata.JavaQueryConfig; import smartbi.freequery.metadata.JavaQueryOutputField; import smartbi.freequery.metadata.JavaQueryParameter; import smartbi.freequery.querydata.CellData; import smartbi.freequery.querydata.GridData; import smartbi.net.sf.json.JSONObject; import smartbi.util.StringUtil; import smartbi.util.ValueType; public class MyJavaQuery implements IJavaQueryData.ISimpleData { private Map<String, JavaQueryConfig> configs = new LinkedHashMap<String, JavaQueryConfig>(); private BufferedReader reader; private List<JavaQueryOutputField> outputFields; private int currentLine; public MyJavaQuery() { // 增加一个名称为FileName的配置项 addConfig("FileName", "文件名", "给定一个文件名", "test.csv", true); addConfig("Encoding", "编码", "编码方式", "GBK", true); } /** * 获取Java查询需要的配置信息 */ public List<JavaQueryConfig> getConfigs() { return new ArrayList<JavaQueryConfig>(configs.values()); } /** * 添加一个配置项 * * @param name * 名称 * @param alias * 别名 * @param desc * 描述 * @param defaultValue * 默认值 * @param notNull * 是否允许为空 */ private void addConfig(String name, String alias, String desc, String defaultValue, boolean notNull) { JavaQueryConfig p = new JavaQueryConfig(); p.setName(name); p.setAlias(alias); p.setDesc(desc); p.setValue(defaultValue); p.setNotNull(notNull); configs.put(name, p); } /** * 从保存的字符串中恢复配置信息 * * @param configStr * 配置字符串 */ public void loadConfigs(String configStr) { if if(StringUtil.isNullOrEmpty(configStr)) return; JSONObject obj = JSONObject.fromString(configStr); configs.get("FileName").setValue( obj.has("FileName") ? obj.getString("FileName") : null); configs.get("Encoding").setValue( obj.has("Encoding") ? obj.getString("Encoding") : null); } /** * 保存配置信息 * * @return 返回配置字符串 */ public String saveConfigs() { JSONObject json = new JSONObject(); for for(JavaQueryConfig config : configs.values()) json.put(config.getName(), config.getValue()); return json.toString(); } /** * 设置配置信息 * * @param key * 名称 * @param value * 配置值 */ public void setConfigValue(String key, String value) { configs.get(key).setValue(value); } /** * 设置配置信息 */ public void setConfigValues(Map<String, String> configValues) { for for(Entry<String, String> config : configValues.entrySet()) configs.get(config.getKey()).setValue(config.getValue()); } /** * 根据配置信息初始化Java查询对象 */ public void init() { try { outputFields = new ArrayList<JavaQueryOutputField>(); File readerfile = new BufferedReader(new InputStreamReader(File(configs.get("FileName").getValue()); if (file.exists()) { FileInputStream fis = new FileInputStream(file); if (configs.get("FileNameEncoding").getValue().toLowerCase().equals("utf-8")) { byte[] headData = new byte[3]; fis.read(headData, 0, 3); if (headData[0] != (byte) 0xef || headData[1] != (byte) 0xbb || headData[2] != (byte) 0xbf) { fis.close(); fis = new FileInputStream(file); } } reader = new BufferedReader(new InputStreamReader(fis, configs.get("Encoding").getValue())); String titleLine = reader.readLine(); String[] fields = titleLine == null ? "".split(","); outputFields = new ArrayList<JavaQueryOutputField>(: titleLine.split(","); for for (String str : fields) { JavaQueryOutputField f = new JavaQueryOutputField(); f.setId(str); f.setName(str); f.setAlias(str); if (str.equals(StringUtil.getLanguageValue("Value1"))) { f.setAliassetDataType(strValueType.DOUBLE); } else { f.setDataType(ValueType.STRING); } outputFields.add(f); } } currentLine = 0; } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); } catch (FileNotFoundException e) { throw new IllegalArgumentException(e); } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * 关闭Java查询对象,关闭必要的资源 */ public void close() { try { if if(reader != null) { reader.close(); reader = null; } } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * 返回参数对象 */ public List<JavaQueryParameter> getParameters() { return new ArrayList<JavaQueryParameter>(); } /** * 设置参数值 */ public void setParameterValue(String id, String value, String displayValue) { } /** * 返回Java查询的输出字段 */ public List<JavaQueryOutputField> getOutputFields() { return outputFields; } /** * 获取指定行的数据 */ public GridData getGridData(int from, int count) { try { if if(currentLine > from) { if (reader != null) { reader.close(); FileInputStream fis = reader = new BufferedReader(new InputStreamReader(new FileInputStream(configs.get("FileName").getValue()); if (configs.get("Encoding").getValue().toLowerCase().equals("utf-8")) { byte[] headData = new byte[3]; fis.read(headData, 0, 3); if (headData[0] != (byte) 0xef || headData[1] != (byte) 0xbb || headData[2] != (byte) 0xbf) { fis.close(); fis = new FileInputStream(configs.get("FileName").getValue()); } } reader = new BufferedReader(new InputStreamReader(fis, configs.get("Encoding").getValue())); reader.readLine(); } currentLine = 0; } if (reader }!= null) { while while(currentLine < from) { reader.readLine(); currentLine++; } } List<List<CellData>> datas = new ArrayList<List<CellData>>(); for for(int i = 0; i < count; i++) { String line = String line =reader == null ? null : reader.readLine(); if if (line == null) break; currentLine++; String[] fs = line.split(","); List<CellData> row = new ArrayList<CellData>(); for for (int j = 0; j < fs.length; j++) { CellData c = new CellData(); c.setStringValue(fs[j]); row.add(c); } datas.add(row); } GridData d = new GridData(); List<String> headers = new ArrayList<String>(); for for(JavaQueryOutputField f : outputFields) headers.add(f.getName()); d.setStringHeaders(headers); d.setData(datas); return d; } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); } catch (FileNotFoundException e) { throw new IllegalArgumentException(e); } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * 返回总行数,返回Integer.MAX_VALUE表示未知总行数 */ public int getRowCount() { return Integer.MAX_VALUE; } } } |
附件
源代码:MyJavaQueryProj.rar,扩展包:MyJavaQueryProj.ext,测试csv文件:test.csv