Commit 4a097956 by guojuxing

下载组件

parent b4e0163a
...@@ -56,9 +56,34 @@ ...@@ -56,9 +56,34 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.gic</groupId> <groupId>com.gic</groupId>
<artifactId>gic-platform-enterprise-api</artifactId>
<version>${gic-platform-enterprise-api}</version>
</dependency>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-log-api</artifactId> <artifactId>gic-log-api</artifactId>
<version>${gic-log-api}</version> <version>${gic-log-api}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-thirdparty-sdk</artifactId>
<version>4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-platform-config</artifactId>
<version>${gic-platform-config}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package com.gic.download.utils;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.gic.thirdparty.BucketNameEnum;
import com.gic.thirdparty.FileOperateUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class BaseUtils {
private static final Logger LOGGER = LogManager.getLogger(BaseUtils.class);
private static final String SUFFIX_EXCEL_2007 = "xlsx";
private static final String SUFFIX_CSV = "csv";
private static final String SUFFIX_EXCEL_2003 = "xls";
/**
* 分页下载数据获取类
* @author Silver
* @date 2017年3月16日 上午11:45:13
*
* @param <T>
*
*/
protected abstract class DownloadDataLoader<T> {
/**
* 分页下载属性值控制操作类
* @param bean
* @param propertyName
* @param property
* @return
* @author Silver
* @date 2017年3月16日 上午11:45:45
*/
protected String convertProperty(T bean, String propertyName, Object property) {
return property == null ? "" : property.toString();
}
/**
* 分页下载属性赋值
* @param bean
* @param propertyName
* @return
* @author Silver
* @date 2017年3月16日 上午11:46:37
*/
protected Object getProperty(T bean, String propertyName) {
try {
return BeanUtils.getProperty(bean, propertyName);
} catch (Throwable e) {
LOGGER.info("bean:" + bean + ",Property:" + propertyName + e.getMessage(), e);
return null;
}
}
/**
* 数据获取接口
* @param pageNum -- 从0计数
* @return
* @throws Exception
* @author Silver
* @date 2017年3月16日 上午11:47:07
*/
protected abstract List<T> getDownloadData(Integer pageNum) throws Exception;
};
protected static interface Writer {
public void write(Collection<String> row) throws IOException;
}
/**
* Web下载文件
* @param tempPath 临时路径
* @param reportId 报表中心ID
* @param fileName 文件名称,如果文件名称为空的情况默认【 日期.csv】格式
* @param header 表头名称
* @param columnWidth 列宽
* @param loader 数据加载类
* @param propertyNames
* @throws Exception
* @author Silver
* @date 2017年3月16日 上午11:47:31
*/
protected <T> void download(String tempPath, Integer reportId, String fileName, List<String> header, List<Integer> columnWidth, DownloadDataLoader<T> loader, List<String> propertyNames) throws Exception {
if (StringUtils.isEmpty(fileName) || loader == null || CollectionUtils.isEmpty(propertyNames)) {
throw new RuntimeException("参数错误。FileName:" + fileName + ",DataLoader:" + loader + ",PropertyName:" + propertyNames);
}
// 获取输出流,设置content-type等头域
//final OutputStream out = getResponseStream(response ,fileName);
File tempFile = null;
//重置临时文件路径
DataDownloadUtils.mkDir(new File(tempPath));
File file = new File(tempPath);
//初始化数据
tempFile = File.createTempFile(fileName, ".csv", file);
final OutputStream out = new FileOutputStream(tempFile);
try {
Writer writer = null;
// 获取文件后缀名
String extension = FilenameUtils.getExtension(fileName);
// 如果是excel的后缀
if (SUFFIX_EXCEL_2003.equalsIgnoreCase(extension) || SUFFIX_EXCEL_2007.equalsIgnoreCase(extension)) {
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("sheet1");
final List<Collection<String>> rows = new ArrayList<>();
writer = new Writer() {
@Override
public void write(Collection<String> row) {
rows.add(row);
}
};
writeOutputStream(loader, propertyNames, writer);
// 写入excel
if (!ExcelUtils.setExcelInfo(sheet, columnWidth, header, rows)) {
throw new IOException("设置导出文件内容失败。");
}
workbook.write(out);
} else if (SUFFIX_CSV.equalsIgnoreCase(extension)) {
writer = new Writer() {
@Override
public void write(Collection<String> row) throws IOException {
String str = ExcelUtils.collectionToCsvString(row);
byte[] content = org.apache.commons.codec.binary.StringUtils.getBytesUnchecked(str + "\n",
"GBK");
IOUtils.write(content, out);
out.flush();
}
};
// 写文件头
writer.write(header);
// 写文件
writeOutputStream(loader, propertyNames, writer);
} else {
writer = new Writer() {
@Override
public void write(Collection<String> row) throws IOException {
IOUtils.write(org.apache.commons.codec.binary.StringUtils.getBytesUnchecked(row + "\n",
"GBK"), out);
out.flush();
}
};
// 写文件头
writer.write(header);
// 写文件
writeOutputStream(loader, propertyNames, writer);
}
out.flush();
tempFile.deleteOnExit();
//上传文件
String fieldCode = "/" + System.currentTimeMillis() + "_" + fileName;
//文件存进腾讯云
String url = FileOperateUtils.simpleUploadFileFromLocal(tempFile, fieldCode, BucketNameEnum.REPORT_50000.getName());
if (org.apache.commons.lang.StringUtils.isNotBlank(url)) {
url = "https://" + url;
}
LOGGER.info("上传文件到腾讯云,路径:" + url);
//更新数据
DataDownloadUtils.uploadFile(3, url);
} finally {
IOUtils.closeQuietly(out);
}
}
/**
* 获得输出流
*
* @return
* @throws IOException
*/
protected OutputStream getResponseStream(HttpServletResponse response, String fileName) throws IOException {
if (StringUtils.isEmpty(fileName)) {
fileName = DateUtils.formatDate(new Date(), "yyyy-MM-dd_HH-mm-ss") + SUFFIX_CSV;
}
response.reset();
String extension = FilenameUtils.getExtension(fileName);
if(SUFFIX_EXCEL_2007.equalsIgnoreCase(extension)){
// 部分window版本生成后的xlsx打不开,默认改成xls打开
fileName = fileName.substring(0, fileName.length() -1);
}
//设置响应编码
response.setCharacterEncoding("UTF-8");
//设置对应的contentType
response.setContentType("application/x-download;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename="
+ new String(fileName.getBytes("gb2312"), "ISO-8859-1"));
OutputStream out = response.getOutputStream();
return out;
}
protected <T> void writeOutputStream(DownloadDataLoader<T> loader, List<String> propertyNames,
Writer writer) throws Exception {
int pageNum = 1;
int maxLength = 102400;
while (maxLength -- > 0) {
// 分页获取数据
List<T> objList = null;
try {
objList = loader.getDownloadData(pageNum++);
} catch (Exception e) {
LOGGER.error("获得到处数据异常:{}",e.getMessage(), e);
}
if (CollectionUtils.isEmpty(objList)) {
break;
}
for (T bean : objList) {
if (bean == null) {
continue;
}
Collection<String> result = new ArrayList<String>();
// 遍历指定属性
for (String name : propertyNames) {
// 获得属性值
Object property = loader.getProperty(bean, name);
// 将属性值转换成字符串
String convertValue = loader.convertProperty(bean, name, property);
// 组装成row
result.add(convertValue);
}
if (CollectionUtils.isEmpty(result)) {
continue;
}
writer.write(result);
}
}
}
}
package com.gic.download.utils;
import java.io.Serializable;
import java.util.List;
/**
* 工具初始化参数
* @ClassName: DataDownload

* @Description: 

* @author guojuxing

* @date 2019/11/5 9:53 AM

*/
public class DataDownload implements Serializable{
private static final long serialVersionUID = -3448865281389941085L;
/**
* 报表中心ID
*/
private Integer reportId;
/**
* 待下载文件名
*/
private String fileName;
/**
* 待下载文件临时路径
*/
private String tempPath;
/**
* 下载字段名,用于反射获取字段值
*/
private List<String> fieldList;
/**
* 待下载文件标题,一一对应字段名
*/
private List<String> titleList;
/**
* 数据总页数,用于分页生成csv,避免内存溢出
*/
private int totalPage;
public Integer getReportId() {
return reportId;
}
public void setReportId(Integer reportId) {
this.reportId = reportId;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getTempPath() {
return tempPath;
}
public void setTempPath(String tempPath) {
this.tempPath = tempPath;
}
public List<String> getFieldList() {
return fieldList;
}
public void setFieldList(List<String> fieldList) {
this.fieldList = fieldList;
}
public List<String> getTitleList() {
return titleList;
}
public void setTitleList(List<String> titleList) {
this.titleList = titleList;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
}
package com.gic.download.utils;
import java.io.Serializable;
import java.util.Date;
/**
* 创建下载记录的参数
* @ClassName: DownloadReport

* @Description: 

* @author guojuxing

* @date 2019/11/4 7:52 PM

*/
public class DownloadReport implements Serializable{
private static final long serialVersionUID = -8175883273955206619L;
private Integer enterpriseId;
/**
* 申请人ID
*/
private Integer applyUserId;
/**
* 待下载数据的开始世界
*/
private Date reportStartTime;
/**
* 待下载数据的结束世界
*/
private Date reportEndTime;
/**
* 待下载文件名
*/
private String fileName;
/**
* 数据源(频道页),用 "-" 隔开上级和本级
*/
private String dataContent;
/**
* 数据源超链接,用于点击跳转对应频道页面
*/
private String dataUrl;
/**
* 报告类型 1:完整数据, 2:脱敏数据, 3:二维码
*/
private Integer dataType;
/**
* 待下载数据的数据总量
*/
private Integer dataCount;
public Integer getEnterpriseId() {
return enterpriseId;
}
public void setEnterpriseId(Integer enterpriseId) {
this.enterpriseId = enterpriseId;
}
public Integer getApplyUserId() {
return applyUserId;
}
public void setApplyUserId(Integer applyUserId) {
this.applyUserId = applyUserId;
}
public Date getReportStartTime() {
return reportStartTime;
}
public void setReportStartTime(Date reportStartTime) {
this.reportStartTime = reportStartTime;
}
public Date getReportEndTime() {
return reportEndTime;
}
public void setReportEndTime(Date reportEndTime) {
this.reportEndTime = reportEndTime;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getDataContent() {
return dataContent;
}
public void setDataContent(String dataContent) {
this.dataContent = dataContent;
}
public String getDataUrl() {
return dataUrl;
}
public void setDataUrl(String dataUrl) {
this.dataUrl = dataUrl;
}
public Integer getDataType() {
return dataType;
}
public void setDataType(Integer dataType) {
this.dataType = dataType;
}
public Integer getDataCount() {
return dataCount;
}
public void setDataCount(Integer dataCount) {
this.dataCount = dataCount;
}
}
package com.gic.download.utils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.inject.Singleton;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 线程池单例类
* 用于导出数据异步使用
* @ClassName: ExecutorPoolSingleton

* @Description: 

* @author guojuxing

* @date 2019/11/5 7:56 PM

*/
public class ExecutorPoolSingleton {
private Logger logger = LogManager.getLogger(ExecutorPoolSingleton.class);
private static final int availableProcessor = Runtime.getRuntime().availableProcessors();
private static ExecutorService executorService;
private ExecutorPoolSingleton() {
if (executorService == null) {
int coreNum = availableProcessor / 2;
// 用单例模式创建线程池,保留2个核心线程,最多线程为CPU个数的2n+1的两倍.
int maxProcessor = (availableProcessor * 2 + 1) * 2 ;
executorService = new ThreadPoolExecutor(coreNum > 2 ? 2 : coreNum, maxProcessor,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
}
private static ExecutorPoolSingleton instance;
public static ExecutorPoolSingleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new ExecutorPoolSingleton();
}
}
}
return instance;
}
int executeThreadNum = 1;
/**
* 执行任务
* @param runnable
*/
public void executeTask(Runnable runnable) {
executorService.execute(runnable);
logger.info("异步线程执行了%d次:{} ", executeThreadNum++);
}
}
package com.gic.enterprise.utils;
public class DataDownloadUtils {
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment