|
|
@ -55,8 +55,6 @@ import java.nio.file.Path; |
|
|
|
import java.time.LocalDateTime; |
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.util.*; |
|
|
|
import java.util.concurrent.CompletableFuture; |
|
|
|
import java.util.concurrent.CountDownLatch; |
|
|
|
import java.util.concurrent.ExecutorService; |
|
|
|
import java.util.regex.Matcher; |
|
|
|
import java.util.regex.Pattern; |
|
|
@ -279,20 +277,29 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
|
|
|
|
// 查询报表的字段列表(含数据源列表)
|
|
|
|
JiMuResult<List<List<JimuReportFieldTreeResultDTO>>> fResult = jiMuReportOpenFeignClient.fieldTree(reportId); |
|
|
|
if (fResult == null || !fResult.isSuccess()) { |
|
|
|
throw new EpmetException(EpmetErrorCode.SERVER_ERROR.getCode(), "根据报表id未找到字段列表,报表ID:" + reportId, "根据报表id未找到字段列表,报表ID:" + reportId); |
|
|
|
} |
|
|
|
String datasourceId = fResult.getResult().get(0).get(0).getDbId(); |
|
|
|
|
|
|
|
// 报表数据源信息
|
|
|
|
JiMuResult<JimuReportDbDataResultDTO> dbData = jiMuReportOpenFeignClient.loadDbData(datasourceId); |
|
|
|
if (fResult == null || !fResult.isSuccess()) { |
|
|
|
throw new EpmetException(EpmetErrorCode.SERVER_ERROR.getCode(), "根据报表id未找到数据源,报表ID:" + reportId, "根据报表id未找到数据源,报表ID:" + reportId); |
|
|
|
} |
|
|
|
JimuReportDbDataResultDTO.ReportDB reportDb = dbData.getResult().getReportDb(); |
|
|
|
|
|
|
|
// 报表简要信息
|
|
|
|
JiMuResult<JiMuReportBriefResultDTO> reportBriefResult = jiMuReportOpenFeignClient.getReportBrief(reportId); |
|
|
|
if (fResult == null || !fResult.isSuccess()) { |
|
|
|
throw new EpmetException(EpmetErrorCode.SERVER_ERROR.getCode(), "根据报表id未找到报表信息,报表ID:" + reportId, "根据报表id未找到报表信息,报表ID:" + reportId); |
|
|
|
} |
|
|
|
JiMuReportBriefResultDTO reportBrief = reportBriefResult.getResult(); |
|
|
|
|
|
|
|
// api的url
|
|
|
|
String apiUrl = reportDb.getApiUrl(); |
|
|
|
// api方法
|
|
|
|
//String apiMethod = reportDb.getApiMethod();
|
|
|
|
String apiMethod = reportDb.getApiMethod(); |
|
|
|
// 是否是集合
|
|
|
|
//String isList = reportDb.getIsList();
|
|
|
|
// 返回的列表中,哪个字段是ID
|
|
|
@ -318,13 +325,13 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
} |
|
|
|
|
|
|
|
// 2. 调用该url的接口,获取到一个列表,根据idFieldName取出ID列
|
|
|
|
HashMap<String, String> idAndNames = listBizObjectIdAndName(bizId, paramKey, apiUrl, isHttps, idFieldName, nameFieldName); |
|
|
|
HashMap<String, String> idAndNames = listBizObjectIdAndName(bizId, paramKey, apiUrl, isHttps, idFieldName, nameFieldName, apiMethod); |
|
|
|
|
|
|
|
// 3. 然后以这一列作为查询条件,循环,继续调用该接口,得到单条数据,每一条数据都下载一个excel,最后将其打包为一个压缩包下载
|
|
|
|
Path storePath = makeTemporaryDownloadDir(reportId); |
|
|
|
|
|
|
|
// 4.生成压缩文件
|
|
|
|
Path zipFile = downloadAndComppress(storePath, reportId, reportBrief.getName(), paramKey, idAndNames); |
|
|
|
Path zipFile = downloadAndCompress(storePath, reportId, reportBrief.getName(), paramKey, idAndNames); |
|
|
|
|
|
|
|
// 5.下载
|
|
|
|
try (FileInputStream fis = new FileInputStream(zipFile.toFile())) { |
|
|
@ -350,7 +357,7 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
* @param storePath 本次导出文件的存储路径,子目录包括:zip文件,时间戳命名的子目录用于存放临时excel(导出完成会删掉) |
|
|
|
* @return 压缩文件路径 |
|
|
|
*/ |
|
|
|
private Path downloadAndComppress(Path storePath, String reportId, String reportName, String paramKey, HashMap<String, String> idAndNames) { |
|
|
|
private Path downloadAndCompress(Path storePath, String reportId, String reportName, String paramKey, HashMap<String, String> idAndNames) { |
|
|
|
// 请求头
|
|
|
|
Map<String, Object> headers = new HashMap<>(); |
|
|
|
headers.put(Constant.AUTHORIZATION_HEADER, EpmetRequestHolder.getHeader(Constant.AUTHORIZATION_HEADER)); |
|
|
@ -382,21 +389,22 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
idList.addAll(idAndNames.keySet()); |
|
|
|
List<List<String>> idParts = ListUtils.partition(idList, 100); |
|
|
|
|
|
|
|
// 1. 循环下载所有id对应的excel
|
|
|
|
CountDownLatch cdl = new CountDownLatch(idParts.size()); |
|
|
|
// 1. 循环下载所有id对应的excel(积木报表的导出接口有并发问题,多线程会导出空表,暂时不用多线程了)
|
|
|
|
//CountDownLatch cdl = new CountDownLatch(idParts.size());
|
|
|
|
for (List<String> idPart : idParts) { |
|
|
|
CompletableFuture.runAsync(() -> { |
|
|
|
downloadXlsByBatchByBizId(reportId, idPart, idAndNames, param, xlsxStorePath, files, cdl); |
|
|
|
}, executorService); |
|
|
|
downloadXlsByBatchByBizId(reportId, idPart, idAndNames, param, xlsxStorePath, files); |
|
|
|
//CompletableFuture.runAsync(() -> {
|
|
|
|
// downloadXlsByBatchByBizId(reportId, idPart, idAndNames, param, xlsxStorePath, files, cdl);
|
|
|
|
//}, executorService);
|
|
|
|
} |
|
|
|
|
|
|
|
// 等待多线程执行完成,再执行打包
|
|
|
|
try { |
|
|
|
cdl.await(); |
|
|
|
} catch (InterruptedException e) { |
|
|
|
log.error(ExceptionUtils.getErrorStackTrace(e)); |
|
|
|
throw new EpmetException("【报表批量导出】CountDownLatch等待被中断"); |
|
|
|
} |
|
|
|
//try {
|
|
|
|
// cdl.await();
|
|
|
|
//} catch (InterruptedException e) {
|
|
|
|
// log.error(ExceptionUtils.getErrorStackTrace(e));
|
|
|
|
// throw new EpmetException("【报表批量导出】CountDownLatch等待被中断");
|
|
|
|
//}
|
|
|
|
|
|
|
|
// 2,打包
|
|
|
|
Path zipFile = storePath.resolve(reportName + "_" + currentTimeStr + ".zip"); |
|
|
@ -409,11 +417,9 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
String bizObjectId = entry.getKey(); |
|
|
|
File file = entry.getValue(); |
|
|
|
|
|
|
|
String bizObjName = idAndNames.get(bizObjectId); |
|
|
|
String bizObjName = getNumberedObjName(bizObjNameAndCount, idAndNames.get(bizObjectId)); |
|
|
|
|
|
|
|
bizObjName = getBizObjName(bizObjNameAndCount, bizObjName); |
|
|
|
|
|
|
|
try (final FileInputStream fis = new FileInputStream(file.getAbsolutePath())) { |
|
|
|
try (FileInputStream fis = new FileInputStream(file.getAbsolutePath())) { |
|
|
|
zos.putNextEntry(new ZipEntry(String.format("%s_%s/%s_%s.xlsx", reportName, currentTimeStr, reportName, bizObjName))); |
|
|
|
final byte[] buffer = new byte[10240]; |
|
|
|
for (int len; (len = fis.read(buffer)) > 0; ) { |
|
|
@ -436,7 +442,13 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
return zipFile; |
|
|
|
} |
|
|
|
|
|
|
|
public String getBizObjName(HashMap<String, Integer> bizObjNameAndCount, String bizObjName) { |
|
|
|
/** |
|
|
|
* 为业务对象名称编号,解决重名对象问题 |
|
|
|
* @param bizObjNameAndCount 业务对象名称/出现次数map |
|
|
|
* @param bizObjName 原始业务对象名 |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public String getNumberedObjName(HashMap<String, Integer> bizObjNameAndCount, String bizObjName) { |
|
|
|
Integer nameCount = bizObjNameAndCount.get(bizObjName); |
|
|
|
if (nameCount == null) { |
|
|
|
nameCount = 1; |
|
|
@ -460,8 +472,7 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
* @param xlsxStorePath |
|
|
|
* @param files |
|
|
|
*/ |
|
|
|
public void downloadXlsByBatchByBizId(String reportId, List<String> bizIds, Map<String, String> idAndNames, JimuReportExportRequestDTO param, Path xlsxStorePath, Map<String, File> files, |
|
|
|
CountDownLatch cdl) { |
|
|
|
public void downloadXlsByBatchByBizId(String reportId, List<String> bizIds, Map<String, String> idAndNames, JimuReportExportRequestDTO param, Path xlsxStorePath, Map<String, File> files) { |
|
|
|
for (String id : bizIds) { |
|
|
|
|
|
|
|
try { |
|
|
@ -495,7 +506,7 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
cdl.countDown(); |
|
|
|
//cdl.countDown();
|
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -538,25 +549,32 @@ public class IcCustomerReportServiceImpl extends BaseServiceImpl<IcCustomerRepor |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 列出id列表,批量下载用 |
|
|
|
* 列出id和name列表(生成文件用到了name),批量下载用 |
|
|
|
* |
|
|
|
* @param apiUrl |
|
|
|
* @param isHttps |
|
|
|
* @param idFieldName |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public HashMap<String, String> listBizObjectIdAndName(String id, String paramKey, String apiUrl, boolean isHttps, String idFieldName, String nameFieldName) { |
|
|
|
public HashMap<String, String> listBizObjectIdAndName(String id, String paramKey, String apiUrl, boolean isHttps, String idFieldName, String nameFieldName, String apiMethod) { |
|
|
|
apiUrl = apiUrl.replace("'${id}'", id == null ? "" : id); |
|
|
|
apiUrl = apiUrl.replace("'${paramKey}'", paramKey); |
|
|
|
|
|
|
|
Map<String, Object> headers = new HashMap<>(); |
|
|
|
headers.put(Constant.AUTHORIZATION_HEADER, EpmetRequestHolder.getHeader(Constant.AUTHORIZATION_HEADER)); |
|
|
|
Result<String> stringResult = HttpClientManager.getInstance().sendPost(apiUrl, isHttps, "{\"id\":" + id + "}", headers); |
|
|
|
|
|
|
|
Result<String> stringResult; |
|
|
|
// 请求方法0-get,1-post
|
|
|
|
if (NumConstant.ONE_STR.equals(apiMethod)) { |
|
|
|
stringResult = HttpClientManager.getInstance().sendPost(apiUrl, isHttps, "{\"id\":\"" + (id == null ? "" : id) + "\"}", headers); |
|
|
|
} else { |
|
|
|
stringResult = HttpClientManager.getInstance().sendGet(apiUrl, isHttps, null, headers); |
|
|
|
} |
|
|
|
|
|
|
|
JSONObject dataJsonObject = JSON.parseObject(stringResult.getData()); |
|
|
|
Object data = dataJsonObject.get("data"); |
|
|
|
|
|
|
|
JSONArray array = new JSONArray(); |
|
|
|
JSONArray array; |
|
|
|
HashMap<String, String> idAndNames = new HashMap<>(); |
|
|
|
|
|
|
|
if (data instanceof JSONObject) { |
|
|
|