贴一下
import com.alibaba.fastjson.JSON;
import com.paratera.lpbs.consts.Consts;
import com.paratera.lpbs.controller.BaseController;
import com.paratera.lpbs.entity.AsyncJobStatusEnum;
import com.paratera.lpbs.entity.vo.VoAsyncTask;
import com.paratera.lpbs.monitor.AsyncTaskManager;
import com.paratera.lpbs.service.ExportService;
import com.paratera.lpcomm.annotation.AuditLogRecord;
import com.paratera.lpcomm.annotation.LoginPass;
import com.paratera.lpcomm.consts.AuditModel;
import com.paratera.lpcomm.consts.AuditType;
import com.paratera.lpcomm.entity.BillingTypeEnum;
import com.paratera.lpcomm.entity.Error;
import com.paratera.lpcomm.entity.QueueType;
import com.paratera.lpcomm.utils.DateFomatUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.*;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.List;
import java.util.UUID;
import static com.paratera.lpbs.consts.Consts.JOB_LIST;
@RestController
@RequestMapping("/api/admin")
@Api(tags = "导出控制层(admin)", produces = "application/json", value = "导出接口", consumes = "application/json")
@ApiResponses(value = { @ApiResponse(code = 200, message = "successfully"),
@ApiResponse(code = 401, message = "You are not authorized to view the resource", response = Error.class),
@ApiResponse(code = 403, message = "Accessing the resource you were trying to reach is forbidden", response = Error.class),
@ApiResponse(code = 404, message = "The resource you were trying to reach is not found", response = Error.class),
@ApiResponse(code = 500, message = "error", response = Error.class) })
public class ExportAdminController extends BaseController {
@Autowired
private ExportService exportService;
@Autowired
private AsyncTaskManager asyncTaskManager;
@Autowired
public RedisTemplate<String, Object> redisTemplate;
@Value("${spring.config.billing.file-path-profile:disk/}")
private String filePathProfile;
@GetMapping("/billing/job/list/export")
@AuditLogRecord(content = "导出作业清单", type = AuditType.SCC_JOB_LIST_EXPORT, model = AuditModel.BILLING)
@ApiOperation(nickname = "jobListExport", value = "作业清单导出接口", httpMethod = "GET", produces = "application/json")
public VoAsyncTask export(@RequestParam(name = "searchUid", required = false) String searchUid,
@RequestParam(name = "searchRawJobId", required = false) String searchRawJobId,
@RequestParam(name = "billingType", required = false) BillingTypeEnum billingType,
@RequestParam(name = "queueType", required = false) QueueType queueType,
@RequestParam(name = "zoneClusterQueues", required = false) List<String> zoneClusterQueues,
@RequestParam(name = "softwares", required = false) List<String> softwares,
@RequestParam(name = "clusters", required = false) List<String> clusters,
@RequestParam(name = "intervalStartTimeStart") String intervalStartTimeStart,
@RequestParam(name = "intervalStartTimeEnd") String intervalStartTimeEnd,
@RequestParam(name = "page", required = false, defaultValue = "1") int page,
@RequestParam(name = "size", required = false, defaultValue = "100") int size,
@RequestParam(name = "order", required = false, defaultValue = "DESC") Sort.Direction order,
@RequestParam(name = "orderBy", required = false, defaultValue = "createdDate") String orderBy)
throws IOException {
initFilePathDisk(filePathProfile);
String filePath = filePathProfile + UUID.randomUUID() + ".csv";
String[] header = { "分区", "作业ID", "应用软件", "队列别名", "提交时间", "计费开始时间", "计费截止时间", "开始时间", "结束时间", "进程数量", "计费时长",
"作业时长", "作业空闲时长", "作业空闲时长占比", "核时/卡时", "计费模式", "排队时长", "排队原因", "超算账号", "用户账号" };
VoAsyncTask voAsyncTask = asyncTaskManager.initTask(filePath, intervalStartTimeStart, intervalStartTimeEnd);
exportService.asyncExport(voAsyncTask, filePath, header, searchUid, searchRawJobId, billingType, queueType,
zoneClusterQueues, softwares, clusters, intervalStartTimeStart, intervalStartTimeEnd, page, Consts.SIZE,
order, orderBy);
return voAsyncTask;
}
@GetMapping("/billing/job/list/export/progress")
@AuditLogRecord(content = "查询作业清单导出进度", type = AuditType.SCC_JOB_LIST_EXPORT, model = AuditModel.BILLING)
@ApiOperation(nickname = "jobListExport", value = "作业清单导出进度查询接口", httpMethod = "GET", produces = "application/json")
public VoAsyncTask getProgress(@RequestParam(name = "taskId") String taskId) {
String jsonString = (String) redisTemplate.opsForHash().get(JOB_LIST, taskId);
return JSON.parseObject(jsonString, VoAsyncTask.class);
}
@GetMapping("/billing/job/list/export/download")
@AuditLogRecord(content = "下载作业清单", type = AuditType.SCC_JOB_LIST_EXPORT, model = AuditModel.BILLING)
@ApiOperation(nickname = "jobListExport", value = "作业清单文件下载接口", httpMethod = "GET", produces = "text/comma-separated-values")
public void exportDownload(@RequestParam(name = "taskId") String taskId) throws IOException, ParseException {
String jsonString = (String) redisTemplate.opsForHash().get(JOB_LIST, taskId);
VoAsyncTask voAsyncTask = JSON.parseObject(jsonString, VoAsyncTask.class);
if(voAsyncTask.getStatus() == AsyncJobStatusEnum.ACTIVE && voAsyncTask.getProgress() == 100.00) {
String filePath = voAsyncTask.getFilePath();
File f = new File(filePath);
if (!f.exists()) {
return;
}
BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
byte[] buf = new byte[1024];
int len = 0;
String csvName = DateFomatUtils.getCsvName(voAsyncTask.getIntervalStartTimeStart(), voAsyncTask.getIntervalStartTimeEnd(), JOB_LIST);
String fileNameURL = URLEncoder.encode(csvName, "UTF-8");
resp.reset();
resp.setContentType("application/x-msdownload");
resp.setHeader("Content-Disposition", "attachment; filename=" + fileNameURL);
OutputStream out = resp.getOutputStream();
while ((len = br.read(buf)) > 0){
out.write(buf, 0, len);
}
br.close();
out.close();
}
}
private void initFilePathDisk(String path) {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
}
}
import com.alibaba.fastjson.JSON;
import com.paratera.lpbs.consts.Consts;
import com.paratera.lpbs.controller.admin.SccJobAdminController;
import com.paratera.lpbs.entity.AsyncJobStatusEnum;
import com.paratera.lpbs.entity.vo.VoAsyncTask;
import com.paratera.lpbs.entity.vo.VoBillSccJob;
import com.paratera.lpbs.utils.CsvWriterUtils;
import com.paratera.lpcomm.entity.BillingTypeEnum;
import com.paratera.lpcomm.entity.QueueType;
import com.paratera.lpcomm.vo.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.List;
import static com.paratera.lpbs.consts.Consts.JOB_LIST;
@Service
public class ExportService {
@Autowired
private SccJobAdminController sccJobAdminControlle;
@Autowired
public RedisTemplate<String, Object> redisTemplate;
@Async
public void asyncExport(VoAsyncTask voAsyncTask, String filePath, String[] header,
String searchUid, String searchRawJobId, BillingTypeEnum billingType, QueueType queueType,
List<String> zoneClusterQueues, List<String> softwares, List<String> clusters, String intervalStartTimeStart,
String intervalStartTimeEnd, int page, int size, Sort.Direction order, String orderBy) throws IOException {
File file = new File(filePath);
OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream(file), "gbk");
// 写header
Arrays.stream(header).forEach(it -> {
try {
ow.write(it);
ow.write(",");
} catch (IOException e) {
e.printStackTrace();
}
});
ow.write("\r\n");
Page<VoBillSccJob> voBillSccJobPage = sccJobAdminControlle.billList(searchUid, searchRawJobId, billingType, queueType,
zoneClusterQueues, softwares, clusters, intervalStartTimeStart, intervalStartTimeEnd, page, Consts.SIZE,
order, orderBy);
for (int i = 1; i <= voBillSccJobPage.getTotalPage(); i++) {
Page<VoBillSccJob> billSccJobPage = sccJobAdminControlle.billList(searchUid, searchRawJobId, billingType, queueType,
zoneClusterQueues, softwares, clusters, intervalStartTimeStart, intervalStartTimeEnd, i,
Consts.SIZE, order, orderBy);
// 写入本地磁盘
for (VoBillSccJob voBillSccJob : billSccJobPage.getData()) {
List<String> curRowList = CsvWriterUtils.jobListContent(voBillSccJob);
curRowList.forEach(it -> {
try {
ow.write(it);
ow.write(",");
} catch (IOException e) {
e.printStackTrace();
}
});
ow.write("\r\n");
}
// 记录导出进度
voAsyncTask.setProgress(((double) i)/voBillSccJobPage.getTotalPage()*100);
redisTemplate.opsForHash().put(JOB_LIST, voAsyncTask.getTaskId(), JSON.toJSONString(voAsyncTask));
}
voAsyncTask.setStatus(AsyncJobStatusEnum.ACTIVE);
redisTemplate.opsForHash().put(JOB_LIST, voAsyncTask.getTaskId(), JSON.toJSONString(voAsyncTask));
ow.flush();
ow.close();
}
}