目前我正在嘗試從樹中實作下載檔案。一棵樹有孩子和附件。用戶可以選擇多個子樹或多個附件。后端服務器應該從資料庫中收集資料并基于樹構建一個 zip 檔案。如果我正確實施它,請告訴我。
下載檔案 service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class DownloadService {
downloadList: any[] = [];
downloadAttachmentList: any[] = [];
isDownloadInQueue = false;
constructor(
private http: HttpClient
) { }
clear() {
this.downloadList.splice(0, this.downloadList.length);
this.downloadAttachmentList.splice(0, this.downloadAttachmentList.length);
this.isDownloadInQueue = false;
}
addDownloadItemToList(node: any) {
this.isDownloadInQueue = true;
this.downloadList.push(node);
}
removeDownloadItemToList(node: any) {
let nodeIndex = this.downloadList.indexOf(node);
if(nodeIndex >= 0) {
// remove it
this.downloadList.splice(nodeIndex, 1);
if(this.downloadList.length == 0 && this.downloadAttachmentList.length == 0)
this.isDownloadInQueue = false;
}
}
addDownloadAttachmentItemToList(node: any) {
this.isDownloadInQueue = true;
this.downloadAttachmentList.push(node);
}
removeDownloadAttachmentItemToList(node: any) {
let nodeIndex = this.downloadAttachmentList.indexOf(node);
if(nodeIndex >= 0) {
// remove it
this.downloadAttachmentList.splice(nodeIndex, 1);
if(this.downloadAttachmentList.length == 0 && this.downloadAttachmentList.length == 0)
this.isDownloadInQueue = false;
}
}
downloadFilesAsZip(nodeName: string | undefined) {
return this.http.post(`${environment.server}/download`, {
children: this.downloadList,
attachments: this.downloadAttachmentList,
nodeName: nodeName
}, {
responseType: 'arraybuffer'
});
}
}
檔案夾 explorer.ts
toggleDownloadSelected(selected_leaf: any, event: any) {
if(event.target.checked)
this.downloadService.addDownloadItemToList(selected_leaf);
else
this.downloadService.removeDownloadItemToList(selected_leaf);
}
toggleDownloadAttachmentSelected(selected_leaf: any, event: any) {
if(event.target.checked)
this.downloadService.addDownloadAttachmentItemToList(selected_leaf);
else
this.downloadService.removeDownloadAttachmentItemToList(selected_leaf);
}
html模板.htlm
<span>
<input type="checkbox" class="chk-btn" (change)="toggleDownloadSelected(leaf, $event)"/>
</span>
package com.example.treetable;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@RestController
@RequestMapping("download")
@CrossOrigin("http://localhost:4200")
public class DownloadController {
@Autowired
private AttachmentDataRepository attachmentDataRepository;
@PostMapping
@RequestMapping(produces = "application/zip")
public void downloadResourceAsZip(
@RequestBody FileTreeDto fileTree,
HttpServletResponse response
) throws IOException {
List<AttachmentData> dataList = attachmentDataRepository.findAll();
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
createListOfZipEntry(fileTree, fileTree.getNodeName() , zos);
zos.closeEntry();
zos.close();
}
private List<ZipEntry> createListOfZipEntry(FileTreeDto fileTreeDto, String rootPath, ZipOutputStream zos) throws IOException {
List<ZipEntry> zipEntries = new ArrayList<>();
String newRootPath = rootPath "/" fileTreeDto.getNodeName();
// check if attachement arrays exist
if(fileTreeDto.getAttachments() != null) {
for(AttachmentDataDto dataDto: fileTreeDto.getAttachments()) {
System.out.println("Getting by id " dataDto.getAttachment_id());
Optional<AttachmentData> optionalAttachmentData = attachmentDataRepository.findById(dataDto.getAttachment_id());
if(optionalAttachmentData.isPresent()) {
AttachmentData data = optionalAttachmentData.get();
String path = newRootPath "/" dataDto.getName();
System.out.println("Path " path);
ZipEntry zipEntry = new ZipEntry(path);
zipEntry.setSize(data.getFile().length);
zos.putNextEntry(zipEntry);
zos.write(data.getFile());
zipEntries.add(zipEntry);
}
}
}
if(fileTreeDto.getChildren() == null || fileTreeDto.getChildren().size() <= 0)
return zipEntries;
for (FileTreeDto ftD : fileTreeDto.getChildren()) {
zipEntries.addAll(createListOfZipEntry(ftD, newRootPath , zos));
}
return zipEntries;
}
}
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class FileTreeDto {
private String nodeName;
private List<FileTreeDto> children;
private List<AttachmentDataDto> attachments;
}
uj5u.com熱心網友回復:
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AttachmentRequestDto {
private Long id;
private String name;
private Long attachment_id;
}
uj5u.com熱心網友回復:
downloadFile() {
if(!this.downloadService.isDownloadInQueue) return;
this.downloadService.downloadZipOrFiles(this.selected_leaf?.nodeName);
}
downloadZipOrFiles(nodeName: string | undefined) {
if(this.downloadList.length <= 0 && this.downloadAttachmentList.length > 0) {
this.downloadAttachmentOnly(nodeName);
}
else
{
if(this.downloadList.length > 0 || this.downloadAttachmentList.length > 0) {
this.downloadFilesAsZip(nodeName);
}
}
}
downloadAttachmentOnly(nodeName: string | undefined) {
let attachmentIds = this.downloadAttachmentList.map((attachment) => attachment.attachment_id);
this.http.post(`${environment.server}/download/files?ids=` attachmentIds, {
}).subscribe(
(res: any) => {
if(res && res.length > 0) {
for(let i = 0; i < res.length; i ) {
var blob=new Blob([res[i].file], {type: res[i].docType});// change resultByte to bytes
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download=res[i].fileName;
link.click();
}
this.clear();
}
}
);
}
downloadFilesAsZip(nodeName: string | undefined) {
this.http.post(`${environment.server}/download`, {
children: this.downloadList,
attachments: this.downloadAttachmentList,
nodeName: nodeName
}, {
responseType: 'arraybuffer'
}).subscribe(
res => {
const blob = new Blob([res], {
type: 'application/zip'
});
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download = nodeName ? nodeName : 'downloadds';
link.click();
// const url = window.URL.createObjectURL(blob);
// window.open(url);
this.clear();
}
);
}
uj5u.com熱心網友回復:
downloadFile() {
if(!this.downloadService.isDownloadInQueue) return;
this.downloadService.downloadFilesAsZip(this.selected_leaf?.nodeName)
.subscribe(
res => {
const blob = new Blob([res], {
type: 'application/zip'
});
const url = window.URL.createObjectURL(blob);
window.open(url);
this.downloadService.clear();
}
);
}
uj5u.com熱心網友回復:
@PostMapping("files")
public ResponseEntity downloadFiles(
@RequestParam("ids") Long[] attachmentIds
) throws IOException {
List<AttachmentData> dataList = this.attachmentDataRepository.getDataByAttachmentIds(attachmentIds);
return ResponseEntity.ok(dataList);
}
private List<ZipEntry> createListOfZipEntry(FileTreeDto fileTreeDto, String rootPath, ZipOutputStream zos) throws IOException {
List<ZipEntry> zipEntries = new ArrayList<>();
String newRootPath = "";
if(!rootPath.equalsIgnoreCase(fileTreeDto.getNodeName())) {
newRootPath = rootPath "/" fileTreeDto.getNodeName();
}else{
newRootPath = rootPath;
}
// check if attachement arrays exist
if(fileTreeDto.getAttachments() != null) {
for(AttachmentDataDto dataDto: fileTreeDto.getAttachments()) {
System.out.println("Getting by id " dataDto.getAttachment_id());
Optional<AttachmentData> optionalAttachmentData = attachmentDataRepository.findById(dataDto.getAttachment_id());
if(optionalAttachmentData.isPresent()) {
AttachmentData data = optionalAttachmentData.get();
String path = newRootPath "/" dataDto.getName();
System.out.println("Path " path);
ZipEntry zipEntry = new ZipEntry(path);
zipEntry.setSize(data.getFile().length);
zos.putNextEntry(zipEntry);
zos.write(data.getFile());
zipEntries.add(zipEntry);
}
}
}
if(fileTreeDto.getChildren() == null || fileTreeDto.getChildren().size() <= 0)
return zipEntries;
for (FileTreeDto ftD : fileTreeDto.getChildren()) {
zipEntries.addAll(createListOfZipEntry(ftD, newRootPath , zos));
}
return zipEntries;
}
@Query("SELECT a FROM AttachmentData a where a.id in :attachmentIds")
List<AttachmentData> getDataByAttachmentIds(Long[] attachmentIds);
uj5u.com熱心網友回復:
syncTree() {
this.is_syncing = true;
this.route.params.subscribe(param => {
if(param['id']) {
this.fileService.getFundTreeByFundId(param['id'])
.pipe(
delay(1000)
)
.subscribe(
res => {},
err => {},
() => {
this.is_syncing = false;
}
);
}
});
}
uj5u.com熱心網友回復:
.spin {
animation-name: spin;
animation-duration: 1000ms;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes spin {
from {
transform:rotate(0deg);
}
to {
transform:rotate(360deg);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/495521.html
