commit
e6a5ed9b4f
@ -0,0 +1,65 @@ |
|||||||
|
package com.keyware.shandan.bianmu.controller; |
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil; |
||||||
|
import com.keyware.shandan.bianmu.export.ExportCache; |
||||||
|
import com.keyware.shandan.bianmu.export.ExportProgress; |
||||||
|
import com.keyware.shandan.bianmu.service.MetadataService; |
||||||
|
import com.keyware.shandan.common.entity.Result; |
||||||
|
import com.keyware.shandan.common.util.FileDownload; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.security.core.Authentication; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
/** |
||||||
|
* 组合搜索前端控制器 |
||||||
|
* |
||||||
|
* @author Administrator |
||||||
|
* @since 2021/7/1 |
||||||
|
*/ |
||||||
|
@RestController |
||||||
|
@RequestMapping("/search") |
||||||
|
public class SearchController { |
||||||
|
@Autowired |
||||||
|
private MetadataService metadataService; |
||||||
|
/** |
||||||
|
* 目录数据导出-查询任务状态 |
||||||
|
* |
||||||
|
* @param exportId 导出ID |
||||||
|
* @return 导出ID |
||||||
|
*/ |
||||||
|
@GetMapping("/export/status/{exportId}") |
||||||
|
public Result<Object> exportStatus(@PathVariable String exportId, Authentication auth) { |
||||||
|
String userId = auth.getPrincipal().toString(); |
||||||
|
ExportProgress export = ExportCache.getCache(userId, exportId); |
||||||
|
if (export == null) { |
||||||
|
return Result.of(null, false, "导出任务不存在"); |
||||||
|
} |
||||||
|
if (export.isError()) { |
||||||
|
ExportCache.popCache(userId, exportId); |
||||||
|
} |
||||||
|
return Result.of(export.getProgress(), !export.isError()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 目录数据导出-下载 |
||||||
|
* |
||||||
|
* @param response HttpServletResponse |
||||||
|
* @param exportId 导出ID |
||||||
|
* @return - |
||||||
|
*/ |
||||||
|
@GetMapping("/export/download/{exportId}") |
||||||
|
public String exportDownload(HttpServletResponse response, @PathVariable String exportId, Authentication auth) { |
||||||
|
String userId = auth.getPrincipal().toString(); |
||||||
|
ExportProgress export = ExportCache.popCache(userId, exportId); |
||||||
|
if (export == null) { |
||||||
|
return "错误:导出任务不存在"; |
||||||
|
} |
||||||
|
String path = export.getDownloadPath(); |
||||||
|
String downloadName = FileUtil.getName(path); |
||||||
|
File file = new File(path); |
||||||
|
return FileDownload.download(response, file, downloadName, true); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
package com.keyware.shandan.common.service; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author YaoJz |
||||||
|
* @description |
||||||
|
* @date 2024/4/16 15:28 |
||||||
|
*/ |
||||||
|
public class ExportServiceImpl implements IExportService{ |
||||||
|
|
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
package com.keyware.shandan.common.service; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author YaoJz |
||||||
|
* @description |
||||||
|
* @date 2024/4/16 15:27 |
||||||
|
*/ |
||||||
|
public interface IExportService { |
||||||
|
} |
@ -0,0 +1,191 @@ |
|||||||
|
package com.keyware.shandan.bianmu.export; |
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil; |
||||||
|
import cn.hutool.core.date.DateUtil; |
||||||
|
import cn.hutool.core.io.FileUtil; |
||||||
|
import cn.hutool.core.util.ZipUtil; |
||||||
|
import cn.hutool.http.HttpUtil; |
||||||
|
import cn.hutool.poi.excel.BigExcelWriter; |
||||||
|
import cn.hutool.poi.excel.ExcelUtil; |
||||||
|
import com.alibaba.fastjson.JSONArray; |
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.keyware.shandan.bianmu.entity.DirectoryResource; |
||||||
|
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 com.keyware.shandan.system.entity.SysFile; |
||||||
|
import com.keyware.shandan.system.service.SysFileService; |
||||||
|
import com.keyware.shandan.system.utils.SysSettingUtil; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author YaoJz |
||||||
|
* @description |
||||||
|
* @date 2024/4/15 16:40 |
||||||
|
*/ |
||||||
|
public class FileSearchExport extends ExportProgress { |
||||||
|
private final List<DirectoryResource> dataList; |
||||||
|
private final SysFileService fileService; |
||||||
|
private final MetadataService metadataService; |
||||||
|
private final String outputDir = "目录导出_" + DateUtil.format(new Date(), "yyyyMMddHHmmss"); |
||||||
|
private final String outputPath = tempDir + File.separator + outputDir; |
||||||
|
private final String zipName = outputPath + ".zip"; |
||||||
|
|
||||||
|
public FileSearchExport(String userId, List<DirectoryResource> dataList) { |
||||||
|
super(userId); |
||||||
|
this.dataList = dataList; |
||||||
|
this.fileService = AppContext.getContext().getBean(SysFileService.class); |
||||||
|
this.metadataService = AppContext.getContext().getBean(MetadataService.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
try { |
||||||
|
this.setTitle("正在生成临时数据文件"); |
||||||
|
dataList.forEach(resource -> { |
||||||
|
if ("file".equals(resource.getResourceType())) { |
||||||
|
exportFile(resource); |
||||||
|
} else { |
||||||
|
exportMetadata(resource); |
||||||
|
} |
||||||
|
this.autoAddStep(); |
||||||
|
}); |
||||||
|
this.setTitle("正在打包数据文件"); |
||||||
|
ZipUtil.zip(outputPath, zipName, true); |
||||||
|
this.autoAddStep(); |
||||||
|
this.setDone(); |
||||||
|
this.setTitle("数据包准备完毕,开始下载"); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new RuntimeException("导出数据在打包时出错", e); |
||||||
|
} finally { |
||||||
|
delete(outputPath); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 导出文件 |
||||||
|
* |
||||||
|
* @param resource 数据资源 |
||||||
|
*/ |
||||||
|
private void exportFile(DirectoryResource resource) { |
||||||
|
File serverFile = new File(createResourceDir(resource.getDirectoryPath())); |
||||||
|
SysFile file = fileService.getById(resource.getId()); |
||||||
|
String fileDownloadUrl = SysSettingUtil.getSysSetting("BIANMU").getSysInternalAddress() + file.getWebUri(); |
||||||
|
try { |
||||||
|
HttpUtil.downloadFile(fileDownloadUrl, serverFile); |
||||||
|
} catch (Exception e) { |
||||||
|
List<String> lines = new ArrayList<>(); |
||||||
|
String dirPath = serverFile.getParentFile().getPath(); |
||||||
|
String name = "(文件读取错误)" + serverFile.getName(); |
||||||
|
FileUtil.writeLines(lines, new File(dirPath, name), "utf-8"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 导出数据表 |
||||||
|
* |
||||||
|
* @param resource 数据资源 |
||||||
|
*/ |
||||||
|
private void exportMetadata(DirectoryResource resource) { |
||||||
|
File serverFile = new File(createResourceDir(resource.getDirectoryPath())); |
||||||
|
String path = serverFile.getPath() + ".xlsx"; |
||||||
|
MetadataBasicVo metadata = null; |
||||||
|
JSONArray colsArray = null; |
||||||
|
List<Map<String, Object>> datas = null; |
||||||
|
|
||||||
|
try { |
||||||
|
metadata = metadataService.getById(resource.getId()); |
||||||
|
colsArray = metadataService.getColumns(metadata.getId()); |
||||||
|
datas = metadataService.getDynamicData(metadata); |
||||||
|
} catch (Exception e) { |
||||||
|
colsArray = new JSONArray(); |
||||||
|
JSONObject defaultJson = new JSONObject(); |
||||||
|
defaultJson.put("comment", "数据查询失败,无法连接到指定的数据库"); |
||||||
|
colsArray.add(defaultJson); |
||||||
|
datas = new ArrayList<>(); |
||||||
|
|
||||||
|
File temp = new File(path); |
||||||
|
String dirPath = temp.getParentFile().getPath(); |
||||||
|
path = dirPath + File.separator + "(数据读取错误)" + temp.getName(); |
||||||
|
} |
||||||
|
|
||||||
|
// 所有行的集合
|
||||||
|
List<List<String>> rowList = new ArrayList<>(); |
||||||
|
// 字段列名集合
|
||||||
|
List<String> colNameList = new ArrayList<>(); |
||||||
|
// 字段列名注释集合,当做表格的第一行
|
||||||
|
List<String> columns = StreamUtil.as(colsArray).map(json -> { |
||||||
|
JSONObject col = (JSONObject) json; |
||||||
|
String comment = col.getString("comment"); |
||||||
|
String colName = col.getString("columnName"); |
||||||
|
colNameList.add(colName); |
||||||
|
return colName + (StringUtils.hasText(comment) ? "[" + comment + "]" : ""); |
||||||
|
}).toList(); |
||||||
|
|
||||||
|
// 添加第一行
|
||||||
|
rowList.add(columns); |
||||||
|
|
||||||
|
// 遍历数据
|
||||||
|
datas.forEach(data -> { |
||||||
|
// 遍历字段列名,获取对应数据并拼接成列的集合
|
||||||
|
List<String> cells = colNameList.stream().map(col -> { |
||||||
|
Object value = data.get(col); |
||||||
|
if (value == null) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
return String.valueOf(value); |
||||||
|
}).collect(Collectors.toList()); |
||||||
|
rowList.add(cells); |
||||||
|
}); |
||||||
|
|
||||||
|
List<List<String>> rows = CollUtil.newArrayList(rowList); |
||||||
|
//通过工具类创建writer
|
||||||
|
BigExcelWriter writer = ExcelUtil.getBigWriter(path); |
||||||
|
//一次性写出内容
|
||||||
|
writer.write(rows); |
||||||
|
//关闭writer,释放内存
|
||||||
|
writer.close(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据资源路径创建目录 |
||||||
|
* |
||||||
|
* @param resourcePath 资源路径 |
||||||
|
* @return 资源的的绝对路径 |
||||||
|
*/ |
||||||
|
private String createResourceDir(String resourcePath) { |
||||||
|
String path = outputPath + File.separator + resourcePath; |
||||||
|
File file = new File(path); |
||||||
|
File parent = file.getParentFile(); |
||||||
|
if (!parent.exists()) { |
||||||
|
parent.mkdirs(); |
||||||
|
} |
||||||
|
return path; |
||||||
|
} |
||||||
|
|
||||||
|
private void delete(String path) { |
||||||
|
File file = new File(path); |
||||||
|
if (file.exists()) { |
||||||
|
FileUtil.del(file); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getStepTotal() { |
||||||
|
return dataList.size() + 1; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDownloadPath() { |
||||||
|
return zipName; |
||||||
|
} |
||||||
|
|
||||||
|
} |
Reference in new issue