相对路径: String mdbDirPath = "./" + "taskPackage"; (当前工程目录同级)
拼路径: String path = mdbDirPath + "\\" + "1报送通知1.mdb";
获取文件流:InputStream inputStream = new FileInputStream(annexFile);
Java压缩zip
/**
* 下载压缩包
*
* @param instId 实例id
* @param response 响应
* @author 梁伟浩
* @date 2023-08-21
*/
@GetMapping("/downloadZip")
@ApiOperation(value = "下载压缩包")
@ApiImplicitParam(name = "instId", value = "实例id", required = true, paramType = "query", dataTypeClass = String.class)
public void downloadZip(@RequestParam("instId") String instId, HttpServletResponse response) {
Asserts.isEmpty(instId, "实例id[instId]不能为空");
InputStream inputStream = null;
OutputStream outputStream = null;
try {
businessContentService.zipAttachTree(instId,response);
outputStream.flush();
} catch (Exception e) {
response.setStatus(SC_BAD_REQUEST);
try {
if (outputStream != null) {
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "application/json;charset=utf-8");
outputStream.write(JSON.toJSONString(R.fail(e.getMessage())).getBytes());
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
@Override
public void zipAttachTree(String instId, HttpServletResponse response) {
InstBusinessInfo instBusinessInfo = instBusinessInfoMapper.selectById(instId);
String instTitle = instBusinessInfo.getInstTitle();
if (instBusinessInfo == null) {
throw new BusinessException(instId);
}
//获取附件树目录
BusinessContentRequest instanceContentRequest = new BusinessContentRequest();
BusinessContentResponse contentResponse = null;
instanceContentRequest.setInstId(instId);
instanceContentRequest.setGroupEnum(BusinessContentGroupEnum.DIR_TREE);
try {
contentResponse = this.getBusinessContent(instanceContentRequest);
} catch (Exception e) {
e.printStackTrace();
}
List<BusinessContentVO> contentVOList = contentResponse.getContentVOList();
File directory = new File("./" + instTitle);
directory.mkdir();
//递归创建文件夹并把文件流放进对应文件夹
this.getFileName(contentVOList, new StringBuilder(), instTitle);
File file = new File("./" + instTitle);
File zipFile = null;
List<File> souceFileList = new ArrayList();
try {
souceFileList.add(file);
zipFile = new File(instTitle + ".zip");
ZipUtil.toZip(zipFile.getName(), souceFileList);
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(zipFile));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFile.getName(), "UTF-8"));
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
//删除本地生成的文件夹与zip压缩包
if (file!=null && file.exists()){
FileUtil.del(file);
}
if (zipFile != null && zipFile.exists()) {
zipFile.delete();
}
}
}
//递归生成文件夹并把流写到对应文件夹
public void getFileName(List<BusinessContentVO> contentVOList, StringBuilder sb, String instTitle) {
List<StringBuilder> fileNames = new ArrayList<>();
for (BusinessContentVO contentVO : contentVOList) {
OutputStream outputStream = null;
StringBuilder newSb = new StringBuilder(sb); // 创建新的 StringBuilder 对象
if (Func.isEmpty(contentVO.getDataId())) {
File directory = new File("./" + instTitle + "/" + contentVO.getNodeName());
directory.mkdir();
newSb.append(contentVO.getNodeName() + "/");
} else {
String dataId = contentVO.getDataId();
InstFileInfo instFileInfo = instFileInfoMapper.selectById(dataId);
InputStream inputStream = minioTemplate.getObject(instFileInfo.getFilePath());
String fileName = "./" + instTitle + "/" + sb + "/" + contentVO.getNodeName() + "";
File outputFile = new File(fileName);
try {
//把文件夹创建成输出文件
outputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[1024];
int length;
//把文件写到对应的文件夹中
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
List<BusinessContentVO> childrenList = contentVO.getChildren();
if (childrenList != null) {
getFileName(childrenList, newSb, instTitle); // 递归调用时使用新的 StringBuilder 对象
}
}
}
将流写到文件中
MultipartFile file
InputStream is = file.getInputStream();
ZipInputStream zipInputStream = new ZipInputStream(is, Charset.forName("UTF-8"));
File jsonFile = new File("./pre/" + zipEntryNameStr);
this.writeFile(jsonFile.getAbsolutePath(), zipInputStream);
/**
* @描述 将流写到文件中
* @作者 吕嘉伟
* @日期 2023/3/30 17:49
*/
public void writeFile(String filePath, ZipInputStream zipInputStream) {
try (OutputStream outputStream = new FileOutputStream(filePath)) {
byte[] bytes = new byte[4096];
int len;
while ((len = zipInputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
} catch (IOException ex) {
System.out.println("解压文件时,写出到文件出错");
}
}
解析导入的zip压缩包
/**
* @param file
* @description: 导入任务包, 更新ss_rwb任务表
* @author: 梁伟浩
* @date: 2023/10/20 17:08
*/
@Override
public Object importTaskPackage(MultipartFile file) {
// 压缩包文件
File zipFile = UnZipUtil.getFile(file);
//mdb文件路径
String path = null;
// 压缩包解压到指定位置
if (StringUtils.isBlank(taskPackagePath)) {
throw new BusinessException("unzip.path.taskPackage 挂载目录路径未配置!");
}
String id = String.valueOf(IdUtil.getId());
String mdbDirPath = taskPackagePath + id;
File unzipFile = new File(mdbDirPath);
if (!unzipFile.exists()) {
unzipFile.mkdirs();
}
try {
//解压zip文件到指定路径文件夹
UnZipUtil.unzipFile(zipFile.getPath(), mdbDirPath);
// 读取压缩包的内容集合
List<UnzipFileVo> unzipList = UnZipUtil.unzip(zipFile);
//解析任务包,判断格式是否正常
boolean format = false;
boolean formatTwo = false;
for (UnzipFileVo unzipFileVo : unzipList) {
if ("2附件".equals(unzipFileVo.getName())) {
format = true;
} else {
if ("1报送通知.mdb".equals(unzipFileVo.getName())) {
formatTwo = true;
}
}
}
if (!(format && formatTwo)) {
throw new BusinessException("上传的任务包格式有误,请检查任务包!");
}
//解析附件,上传到minio获取到返回路径,存到ss_rwb数据表
// String annexPath = mdbDirPath + "\\" + "2附件";
String annexPath = mdbDirPath;
File folder = new File(annexPath);
File[] files = folder.listFiles();
//附件数据
List<FromFileUploadResponse> annexDatas = new ArrayList<>();
if (files != null) {
for (File annexFile : files) {
if (annexFile.isFile() && !"mdb".equals(FileUtil.getSuffix(annexFile.getName())) && !"json".equals(FileUtil.getSuffix(annexFile.getName()))) {
System.out.println(annexFile.getName());
//附件上传到minio服务器
String objectName = "taskPackage/" + cn.hutool.core.date.DateUtil.year(new Timestamp(System.currentTimeMillis())) + "/" + IdUtil.getId() + "."
+ FileUtil.getSuffix(annexFile.getName());
//上传文件到minio,返回绝对路径
InputStream inputStream = new FileInputStream(annexFile);
String paths = fileService.putObject(objectName, inputStream);
inputStream.close();
InstFileInfo fileInfo = new InstFileInfo();
fileInfo.setFileName(annexFile.getName());
fileInfo.setFileSize(annexFile.length());
fileInfo.setExtension(FileUtil.getSuffix(annexFile.getName()));
fileInfo.setStatus(1);
//加上存储桶
fileInfo.setFilePath("bpm/" + objectName);
instFileInfoMapper.insert(fileInfo);
FromFileUploadResponse response = new FromFileUploadResponse();
response.setFileSize(file.getSize());
BeanUtils.copyProperties(fileInfo, response);
annexDatas.add(response);
//获取存储相对路径
String formatLink = fileService.formatLink(paths);
}
}
}
//解析mdb文件插入数据
path = mdbDirPath + "\\" + "1报送通知.mdb";
this.insertRMBData(path, annexDatas);
} catch (IOException e) {
throw new BusinessException("解析任务包出错!");
} finally {
//删除本地生成的文件夹与zip压缩包
if (unzipFile != null && unzipFile.exists()) {
UnZipUtil.deleteFile(unzipFile);
}
zipFile.delete();
}
return null;
}
public void insertRMBData(String path, List<FromFileUploadResponse> annexDatas) {
Connection connection = AccessUtil.getAccessConnection(path, "", "");
try {
List<Map<String, Object>> rwbMapList = AccessUtil.select(connection, "XM_SJBSTZB");
for (Map<String, Object> map : rwbMapList) {
// 将Map对象转换为JSON字符串
String jsonString = JSONObject.toJSONString(map);
// 使用FastJSON的JSONObject类创建一个新的JSON对象
JSONObject jsonObject = JSONObject.parseObject(jsonString);
// 将JSON对象转换为SsRwb对象
SsRwb ssRwb = jsonObject.toJavaObject(SsRwb.class);
UUID uuid = UUID.randomUUID();
String uuidString = uuid.toString();
ssRwb.setId(uuidString);
ssRwb.setCjrXm(jsonObject.get("CJR").toString());
ssRwb.setCjSj(new Date());
if (annexDatas.size() > 0) {
//把附件数据转json数组
Gson gson = new Gson();
String annexJson = gson.toJson(annexDatas);
ssRwb.setFj(annexJson);
}
ssRwbMapper.insert(ssRwb);
}
} catch (Exception e) {
throw new BusinessException("任务包解析数据插入任务表报错!");
} finally {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
下载文件响应
public void tableExport(@RequestParam("file") MultipartFile file, HttpServletResponse response) {
OutputStream outputStream = null;
try {
//数据表名称
String fileName = "数据表" + ".docx";
response.reset();
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ";filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));
outputStream = response.getOutputStream();
formService.tableExport(file, outputStream);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
try {
if (outputStream != null) {
outputStream.write(JSON.toJSONString(R.fail(e.getMessage())).getBytes());
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
throw new RuntimeException();
}
}
}
if (fileDataMap.containsKey("toInputStream")) {
InputStream toInputStream = (InputStream)fileDataMap.get("toInputStream");
// 创建缓冲区和输出流
byte[] buffer = new byte[1024];
int bytesRead;
// 将输入流数据写入输出流
while ((bytesRead = toInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
批量下载文件压缩成zip格式
/**
* 批量下载文件
*
* @param ids 主键id
* @作者 梁伟浩
* @日期 2024-04-22 14:47 星期一
*/
@GetMapping("/downloadZip")
@ApiOperation(value = "批量下载文件")
@ApiImplicitParam(name = "ids", value = "主键id,多个值英文,隔开", required = true, paramType = "query", dataTypeClass = String.class)
public void downloadZip(@RequestParam("ids") String ids, HttpServletResponse response) {
OutputStream outputStream = null;
try {
biMaterialService.zipAttach(ids,response);
outputStream.flush();
} catch (Exception e) {
response.setStatus(SC_BAD_REQUEST);
try {
if (outputStream != null) {
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "application/json;charset=utf-8");
outputStream.write(JSON.toJSONString(R.fail(e.getMessage())).getBytes());
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
/**
* 批量下载文件
*
* @param ids 主键id
* @param response
* @作者 梁伟浩
* @日期 2024-04-22 15:07 星期一
*/
@Override
public void zipAttach(String ids, HttpServletResponse response) {
List<Long> idList = Func.toLongList(ids);
// 获取对应素材类型作为压缩包名字
Integer type = this.getById(idList.get(0)).getType();
String name = MaterialTypeEnum.getName(type);
// 创建临时目录用于存放文件和压缩包
File tempDir = new File(System.getProperty("java.io.tmpdir"), "attachments");
if (!tempDir.exists()) {
tempDir.mkdirs();
}
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(Paths.get(tempDir.getPath() + File.separator + "attachments.zip")))) {
for (Long id : idList) {
// 文件访问路径
String objectName = this.getById(id).getStorePath();
if (objectName.contains("/minio/")) {
// 找到第一个出现 "/minio/" 的位置
int startIndex = objectName.indexOf("/minio/") + "/minio/".length();
objectName = objectName.substring(startIndex);
}
InputStream inputStream = minIoUtil.getObject(objectName);
// 生成临时文件名
String tempFileName = objectName.substring(objectName.lastIndexOf("/") + 1);
File tempFile = new File(tempDir.getPath() + File.separator + tempFileName);
// 将 InputStream 写入临时文件
try (OutputStream outputStream = Files.newOutputStream(tempFile.toPath())) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
}
// 添加临时文件到 zip 压缩包
zipOut.putNextEntry(new ZipEntry(tempFileName));
try (FileInputStream fileInputStream = new FileInputStream(tempFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = fileInputStream.read(buffer)) > 0) {
zipOut.write(buffer, 0, length);
}
}
// 关闭输入流并删除临时文件
inputStream.close();
tempFile.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
// 提供下载
try (FileInputStream fileInputStream = new FileInputStream(tempDir.getPath() + File.separator + "attachments.zip")) {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(name + ".zip", "UTF-8") + "\"");
OutputStream outputStream = response.getOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = fileInputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
// 删除临时文件和压缩包
this.deleteDir(tempDir);
}
/**
* 递归删除目录及其子目录和文件
*
* @param dir 目录
* @作者 梁伟浩
* @日期 2024-04-23 10:23 星期二
*/
private void deleteDir(File dir) {
if (dir.isDirectory()) {
File[] children = dir.listFiles();
if (children != null) {
for (File child : children) {
deleteDir(child);
}
}
}
dir.delete();
}
文件访问路径
#导出源码地址
sourceCode:
sourceCodeUrl: /data/project/template Linux
sourceCodeUrl2: D:\GDIdeaWorkBi\template windows
根据服务的文件,压缩导出源代码
- controller层
/**
* 导出源代码
*
* @param files 文件流对象
* @作者 梁伟浩
* @日期 2024-04-29 10:25 星期一
*/
@PostMapping("/downloadCode")
@ApiOperation(value = "导出源代码")
@ApiOperationSupport(order = 19)
@ApiImplicitParams({
@ApiImplicitParam(name = "files", value = "需要上传的文件流对象", paramType = "query", dataType = "MultipartFile", required = true),
@ApiImplicitParam(name = "pagePath", value = "页面文件储存路径", paramType = "query", dataType = "String", required = true),
@ApiImplicitParam(name = "routePath", value = "路由文件储存路径", paramType = "query", dataType = "String", required = true),
@ApiImplicitParam(name = "fileIds", value = "文件ID,多个值英文,隔开", paramType = "query", dataType = "String", required = true),
})
public void downloadCode(MultipartFile[] files, String pagePath, String routePath, String fileIds,HttpServletResponse response){
OutputStream outputStream = null;
try {
iProjectService.downloadCode(files,pagePath,routePath,fileIds,response);
outputStream.flush();
} catch (Exception e) {
response.setStatus(SC_BAD_REQUEST);
try {
if (outputStream != null) {
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "application/json;charset=utf-8");
outputStream.write(JSON.toJSONString(R.fail(e.getMessage())).getBytes());
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
- service接口层
/**
* 导出源代码
*
* @param files 需要上传的文件流对象
* @param pagePath 页面文件储存路径
* @param routePath 路由文件储存路径
* @param fileIds 文件ID
* @作者 梁伟浩
* @日期 2024-04-29 10:50 星期一
*/
void downloadCode(MultipartFile[] files,String pagePath,String routePath, String fileIds, HttpServletResponse response);
- service实现层
@Value("${sourceCode.sourceCodeUrl}")
private String sourceCodeUrl;
@Value("${sourceCode.fileIdUrl}")
private String filePath;
/**
* 导出源代码
*
* @param files 需要上传的文件流对象
* @param pagePath 页面文件流存储路径
* @param routePath 路由文件流存储路径
* @param fileIds 文件ID
* @作者 梁伟浩
* @日期 2024-05-06 17:36 星期一
*/
@Override
public void downloadCode(MultipartFile[] files, String pagePath, String routePath, String fileIds, HttpServletResponse response) {
//整个前端工程目录
File oFile = new File(sourceCodeUrl);
//本地测试路径
// String filePath = "D:\\GDIdeaWorkBi\\template\\src\\views\\exportDemo\\assets";
// 创建路由目录
File routDirectory = new File(routePath);
if (!routDirectory.exists()) {
routDirectory.mkdirs();
}
// 创建页面目录
File pageDirectory = new File(pagePath);
if (!pageDirectory.exists()) {
pageDirectory.mkdirs();
}
// 创建静态文件目录
File fileDirectory = new File(filePath);
if (!fileDirectory.exists()) {
fileDirectory.mkdirs();
}
try {
// 将上传的文件复制到指定路径下
for (MultipartFile file : files) {
String nameSuffix = cn.hutool.core.io.FileUtil.getSuffix(file.getOriginalFilename());
//文件后缀为vue是页面,其他则为路由(ts)
if ("vue".equals(nameSuffix)) {
File destFile = new File(pagePath + File.separator + file.getOriginalFilename());
try (InputStream inputStream = file.getInputStream();
OutputStream outputStream = Files.newOutputStream(destFile.toPath())) {
IOUtils.copy(inputStream, outputStream);
}
} else {
File destFile = new File(routePath + File.separator + file.getOriginalFilename());
try (InputStream inputStream = file.getInputStream();
OutputStream outputStream = Files.newOutputStream(destFile.toPath())) {
IOUtils.copy(inputStream, outputStream);
}
}
}
// 处理导出静态文件
this.handleTemplateFile(fileIds, filePath);
// 压缩文件夹
File zipFile = new File("template.zip");
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile))) {
// 压缩文件夹
zipFolder(oFile, oFile, zipOut);
}
// 提供下载
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"template.zip\"");
try (InputStream zipStream = Files.newInputStream(zipFile.toPath());
OutputStream outputStream = response.getOutputStream()) {
IOUtils.copy(zipStream, outputStream);
}
// 清空目录存储文件目录数据
clearDirectory(routDirectory);
clearDirectory(pageDirectory);
clearDirectory(fileDirectory);
} catch (Exception e) {
throw new BusinessException("压缩源码报错!" + e.getMessage());
}
}
/**
* 导出源码处理静态文件
*
* @param fileIds 文件ID
* @param filePath 存储静态文件路径
* @throws IOException
* @作者 梁伟浩
* @日期 2024-05-09 11:08 星期四
*/
private void handleTemplateFile(String fileIds, String filePath) throws IOException {
InputStream inputStream = null;
try {
if (StringUtil.isNotEmpty(fileIds)) {
// 英文逗号分割
List<String> ids = new ArrayList<>(Arrays.asList(fileIds.split(",")));
// 处理文件存到模版文件夹
for (String fileId : ids) {
SysFile sysFile = sysFileMapper.selectById(fileId);
if (Objects.nonNull(sysFile)) {
String objectName = sysFile.getFileUrl();
String fileName = fileId + "." + sysFile.getFileSuffix();
if (objectName.contains("/minio/")) {
// 找到第一个出现 "/minio/" 的位置
int startIndex = objectName.indexOf("/minio/") + "/minio/".length();
objectName = objectName.substring(startIndex);
}
inputStream = minIoUtil.getObject(objectName);
File destFile = new File(filePath + File.separator + fileName);
try (OutputStream outputStream = Files.newOutputStream(destFile.toPath())) {
// 将对应文件夹放到指定路径目录
IOUtils.copy(inputStream, outputStream);
}
}
}
}
} catch (Exception e) {
throw new BusinessException("导出源码处理静态文件报错!" + e.getMessage());
} finally {
// 在这里可以关闭 inputStream 流
if (inputStream != null) {
inputStream.close();
}
}
}
/**
* 递归压缩处理子目录下的文件
*
* @param directory 文件目录
* @作者 梁伟浩
* @日期 2024-05-07 10:16 星期二
*/
private void zipFolder(File directory, File baseDir, ZipOutputStream zipOut) throws IOException {
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
String relativePath = baseDir.toPath().relativize(file.toPath()).toString() + "/";
ZipEntry zipEntry = new ZipEntry(relativePath);
zipOut.putNextEntry(zipEntry);
// 递归处理子目录下的文件
zipFolder(file, baseDir, zipOut);
} else {
String relativePath = baseDir.toPath().relativize(file.toPath()).toString();
try (FileInputStream fis = new FileInputStream(file)) {
ZipEntry zipEntry = new ZipEntry(relativePath);
zipOut.putNextEntry(zipEntry);
IOUtils.copy(fis, zipOut);
}
}
}
}
/**
* 递归删除指定目录下的数据
*
* @param directory
* @作者 梁伟浩
* @日期 2024-05-06 17:40 星期一
*/
private void clearDirectory(File directory) {
for (File file : directory.listFiles()) {
if (file.isDirectory()) {
clearDirectory(file);
}
file.delete();
}
}
- 服务器xml
#导出源码地址
sourceCode:
sourceCodeUrl: /data/project/template
sourceCodeUrl2: D:\GDIdeaWorkBi\template
fileIdUrl: /data/project/template/src/views/exportDemo/assets/