Hexo


  • 首页

  • 关于

  • 分类

  • 归档

Excel导出功能

发表于 2019-07-16 | 分类于 小功能 | 阅读次数:

1、前端导出请求后台

2、后台根据查询条件、字段关联关系,生成导出文件及导出路径

Controller中 将数据、对应关系、导出文件名封装为Vo ExcelDataVo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@ResponseBody
@RequestMapping(value = "/export.do")
public ExcelExportVo export(PageResult<DataSafetyVo> page, DataSafetyVo dataSafetyVo, HttpServletRequest request) throws Exception {
// 查询数据列表
List<DataSafetyVo> dataSafetyVoList = pagingList(page, dataSafetyVo).getRows();
if (CollectionUtils.isNotEmpty(dataSafetyVoList)) {
ExcelDataVo excelVo = new ExcelDataVo<>(dataSafetyVoList, "导出文件名", initMappingRelation());
// 最大导出数量
Integer exportMaxRow = CommonConstant.EXPORT_MAX_ROW;
String template = request.getSession().getServletContext().getRealPath("/") + "download/excel.xls";
return ExcelUtil.exportByTemplate(request, excelVo, exportMaxRow, template);
}
return null;
}
private String initMappingRelation() {
return "Date:时间|Name:名称|User:用户|TotalNum:总量|FirstLevelNum:一级|SecondLevelNum:二级|ThirdLevelNum:三级|FouthLevelNum:四级";
}

3、将生成的文件名及导出路径返回前端

工具类 ExcelUtil.java

返回Vo ExcelExportVo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static <T> ExcelExportVo exportByTemplate(HttpServletRequest request, ExcelDataVo<T> excelVo,
Integer exportMaxRow, String template) throws Exception {
// 导出数据
List<Object[]> exportList = initExport(excelVo.getDataList(), excelVo.getMappingRelation());
// 导出文件名称
String fileName = excelVo.getFileName();
String filePath;
if (exportList.size() < exportMaxRow) {
// excel导出
filePath = exportExcel(request, exportList, fileName, template);
return new ExcelExportVo(filePath, fileName + ".xls");
} else {
// zip导出
filePath = exportZip(request, exportList, fileName, exportMaxRow, template);
return new ExcelExportVo(filePath, fileName + ".zip");
}
}

4、前端根据返回数据,继续请求后台进行文件下载

前端请求(以vue为例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
exportData(params).then( res => {
if( res.status === 'success') {
// 下载附件
exportFn(res.message.filePath, res.message.fileName)
} else {
this.$message({
showClose: true,
message: res.message,
type: 'error'
})
}
loadingInstance.close()
}).catch( err => {
console.log(err)
loadingInstance.close()
})


在工具类中复制下面的方法,在需要导出的页面进行引用即可
/**
* [exportFn 导出文件]
* @param {[type]} filePath [服务端导出文件的路径]
* @param {[type]} fileName [服务端导出文件的名称]
* @return {[type]} [description]
*/
export function exportFn(filePath, fileName) {
const a = document.createElement('a')
const baseUrl = '/home-web/common/excel/exportDownload.do'
a.download = fileName
a.href = encodeURI(`${baseUrl}?filePath=${filePath}&fileName=${fileName}`)
a.style.display = 'none'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}

5、导出成功

下载公共类 ExcelController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
*
* <p>Title: exportDownload
* <p>Description: 文件下载通用类 <em>下载完成后会删除文件目录</em>
* @author LXL
* @param request
* 获取项目路径
* @param response
* 输出流
* @param filePath
* 文件路径
* @param fileName
* 文件名称
* @date 2018/2/2 10:39
*/
@ResponseBody
@RequestMapping(value = "/exportDownload.do")
public void exportDownload(HttpServletRequest request, HttpServletResponse response, String filePath, String fileName) {
try {
downloadResponse(request, response, filePath, fileName);
} catch (Exception e) {
log.error("导出alone_export_data失败", e);
}
}

6、备注

1、相关代码已给出超链接

2、工具类 ExcelUtil.java 中也封装了导出zip文件的方法(多个excel文件合并了一个zip文件)

集成SpringJDBC

发表于 2019-07-16 | 分类于 小功能 | 阅读次数:

1、spring.xml配置文件中配置连接池,id为datasource(必须,以c3p0为例),其余属性在jdbc.config配置文件中进行配置,在引入spring.xml文件中即可

image

2、同样在spring.xml中进行jdbc配置

DataSource,数据源(即上一步所配置的连接池)

MaxRows,使用jdbc一次查询出的最大数量 image

3、将获取jdbc连接封装进工具类中,同样在Spring.xml中进行配置

在Spring.xml中进行配置 image

将jdbc连接封装进SpringUtil中,提供getJdbcTemplete方法调用jdbc 对属性提供set/get方法 image

4、即可使用DbUtil进行jdbc查询

DbUtils.java

集成Springcontext上下文环境

发表于 2019-07-16 | 分类于 小功能 | 阅读次数:
具体工具类见 上传资源->util工具类->SpringContextUtil

一、将工具类放入项目中

二、在applicationContext.xml中添加SpringContextUtil.java配置即可

1
<bean class="com.seentech.ucenter.sysmanage.utils.SpringContextUtil" lazy-init="false" />

三、使用方法,在需要加载bean的地方调用即可

1
AccessLogQueryService accessLogQueryService = SpringContextUtil.getBean("accessLogQueryService");

common-pool2手写连接池

发表于 2019-07-16 | 分类于 小功能 | 阅读次数:

背景:使用common-pool2框架手写连接池(例如es连接池),提升创建es连接的性能

以es连接池为例,代码见 上传资源->util工具类->es连接池 文件夹

一、maven引入common-pool2依赖

1
2
3
4
5
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>

二、创建一个池类,这个池通过依赖的方式引入commons-pool2中的GenericObjectPool。在这个类中,我们定义了如何从池中借对象和返回对象

Pool.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public T getResource(){
try {
return internalPool.borrowObject();
} catch (Exception e) {
log.info("Could not get a resource from the pool", e);
}
return null;
}


public void returnResource(final T resource){
if (resource != null) {
returnResourceObject(resource);
}
}

三、创建ES的连接池,继承池类

ElasticSearchPool.java

1
2
3
4
5
6
7
8
private String clusterName;
private HostAndPort hostAndPort;

public ElasticSearchPool(ElasticSearchPoolConfig config,HostAndPort hostAndPort){
super(config, new ElasticSearchClientFactory(config.getClusterName(), hostAndPort));
this.clusterName = config.getClusterName();
this.hostAndPort = hostAndPort;
}

四、定义了一个ES的连接池配置类用于配置连接池的属性,在apache提供的commons-pool2中已经提供了一个池基本属性配置的类GenericObjectPoolConfig,我们可以直接继承此类

ElasticSearchPoolConfig.java

1
2
3
4
5
6
7
/**
*有很多配置项,这里只选择两种进行展示
*/
//超时时间
private long connectTimeMillis;
//集群名称
private String clusterName;

五、ES连接属性配置类

HostAndPort.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//ip
private String host ;
//端口
private int port ;
//连接协议
private String schema;

public HostAndPort(String host, int port, String schema) {
this.host = host;
this.port = port;
this.schema = schema;
}

//使用如下
HostAndPort hostAndPort = new HostAndPort("172.31.133.21",19200,"http");

六、最后,我们还需要做的是给这个池提供一个工厂类,用于创建池中的对象和回收对象,我们只要实现PooledObjectFactory接口并实现接口中的makeObject()和destroyObject()方法即可

ElasticSearchClientFactory.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private HostAndPort hostAndPort;

private String clusterName;

public ElasticSearchClientFactory(String clusterName, HostAndPort hostAndPort){
this.clusterName = clusterName;
this.hostAndPort = hostAndPort;
}

@Override
public PooledObject<RestClient> makeObject() throws Exception {
RestClient client = RestClient.builder(new HttpHost(hostAndPort.getHost(),hostAndPort.getPort(),hostAndPort.getSchema())).build();
return new DefaultPooledObject<>(client);
}

@Override
public void destroyObject(PooledObject<RestClient> pooledObject) throws Exception {
RestClient client = pooledObject.getObject();
if(client!=null){
try {
client.close();
}catch (Exception e){
//ignore
}
}
}

七、验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ElasticSearchPoolTest {

public static void main(String[] args) throws Exception {
HostAndPort hostAndPort = new HostAndPort("172.31.133.21",19200,"http");
ElasticSearchPoolConfig config = new ElasticSearchPoolConfig();
//超时时间
config.setConnectTimeMillis(8000);
//最大连接
config.setMaxTotal(10);
//集群名称
config.setClusterName("idc_es");
ElasticSearchPool pool = new ElasticSearchPool(config,hostAndPort);

for(int i=0;i<100;i++){
RestClient client = (RestClient)pool.getResource();
System.out.println(client.toString());
pool.returnResource(client);
}
}

}

Xml转Object(xstream及自定义解析)

发表于 2019-07-16 | 分类于 小功能 | 阅读次数:

xml格式转为object对象,分三种情况:

1、常规标签格式转化

2、标签属性格式转化

3、两种方式相结合的xml格式转化

备注:需要用到的jar包 xstream,xpp3

一、常规标签格式转化

主要使用xstream中 @XStreamAlias 标签,将xml标签和实体类属性进行一一对应后,使用util类转化方法进行转化即可。

xml格式如下:

1
2
3
4
<User>
<userName>lanweihong</userName>
<email>lwhhhp@gmail.com</email>
</User>

User.java

1
2
3
4
5
6
7
8
9
10
@XStreamAlias("User")
public class User {

@XStreamAlias("userName")
private String userName;

@XStreamAlias("email")
private String email;

}

转化方式:

1
User user = XmlUtils.xmlToObject(xmlStr);

二、标签属性格式转化

主要使用xstream中 @XStreamAsAttribute 和 @XStreamImplicit 标签,将xml标签的属性和实体类属性进行一一对应后进行转化即可。

xml格式如下:

1
2
3
4
5
<?xml version="1.0" encoding="UTF-8"?>
<info id="200000000002" type="general_log_info" resultnum="40000">
<log SeviceGroup="15" SeviceType="401" User-Agent="1"></log>
<log SeviceGroup="16" SeviceType="402" User-Agent="2"></log>
</info>

Info.java

最外层标签使用 @XStreamAlias 对应实体类名

标签属性使用 @XStreamAsAttribute 对应实体类属性(字段名称必须一致)

内层集合标签使用 @XStreamImplicit(itemFieldName = “log”) 对应实体类集合属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@XStreamAlias("info")
public class HttpInfoVo {

@XStreamAsAttribute
private String id;

@XStreamAsAttribute
private String type;

@XStreamAsAttribute
private String resultnum;

@XStreamImplicit(itemFieldName = "log")
private List<HttpLogVo> logs = new ArrayList<HttpLogVo>();
}

Log.java

1
2
3
4
5
6
7
8
9
10
11
12
13
@XStreamAlias("log")
public class HttpLogVo {

@XStreamAsAttribute
private String SeviceGroup;

@XStreamAsAttribute
private String SeviceType;

@XStreamAsAttribute
private String userAgent;

}

转化方法

因为实体类属性不能使用”-“这类特殊符号,所以讲xml读取后要将带有”-“的字段进行转化(如User-Agent转为userAgent,转化后的字段保持与实体类字段一致即可)

1
2
3
4
5
6
XStream xstream = new XStream(new DomDriver());
xstream.autodetectAnnotations(true);
xstream.processAnnotations(Info.class);
xmlStr = xmlStr.replaceAll("User-Agent","userAgent");

Info info = (Info) xstream.fromXML(xmlStr);

三、两种xml格式相结合的xml转化

xml样例如下:

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<info id="200000000002" type="general_log_info" resultnum="40000">
<log SeviceGroup="15" SeviceType="401" User-Agent="1">
<id>1</id>
<name>test</name>
</log>
<log SeviceGroup="16" SeviceType="402" User-Agent="2"></log>
</info>

此时只需针对内层的标签添加 @XStreamAlias 对应实体类属性名即可

更改后的Log.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@XStreamAlias("log")
public class HttpLogVo {

@XStreamAsAttribute
private String SeviceGroup;

@XStreamAsAttribute
private String SeviceType;

@XStreamAsAttribute
private String userAgent;

@XStreamAlias("id")
private String id;

@XStreamAlias("name")
private String name;

}

四、自定义xml解析(性能最好)

引入maven依赖

1
2
3
4
5
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
private HttpInfoVo getLogsByXml(String line) {
InputStream in = new ByteArrayInputStream(line.getBytes());
SAXReader reader = new SAXReader();
Document doc = null;
Element root = null;
try {
doc = reader.read(in);
root = doc.getRootElement();
} catch (DocumentException e) {
logger.info("xml文件读取失败!",e);
}

HttpInfoVo info = new HttpInfoVo();
List<HttpLogVo> logVos = new ArrayList<>();
if("info".equals(root.getName())) {
//获取info标签中的type属性值,用于区分http和gene话单
String type = root.attributeValue("type");
info.setType(type);
List<Element> elements = root.elements();
for (Element element : elements) {
if ("log".equals(element.getName())) {
HttpLogVo log = new HttpLogVo();
log.setMsisdn(element.attributeValue("MSISDN"));
log.setSeviceGroup(element.attributeValue("SeviceGroup"));
log.setSeviceType(element.attributeValue("SeviceType"));
String imsi = element.attributeValue("IMSI");
String imei = element.attributeValue("IMEI");
log.setIMSIIMEI(imsi+"/"+imei);
log.setApn(element.attributeValue("APN"));
log.setNetType(element.attributeValue("NetType"));
log.setSgsnIp(element.attributeValue("SGSN_IP"));
log.setSgsnPort(element.attributeValue("SGSN_PORT"));
log.setGgsnIp(element.attributeValue("GGSN_IP"));
log.setGgsnPort(element.attributeValue("GGSN_PORT"));
log.setsIP(element.attributeValue("SIP"));
log.setSport(element.attributeValue("Sport"));
log.setdIP(element.attributeValue("DIP"));
log.setDport(element.attributeValue("Dport"));
log.setDate(element.attributeValue("Date"));
log.setUserAgent(element.attributeValue("User-Agent"));
log.settVendor(element.attributeValue("TVENDOR"));
log.settModel(element.attributeValue("TMODEL"));
log.settType(element.attributeValue("TTYPE"));
if ("http_log_info".equals(type)) {
log.setUrl(element.attributeValue("URL"));
log.setHost(element.attributeValue("Host"));
log.setxOnlineHost(element.attributeValue("X-online-Host"));
log.setContentType(element.attributeValue("Content-Type"));
log.setHttpCmd(element.attributeValue("HTTP-CMD"));
log.setContentLength(element.attributeValue("Content-Length"));
}
logVos.add(log);
}
}

//log节点解析完毕后
info.setLogs(logVos);
}
return info;
}

Linux常用命令

发表于 2019-07-15 | 分类于 常用命令 > shell | 阅读次数:

获取当前所在目录

currentdir=$(cd “$(dirname “$0”)”; pwd)

date和+中间要有空格,获取当前时间和日期

baktime=date "+%Y-%m-%d-%H-%M-%S"
clear_dir=date +"%Y-%m-%d" -d'-1 day'
remove_date=date "+%Y-%m-%d"

获取$app项目的进程号

ps -ef | grep $app| grep -v grep | awk ‘{ print $2 }’

查找某目录下两天前的.log文件,并删除

find $ROOT_DIR/* -type f -name *.log -mtime +2 -exec rm -rf {} ;

Linux常用命令

发表于 2019-07-15 | 分类于 常用命令 > Redis | 阅读次数:

redis key的数量( 集群)

redis-cli -c -p 16379 -h 172.31.133.98 -a yhsj_idc@act keys “*” |wc -l

Linux常用命令

发表于 2019-07-15 | 分类于 常用命令 > Mysql | 阅读次数:

开通访问权限

all privileges on . to rooact@’172.31.131.31’ identified by ‘Yhsj_idc@2019’;

flush privileges;

Linux常用命令

发表于 2019-07-15 | 分类于 常用命令 > Linux | 阅读次数:

防火墙状态

systemctl status firewalld.service

通过进程号,找到软件安装目录

ls -l /proc/xxxx/cwd (XXXXX代表进程号)

端口号占用

netstat -nltp | grep port

每个文件夹大小(* 可以替换成任意目录)

du -hls *

执行rpm包

rpm -ivh ucenter.rpm –force

Linux常用命令

发表于 2019-07-15 | 分类于 常用命令 > Kafka | 阅读次数:

kafka启动

bin/kafka-server-start.sh config/server.properties

kafka生产者启动

bin/kafka-console-producer.sh –broker-list localhost:20882 –topic test

kafka消费者启动

bin/kafka-console-consumer.sh –zookeeper localhost:48890 –topic test –from-beginning

kafka创建topic

bin/kafka-topics.sh –create –zookeeper localhost:2181 –replication-factor 3 –partitions 3 –topic test

kafka topic列表

bin/kafka-topics.sh –list –zookeeper localhost:48889

123

Liang2L

21 日志
12 分类
© 2019 Liang2L
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4