首页 > 解决方案 > 在客户端reactJS下载之前将多个文件放到一个zip文件夹中

问题描述

我在这里有两个函数,它们接受一组文件键,并将其传递给一个下载函数,该函数将从 aws s3 单独下载每个文件。

我想将所有文件放在一个 zip 文件夹中,然后下载那个 zip 文件夹,这样所有文件就在一起了。

问题:

1st我将如何首先设置目录来保存文件?

2nd我如何将所有正在下载的文件放入一个 zip 文件夹中,然后下载 zip 文件夹?

非常感谢任何帮助或见解。

当前代码

async function handleDownloadClick(event) {
         event.preventDefault();

      const imagesAsArray = [...imagesUploaded];

        for (let i = 0; i < imagesAsArray.length; i++) {                      

            await DownloadFile(imagesAsArray[i]);

        }
    }


    async function DownloadFile(fileToDownload) {

    const filename = `${fileToDownload.key}`;

   const result = await Storage.get(fileToDownload.key, {download: true})

        console.log(result)
        let mimeType = result.ContentType

        let fileName = fileToDownload.key.split(`${job.jobId},/`)

        console.log(fileToDownload.key)

        try {
          let blob = new Blob([result.Body], {type: mimeType})

          //downloading the file depends on the browser
          //IE handles it differently than chrome/webkit
          if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveOrOpenBlob(blob, fileName)
          } else {
            let objectUrl = URL.createObjectURL(blob);
            let link = document.createElement('a')
            link.href = objectUrl
            link.setAttribute('download', fileName)
            document.body.appendChild(link)
            link.click()
            document.body.removeChild(link)
          }
        } catch (exc) {
          console.log("Save Blob method failed with the following exception.");
          console.log(exc);
        }

   }

更新的代码做我需要做的事情

想我会分享我的解决方案,因为我已经看到了很多关于此的问题,但没有多少有用的答案。

使用 JSZip:https ://stuk.github.io/jszip/

saveAs从 fileSaver.js使用: https ://github.com/eligrey/FileSaver.js

首先:它循环从 s3 单独下载每个文件,创建一个 blob,并将每个 blob/文件放入一个“文件夹”。

第二:从 s3 下载每个文件后,它将使用 saveAs 方法下载/保存压缩文件夹。


function NewEditInfo(props) {
const [job, setJob] = useState([]);
const [imagesUploaded, setImagesUploaded] = useState(null); 

//initialize jsZip
var JSZip = require("jszip");
let zip = new JSZip();
let photoZip = zip.folder(`${job.streetAddress}`);

useEffect(() => { 
     //// API call to load job info from dynamo db
  function loadJob() {
    return API.get("api name", "/tablename/tableinfo", {
  'queryStringParameters': {jobId: props.match.params.id}    
   }); 
  } 
   /// onload function to load job info and get a count of files
    async function onLoad() {   

      try {
        const job = await loadJob();
        setJob(job[0])

        const ImagesUploaded = await Storage.list(`${job[0].jobId}`);
        setImagesUploaded(ImagesUploaded);

        } catch (e) {
          alert(e);
      }

    }

    onLoad();
  }, [props.match.params.id,]);


  /// On download button click, loop through / download images using the key given from storage.list in onload function
  async function handleDownloadClick(event) {
         event.preventDefault();    
      const imagesAsArray = [...imagesUploaded];

    for (let i = 0; i < imagesAsArray.length; i++) {                                                                                          
      await DownloadFileFromS3(imagesAsArray[i]); 
        }
       /// waits for "await DownloadFileFromS3, then executes the save as which saves the zipped folder created in "DownloadFileFromS3"
        zip.generateAsync({type:"blob"})
             .then(function(content) {
        saveAs(content, `${job.streetAddress}`);
        });
   }


    /// download each file from s3 and put it in the zip folder
    async function DownloadFileFromS3(fileToDownload) {

        const result = await Storage.get(fileToDownload.key, {download: true})

        let mimeType = result.ContentType
        let fileName = fileToDownload.key
        let blob = new Blob([result.Body], {type: mimeType})

        photoZip.file(fileName[1], blob)

   }

 return(

      <IonPage>
      <IonHeader>
        <IonToolbar>
      <IonButtons slot="start">
          <IonBackButton/>
      </IonButtons>
          <IonTitle>Download Images</IonTitle>
        </IonToolbar>
      </IonHeader>  
      <IonContent className="ion-padding">   
      <IonButton onclick={handleDownloadClick}> download </IonButton>
      </IonContent>
      </IonPage>
    );


  }


export default withRouter(NewEditInfo);

标签: javascriptreactjsamazon-web-servicesloopsdownload

解决方案


想我会分享我的解决方案,因为我已经看到了很多关于此的问题,但没有多少有用的答案。

使用 JSZip:https ://stuk.github.io/jszip/

使用 fileSaver.js 中的 saveAs:https ://github.com/eligrey/FileSaver.js

首先:它循环从 s3 单独下载每个文件,创建一个 blob,并将每个 blob/文件放入一个“文件夹”。

第二:从 s3 下载每个文件后,它将使用 saveAs 方法下载/保存压缩文件夹。

function NewEditInfo(props) {
const [job, setJob] = useState([]);
const [imagesUploaded, setImagesUploaded] = useState(null); 

//initialize jsZip
var JSZip = require("jszip");
let zip = new JSZip();
let photoZip = zip.folder(`${job.streetAddress}`);

useEffect(() => { 
     //// API call to load job info from dynamo db
  function loadJob() {
    return API.get("api name", "/tablename/tableinfo", {
  'queryStringParameters': {jobId: props.match.params.id}    
   }); 
  } 
   /// onload function to load job info and get a count of files
    async function onLoad() {   

      try {
        const job = await loadJob();
        setJob(job[0])

        const ImagesUploaded = await Storage.list(`${job[0].jobId}`);
        setImagesUploaded(ImagesUploaded);

        } catch (e) {
          alert(e);
      }

    }

    onLoad();
  }, [props.match.params.id,]);


  /// On download button click, loop through / download images using the key given from storage.list in onload function
  async function handleDownloadClick(event) {
         event.preventDefault();    
      const imagesAsArray = [...imagesUploaded];

    for (let i = 0; i < imagesAsArray.length; i++) {                                                                                          
      await DownloadFileFromS3(imagesAsArray[i]); 
        }
       /// waits for "await DownloadFileFromS3, then executes the save as which saves the zipped folder created in "DownloadFileFromS3"
        zip.generateAsync({type:"blob"})
             .then(function(content) {
        saveAs(content, `${job.streetAddress}`);
        });
   }


    /// download each file from s3 and put it in the zip folder
    async function DownloadFileFromS3(fileToDownload) {

        const result = await Storage.get(fileToDownload.key, {download: true})

        let mimeType = result.ContentType
        let fileName = fileToDownload.key
        let blob = new Blob([result.Body], {type: mimeType})

        photoZip.file(fileName[1], blob)

   }

 return(

      <IonPage>
      <IonHeader>
        <IonToolbar>
      <IonButtons slot="start">
          <IonBackButton/>
      </IonButtons>
          <IonTitle>Download Images</IonTitle>
        </IonToolbar>
      </IonHeader>  
      <IonContent className="ion-padding">   
      <IonButton onclick={handleDownloadClick}> download </IonButton>
      </IonContent>
      </IonPage>
    );


  }


export default withRouter(NewEditInfo);

推荐阅读