'新增导出功能'

This commit is contained in:
2019-04-24 17:36:55 +08:00
parent e13588f3ab
commit 936d4dc992
9 changed files with 162 additions and 173 deletions

View File

@@ -19,6 +19,7 @@
<rest autoload="true" base="net.tccn.servlet.BaseServlet"/> <rest autoload="true" base="net.tccn.servlet.BaseServlet"/>
<services autoload="true"/> <services autoload="true"/>
<servlets autoload="true"/> <servlets autoload="true"/>
<render value="net.tccn.base.MetaRender"/>
</server> </server>

View File

@@ -72,7 +72,7 @@
</plugin> </plugin>
<!-- 指定到相对路径下--> <!-- 指定到相对路径下-->
<plugin> <!--<plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId> <artifactId>maven-dependency-plugin</artifactId>
<executions> <executions>
@@ -95,7 +95,7 @@
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
</plugin> </plugin>-->
</plugins> </plugins>
</build> </build>

View File

@@ -78,5 +78,16 @@ const meta = {
itemUpdate({alias, items}) { itemUpdate({alias, items}) {
return red.postX('/meta/itemupdate', {alias, items: JSON.stringify(items)}) return red.postX('/meta/itemupdate', {alias, items: JSON.stringify(items)})
}, },
//client
exportData({fbean, cate}) {
if (cate == 'excel') {
location.href = "/data/export?fBean=" + JSON.stringify(fbean) + "&platToken=" + red.getPlatToken() + "&cate=csv";
} else if (cate == 'cvs') {
} else if (cate == 'json') {
}
}
} }

View File

@@ -22,14 +22,6 @@
</div> </div>
</div> </div>
<!--<h3>高级查询 - [测试用例]</h3>
<div class="col-md-6">
<select class="form-control" v-model="service" style="width: 300px;">
<option v-for="t in services" :value="t.name">{{t.comment}}&nbsp;&nbsp;&nbsp;[{{t.name}}]</option>
</select>
</div>-->
<!-- 业务列表 --> <!-- 业务列表 -->
<div class="col-md-2"> <div class="col-md-2">
<div style="padding-left: 10px;background-color: #ccc;width: 100%"> 业务列表(Meta-Service)</div> <div style="padding-left: 10px;background-color: #ccc;width: 100%"> 业务列表(Meta-Service)</div>
@@ -129,7 +121,7 @@
</row> </row>
<script> <script>
let {getServiceList, getCfg, getDataList} = meta; let {getServiceList, getCfg, getDataList, exportData} = meta;
var vm = new Vue({ var vm = new Vue({
el:".data-list", el:".data-list",
data: { data: {
@@ -140,9 +132,6 @@
}, },
services:[], services:[],
service:"", service:"",
//tables: [],
//table: "",
//filters: [],
addFilter: "recompany", addFilter: "recompany",
para: {}, para: {},
@@ -174,67 +163,17 @@
}, },
methods: { methods: {
findList() { findList() {
vm.list = {rows:[], total:0}; this.list = {rows:[], total:0};
// filters let fbean = this.buildFBean();
let filters = [];
//filters.push({col: "status", value: 9, type: "NOTEQUAL"});
for (i in this.cfg.filters) {
let filter = this.cfg.filters[i];
if (filter.checked && filter['value']) {
let {name: col, value, type} = filter;
filters.push({col, value, type});
}
}
// orders
let orders = [];
//截取真实字段名,(考虑如果多表关联情况,是否需要加入真实字段名)
if (vm.order.col) {
var end = vm.order.col.indexOf("\|");
if (end < 0) {
end = vm.order.col.indexOf("=")
}
var col = vm.order.col;
if (end > 0) {
col = vm.order.col.substring(0, end);
}
orders.push({col: col, desc: vm.order.desc});
}
// fbean
let fbean = {
name: this.service,
filters: filters,
orders: orders,
limit: vm.limit,
};
getDataList(fbean, json => { getDataList(fbean, json => {
console.log(json) console.log(json)
vm.list = json; vm.list = json;
}); });
}, },
exportExcel() { exportExcel() {
var data = []; let fbean = this.buildFBean();
for (k in vm.para) { fbean['limit'] = {pn:1, ps: 1000}
if (vm.para[k] != '') { exportData({fbean, cate:'excel'})
var d = {};
d["col"] = k;
d["value"] = vm.para[k];
d["type"] = $("select[name=" + k + "_cate]").val();
data.push(d);
}
}
//data.push({col: "status", value: 9, type: "NOTEQUAL"});
var fBean = {
keyService: vm.table,
filters: data,
orders: [{col: "status", desc: -1}],
limit: {ps: 5}
}
location.href = "/export/data?fBean=" + JSON.stringify(fBean) + "&platToken=" + red.getPlatToken() + "&cate=csv";
return; return;
}, },
serviceList() { serviceList() {
@@ -247,31 +186,31 @@
getCfg({name: this.service}).then(res => this.cfg = res); getCfg({name: this.service}).then(res => this.cfg = res);
}, },
dealField(bean, field) { dealField(bean, field) {
var str = ""; let str = "";
if (!bean || !field) { if (!bean || !field) {
} else if (typeof(field) === 'function') { } else if (typeof(field) === 'function') {
str = field(bean); str = field(bean);
} else if (field.indexOf("||") > 0) {//处理字典数据 } else if (field.indexOf("||") > 0) {//处理字典数据
var dic_type = field.split("||")[1]; let dic_type = field.split("||")[1];
var v = bean[field.split("||")[0]]; let v = bean[field.split("||")[0]];
str = kvExtDeal(dic_type, v); str = kvExtDeal(dic_type, v);
} else if (field.indexOf("|") > 0) {//处理字典数据 } else if (field.indexOf("|") > 0) {//处理字典数据
var dic_type = field.split("|")[1]; let dic_type = field.split("|")[1];
var v = bean[field.split("|")[0]]; let v = bean[field.split("|")[0]];
str = v;//kvDeal(dic_type, v); str = v;//kvDeal(dic_type, v);
} }
else if (field.indexOf("=") > 0) {//处理字典数据 else if (field.indexOf("=") > 0) {//处理字典数据
var fun = field.split("=")[1]; let fun = field.split("=")[1];
var v = bean[field.split("=")[0]]; let v = bean[field.split("=")[0]];
return v; return v;
//eval("str =$funs."+ fun +"('"+ v +"')"); //eval("str =$funs."+ fun +"('"+ v +"')");
} }
else if (field.indexOf("-") > 0) { else if (field.indexOf("-") > 0) {
var name = field.split("-")[0]; let name = field.split("-")[0];
var path = field.split("-")[1]; let path = field.split("-")[1];
if (bean[name]) { if (bean[name]) {
var href = config.services.issct + "/downLoadFdfs?fileId=" + encodeURI(bean[path]) + "&filename=" + encodeURI(bean[name]); let href = config.services.issct + "/downLoadFdfs?fileId=" + encodeURI(bean[path]) + "&filename=" + encodeURI(bean[name]);
str = "<a href='" + href + "' target='_blank'>" + bean[name] + "</a>"; str = "<a href='" + href + "' target='_blank'>" + bean[name] + "</a>";
} }
} else if (bean[field] === 0) { //特殊值 "0" 处理 } else if (bean[field] === 0) { //特殊值 "0" 处理
@@ -304,6 +243,44 @@
} }
return ''; return '';
}, },
buildFBean() {
// filters
let filters = [];
//filters.push({col: "status", value: 9, type: "NOTEQUAL"});
for (i in this.cfg.filters) {
let filter = this.cfg.filters[i];
if (filter.checked && filter['value']) {
let {name: col, value, type} = filter;
filters.push({col, value, type});
}
}
// orders
let orders = [];
//截取真实字段名,(考虑如果多表关联情况,是否需要加入真实字段名)
if (vm.order.col) {
var end = vm.order.col.indexOf("\|");
if (end < 0) {
end = vm.order.col.indexOf("=")
}
var col = vm.order.col;
if (end > 0) {
col = vm.order.col.substring(0, end);
}
orders.push({col: col, desc: vm.order.desc});
}
// fbean
let fbean = {
name: this.service,
filters: filters,
orders: orders,
limit: this.limit,
};
return fbean
},
showInfo() { showInfo() {
$('#f-info').modal({moveable: true}) $('#f-info').modal({moveable: true})
} }

View File

@@ -369,15 +369,13 @@ public class MetaKit {
} }
@Comment("业务导出表头配置") @Comment("业务导出表头配置")
public Kv cfgExport(String name, String token) { public static Kv cfgExport(String name, String token) {
MetaService metaService = getMetaService(name, token); MetaService metaService = getMetaService(name, token);
Kv<String, MetaTable> tables = getMetaTables(metaService, true);
List<Map<String,String>> exports = metaService.getExports(); List<Map<String,String>> exports = metaService.getExports();
Kv kv = Kv.of(); Kv kv = Kv.of(); // {col:label}
exports.forEach(x -> { exports.forEach(x -> {
kv.put(x.get("col"), x.get("lable")); kv.put(x.get("col"), x.get("label"));
}); });
return kv; return kv;
} }

View File

@@ -0,0 +1,58 @@
package net.tccn.base;
import com.lxyer.excel.poi.ExcelKit;
import org.apache.poi.ss.usermodel.Workbook;
import org.redkale.convert.Convert;
import org.redkale.net.http.*;
import org.redkale.util.AnyValue;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;
/**
* @author: liangxianyou
*/
public class MetaRender implements HttpRender<HttpScope> {
@Override
public void init(HttpContext context, AnyValue config) {
}
@Override
public <V extends HttpScope> void renderTo(HttpRequest request, HttpResponse response, Convert convert, V scope) {
Map<String, Object> attr = scope.getAttributes();
if ("excel".equals(scope.getReferid())) {
List list = (List) attr.get("data");
Kv heads = (Kv) attr.get("heads");
String fileName = (String) attr.get("fileName");
try {
Workbook workbook = ExcelKit.exportExcel(list, heads);
File file = new File(String.format("tmp/%s.xls", fileName));
file.getParentFile().mkdirs();
if (file.exists()) file.delete();
FileOutputStream fos = new FileOutputStream(file);
workbook.write(fos);
try {
fos.close();
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
response.finish(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public Class<HttpScope> getType() {
return HttpScope.class;
}
}

View File

@@ -8,9 +8,9 @@ import java.util.List;
*/ */
public class FBean { public class FBean {
private String platToken; //plat token private String platToken; // 平台token
String name; // service key private String name; // 业务名称
private String type; // 操作类型 listexport private String type; // 操作类型 list:列表export:导出
private List<Filter> filters;//[{f:xx, v: v, type:t}] -- t, private List<Filter> filters;//[{f:xx, v: v, type:t}] -- t,
private List<Order> orders;//{f1: 1, f2: -1} private List<Order> orders;//{f1: 1, f2: -1}
@@ -34,6 +34,14 @@ public class FBean {
this.name = name; this.name = name;
} }
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Filter> getFilters() { public List<Filter> getFilters() {
return filters; return filters;
} }

View File

@@ -10,7 +10,6 @@ import net.tccn.meta.MetaTable;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -36,57 +35,6 @@ public class ParseMysql implements Parser {
return false; return false;
}; };
BiFunction<Filter, String, String> buildFilter = (f, cate) -> {
return null;
};
@Deprecated
/*Function<FBean, Kv<String, MetaTable>> tablesFun = fbean -> {
MetaService metaService = MetaKit.getMetaService(fbean.getName());
List<Filter> filters = fbean.getFilters();
List<String> shows = metaService.getShows();
Kv tables = Kv.of();
shows.forEach(x-> {
String table = x.split("[.]")[0];
tables.set(table, MetaKit.getMetaTableByAlias(table));
});
filters.forEach(f -> {
String table = f.getCol().split("[.]")[0];
if (!tables.containsKey(table)) {
tables.set(table, MetaKit.getMetaTableByAlias(table));
}
});
metaService.getShows();
//查询用的过滤条件
Map<String, List<Filter>> filterMap = filters.stream().collect(Collectors.groupingBy(x -> x.getCol().split("[.]")[0]));
//要展示的数据
Map<String, List<String>> showMap = shows.stream().collect(Collectors.groupingBy(x -> x.split("[.]")[0]));
StringBuffer bufWhere = new StringBuffer();
filterMap.getOrDefault(metaService.getTable(), asList()).forEach(f -> {
bufWhere.append(f.getCol()).append(f.getType()).append(f.getValue());
});
//select * from tableA a left join tableB b on a.xx = b.yy where b.zz = xxx;
//where tableB where b.
//是否跨库
return tables;
};*/
Predicate<Kv<String, MetaTable>> sameDbFun = (kv) -> { Predicate<Kv<String, MetaTable>> sameDbFun = (kv) -> {
String dbPlatId = null; String dbPlatId = null;
for (MetaTable metaTable : kv.values()) { for (MetaTable metaTable : kv.values()) {
@@ -105,7 +53,8 @@ public class ParseMysql implements Parser {
Kv<String, MetaTable> tables = MetaKit.getMetaTables(metaService, false);//所有的关联表信息 Kv<String, MetaTable> tables = MetaKit.getMetaTables(metaService, false);//所有的关联表信息
MetaTable metaTable = tables.get(metaService.getTable());//基础元数据 MetaTable metaTable = tables.get(metaService.getTable());//基础元数据
List<Map<String, String>> shows = metaService.getShows();//查询的属性 List<Map<String, String>> shows = metaService.getShows();//查询的属性-列表
List<Map<String, String>> exports = metaService.getExports();//查询的属性-导出
List<String> _filters = fBean.getFilters().stream().map(Filter::getCol).collect(Collectors.toList()); List<String> _filters = fBean.getFilters().stream().map(Filter::getCol).collect(Collectors.toList());
List<MetaLink> links = MetaKit.getMetaLinks( List<MetaLink> links = MetaKit.getMetaLinks(
@@ -132,9 +81,14 @@ public class ParseMysql implements Parser {
//select a.x, b.y, c.z //select a.x, b.y, c.z
StringBuffer bufSelect = new StringBuffer(); StringBuffer bufSelect = new StringBuffer();
bufSelect.append("select "); bufSelect.append("select ");
if (!isEmpty.test(shows)) { if ("export".equals(fBean.getType()) && !isEmpty.test(exports)) {
exports.forEach(x -> {
bufSelect.append(x.get("col")).append(" as ").append("'").append(x.get("col")).append("',");
});
bufSelect.deleteCharAt(bufSelect.length() - 1);
}
else if ("list".equals(fBean.getType()) && !isEmpty.test(shows)) {
shows.forEach(x -> { shows.forEach(x -> {
//buf.append("`").append("x").append("`").append(",");
bufSelect.append(x.get("col")).append(" as ").append("'").append(x.get("col")).append("',"); bufSelect.append(x.get("col")).append(" as ").append("'").append(x.get("col")).append("',");
}); });
bufSelect.deleteCharAt(bufSelect.length() - 1); bufSelect.deleteCharAt(bufSelect.length() - 1);
@@ -178,31 +132,4 @@ public class ParseMysql implements Parser {
return null; return null;
} }
/*@Override
public String parse(Filter filter) {
return null;
}
@Override
public String parseSave(MetaService ms, Map data) {
MetaTable metaTable = MetaKit.getMetaTableByAlias(ms.getName());//基础元数据
String sqlTpl = "insert %s (%s) value (%s)";
StringBuilder bufK = new StringBuilder();
StringBuilder bufV = new StringBuilder();
data.forEach((k,v) -> {
if (v != null || !String.valueOf(v).isEmpty()) {
bufK.append("`").append(k).append("`,");
if (v instanceof Number) {
bufV.append(v).append(",");
} else {
bufV.append("'").append(v).append("',");
}
}
});
bufK.deleteCharAt(bufK.length() - 1);
bufV.deleteCharAt(bufV.length() - 1);
return String.format(sqlTpl, metaTable.getName(), bufK.toString(), bufV.toString());
}*/
} }

View File

@@ -1,8 +1,8 @@
package net.tccn.service; package net.tccn.service;
import com.lxyer.excel.poi.ExcelKit;
import net.tccn.base.JBean; import net.tccn.base.JBean;
import net.tccn.base.Kv; import net.tccn.base.Kv;
import net.tccn.base.MetaKit;
import net.tccn.base.PageBean; import net.tccn.base.PageBean;
import net.tccn.dbq.DbExecutors; import net.tccn.dbq.DbExecutors;
import net.tccn.dbq.fbean.FBean; import net.tccn.dbq.fbean.FBean;
@@ -32,6 +32,7 @@ public class DataService extends BaseService {
JBean jBean = new JBean(); JBean jBean = new JBean();
try { try {
fBean.setPlatToken(token); fBean.setPlatToken(token);
fBean.setType("list");
PageBean page = DbExecutors.findPage(fBean); PageBean page = DbExecutors.findPage(fBean);
jBean.setBody(page); jBean.setBody(page);
} catch (Exception e) { } catch (Exception e) {
@@ -52,15 +53,23 @@ public class DataService extends BaseService {
} }
@Comment("数据导出excel") @Comment("数据导出excel")
public HttpScope export(FBean fBean, @RestParam(name = "platToken") String token) { public HttpScope export(FBean fBean, String fileName, @RestParam(name = "platToken") String token) {
try { try {
fBean.setPlatToken(token); fBean.setPlatToken(token);
fBean.setType("export");
PageBean page = DbExecutors.findPage(fBean); PageBean page = DbExecutors.findPage(fBean);
Kv heads = MetaKit.cfgExport(fBean.getName(), token);
ExcelKit.exportExcel(page.getRows(), Kv.of()); if (isEmpty.test(fileName)) {
fileName = String.format("export_excel_%s", System.currentTimeMillis());
}
Kv attrs = Kv.of();
attrs.put("data", page.getRows());
attrs.put("heads", heads);
attrs.put("fileName", fileName);
return HttpScope.refer("excel").attr("data", page.getRows()).attr("heads", null); return HttpScope.refer("excel").attr(attrs);
} catch (ExecutionException | InterruptedException e) { } catch (ExecutionException | InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} catch (Exception e) { } catch (Exception e) {