parent
3f2007cf9f
commit
47f9f95818
@ -0,0 +1,47 @@ |
|||||||
|
package com.keyware.shandan.bianmu.export; |
||||||
|
|
||||||
|
import com.keyware.shandan.common.util.StringUtils; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Optional; |
||||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||||
|
|
||||||
|
public class ExportCache { |
||||||
|
private final static ConcurrentHashMap<String, Map<String, ExportProgress>> cache = new ConcurrentHashMap<>(); |
||||||
|
|
||||||
|
public static void startExport(ExportProgress progress) { |
||||||
|
Map<String, ExportProgress> userCache = cache.get(progress.getUserId()); |
||||||
|
if (userCache == null) { |
||||||
|
userCache = new HashMap<>(); |
||||||
|
} |
||||||
|
userCache.put(progress.getExportId(), progress); |
||||||
|
cache.put(progress.getUserId(), userCache); |
||||||
|
new Thread(progress).start(); |
||||||
|
} |
||||||
|
|
||||||
|
public static <T extends ExportProgress> T getCache(String userId, String exportId) { |
||||||
|
Map<String, ExportProgress> userCache = cache.get(userId); |
||||||
|
if (userCache == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
if (StringUtils.hasText(exportId)) { |
||||||
|
return (T) userCache.get(exportId); |
||||||
|
} |
||||||
|
Optional<ExportProgress> optional = userCache.values().stream().findFirst(); |
||||||
|
if (optional.isPresent()) { |
||||||
|
return (T) optional.get(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public static <T extends ExportProgress> T popCache(String userId, String exportId) { |
||||||
|
Map<String, ExportProgress> userCache = cache.get(userId); |
||||||
|
if (userCache == null) { |
||||||
|
return null; |
||||||
|
} else { |
||||||
|
ExportProgress progress = userCache.remove(exportId); |
||||||
|
return (T) progress; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,90 @@ |
|||||||
|
package com.keyware.shandan.bianmu.export; |
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil; |
||||||
|
import com.keyware.shandan.common.util.UUIDUtil; |
||||||
|
import com.keyware.shandan.frame.config.component.AppContext; |
||||||
|
import com.keyware.shandan.frame.properties.CustomProperties; |
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
@Data |
||||||
|
public abstract class ExportProgress implements Runnable, Serializable { |
||||||
|
|
||||||
|
private String exportId = UUIDUtil.getUUID(); |
||||||
|
private String userId; |
||||||
|
private String title; |
||||||
|
private Integer currentStep = 0; |
||||||
|
protected final String tempDir; |
||||||
|
|
||||||
|
protected boolean error = false; |
||||||
|
|
||||||
|
public ExportProgress(String userId) { |
||||||
|
this.userId = userId; |
||||||
|
this.title = "正在查询需要导出的数据"; |
||||||
|
CustomProperties customProperties = AppContext.getContext().getBean(CustomProperties.class); |
||||||
|
tempDir = customProperties.getFileStorage().getTempPath(); |
||||||
|
} |
||||||
|
|
||||||
|
public abstract void run(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 进度总步数 |
||||||
|
*/ |
||||||
|
public abstract long getStepTotal(); |
||||||
|
|
||||||
|
public abstract String getDownloadPath(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 偏移量自增 |
||||||
|
*/ |
||||||
|
public void autoAddStep() { |
||||||
|
this.currentStep++; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取百分比 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public int getPercentage() { |
||||||
|
return Math.round(currentStep / (float) getStepTotal() * 100); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断是否完成 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public boolean getIsDone() { |
||||||
|
return currentStep == getStepTotal(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void setDone() { |
||||||
|
currentStep = getCurrentStep(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getMsg() { |
||||||
|
return "(" + getPercentage() + "%) " + this.title; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, Object> getProgress() { |
||||||
|
Map<String, Object> map = new HashMap<>(); |
||||||
|
map.put("exportId", exportId); |
||||||
|
map.put("title", title); |
||||||
|
map.put("msg", getMsg()); |
||||||
|
map.put("isDone", getIsDone()); |
||||||
|
map.put("isError", error); |
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
public void clean() { |
||||||
|
File file = new File(getDownloadPath()); |
||||||
|
if (file.exists()) { |
||||||
|
FileUtil.del(file); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,119 @@ |
|||||||
|
package com.keyware.shandan.bianmu.export; |
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil; |
||||||
|
import cn.hutool.poi.excel.BigExcelWriter; |
||||||
|
import cn.hutool.poi.excel.ExcelUtil; |
||||||
|
import cn.hutool.poi.excel.ExcelWriter; |
||||||
|
import com.alibaba.fastjson.JSONArray; |
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.keyware.shandan.bianmu.entity.MetadataBasicVo; |
||||||
|
import com.keyware.shandan.bianmu.service.MetadataService; |
||||||
|
import com.keyware.shandan.common.util.StreamUtil; |
||||||
|
import com.keyware.shandan.common.util.StringUtils; |
||||||
|
import com.keyware.shandan.frame.config.component.AppContext; |
||||||
|
import org.apache.ibatis.session.ResultContext; |
||||||
|
import org.apache.ibatis.session.ResultHandler; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.function.Consumer; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
public class MetaTableExport extends ExportProgress implements ResultHandler<HashMap<String, Object>> { |
||||||
|
private final MetadataBasicVo metadata; |
||||||
|
private Consumer<Object> queryFunc; |
||||||
|
private final String fileName; |
||||||
|
private JSONArray colsArray; |
||||||
|
private final MetadataService metadataService; |
||||||
|
|
||||||
|
// 所有行的集合
|
||||||
|
private List<List<String>> rowList = new ArrayList<>(); |
||||||
|
// 字段列名集合
|
||||||
|
private List<String> colNameList = new ArrayList<>(); |
||||||
|
private int dataTotal; |
||||||
|
|
||||||
|
public MetaTableExport(String userId, MetadataBasicVo metadata) { |
||||||
|
super(userId); |
||||||
|
this.metadataService = AppContext.getContext().getBean(MetadataService.class); |
||||||
|
this.metadata = metadata; |
||||||
|
String name = metadata.getMetadataComment(); |
||||||
|
if (!StringUtils.hasText(name)) { |
||||||
|
name = metadata.getMetadataName(); |
||||||
|
} |
||||||
|
fileName = tempDir + File.separator + name + ".xlsx"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
this.setTitle("正在读取数据表信息"); |
||||||
|
colsArray = metadataService.getColumns(metadata.getId()); |
||||||
|
|
||||||
|
// 添加第一行,字段列名注释集合,当做表格的第一行
|
||||||
|
rowList.add(colsArray.stream().map((json) -> { |
||||||
|
JSONObject field = (JSONObject) json; |
||||||
|
String comment = field.getString("comment"); |
||||||
|
String colName = field.getString("columnName"); |
||||||
|
colNameList.add(colName); |
||||||
|
return colName + (StringUtils.hasText(comment) ? "[" + comment + "]" : ""); |
||||||
|
}).collect(Collectors.toList())); |
||||||
|
|
||||||
|
this.setTitle("正在读取数据到临时文件"); |
||||||
|
|
||||||
|
// 执行数据查询
|
||||||
|
try { |
||||||
|
queryFunc.accept(null); |
||||||
|
|
||||||
|
File file = new File(fileName); |
||||||
|
if(file.exists()){ |
||||||
|
file.delete(); |
||||||
|
} |
||||||
|
List<List<String>> rows = CollUtil.newArrayList(rowList); |
||||||
|
//通过工具类创建writer
|
||||||
|
ExcelWriter writer = ExcelUtil.getWriter(file); |
||||||
|
//一次性写出内容
|
||||||
|
writer.write(rows); |
||||||
|
//关闭writer,释放内存
|
||||||
|
writer.close(); |
||||||
|
this.setTitle("数据文件准备完毕,开始下载"); |
||||||
|
this.setDone(); |
||||||
|
} catch (Exception e) { |
||||||
|
this.error = true; |
||||||
|
this.setTitle("准备数据时出现异常"); |
||||||
|
this.clean(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getStepTotal() { |
||||||
|
return this.dataTotal; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDownloadPath() { |
||||||
|
return this.fileName; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void handleResult(ResultContext<? extends HashMap<String, Object>> context) { |
||||||
|
Map<String, Object> data = context.getResultObject(); |
||||||
|
// 遍历字段列名,获取对应数据并拼接成列的集合
|
||||||
|
List<String> cells = colNameList.stream().map(col -> { |
||||||
|
Object value = data.get(col); |
||||||
|
value = value == null ? "" : value; |
||||||
|
return String.valueOf(value); |
||||||
|
}).collect(Collectors.toList()); |
||||||
|
rowList.add(cells); |
||||||
|
this.autoAddStep(); |
||||||
|
} |
||||||
|
|
||||||
|
public void queryData(Consumer<Object> query) { |
||||||
|
this.queryFunc = query; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDataCount(int count) { |
||||||
|
this.dataTotal = count; |
||||||
|
} |
||||||
|
} |
Reference in new issue