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