javascript - 在客户端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);
解决方案
想我会分享我的解决方案,因为我已经看到了很多关于此的问题,但没有多少有用的答案。
使用 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);
推荐阅读
- javascript - 尝试在我的 JSON 中创建 URL,但不确定这是否正确
- javascript - AngularJS 应用程序:使分页考虑到标准过滤器
- javascript - 为什么从可拖动的 jquery 中获取错误的左侧和顶部位置值
- bash - makefile 并行运行目标
- ldap - Gerrit LDAP 设置和获取 InitInjector 失败错误
- c# - 如何让脚本窗口显示其输出并在最后捕获其 StdOut?
- wordpress - 将站点迁移到/从另一台服务器时如何更改 Wordpress 站点 URL?
- angular - 如何在角度 6 中使用 @Output 来发出对象数组?
- vba - 读取 Outlook HTML 正文时出错
- oracle - Oracle Apex IR 无法显示 clob