Home > Mobile >  How to download file in angular with tree?
How to download file in angular with tree?

Time:06-22

Currently I am trying to implement a download file from a tree. A tree has children and attachments. The user can select multiple children tree or multiple attachments. Backend server should collect the data from a database and build a zip file based on a tree. Please let me know if I am implementing it correctly.

download file 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'
    });
  }
}

folder 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 template.htlm

 <span>
                <input type="checkbox"  (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;
}

CodePudding user response:

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;
}

CodePudding user response:

  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();
        }
      );
  }

  • Related