在 angular 中使用 jsZIP 在一个 zip 文件夹中下载多个 csv 文件
Download multiple csv files in one zip folder using jsZIP in angular
下面是我为 csv 文件创建数据并在 zip 文件夹中下载 csv 文件的代码:
generateCSVfiles()
{
this.studentdata.forEach(function (student)
{
this.service.getStudentDetails(student.studentId).subscribe
(res => {
var dataSet = JSON.parse (res);
// start
if (student.studentId == "Senior") {
const header = ["studentId","studentName","studentaddress", "studentmarks", "studentgrade"];
const replacer = (key, values) => values === null ? '' : values // specify how you want to handle null values here
this.seniordata = dataSet.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
this.seniordata.unshift(header.join(','));
this.seniordata = this.seniordata.join('\r\n');
}
else (student.studentId == "Junior") {
const header = ["studentId","studentName","studentaddress", "studentmarks", "studentgrade"];
const replacer = (key, values) => values === null ? '' : values // specify how you want to handle null values here
this.juniordata = dataSet.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
this.juniordata.unshift(header.join(','));
this.juniordata = this.juniordata.join('\r\n');
}
this.downloadzip();
}
}.bind(this)
}
public downloadzip()
{
let zip = new JSZip();
// Fill CSV variable
// i am getting two separate zip file by below logic but need to
//implement logic here to add two different file in one zip folder
zip.file( 'Studentrecord'+'.csv', this.juniordata);
zip.file( 'Studentrecord'+'.csv', this.seniordata);
zip.generateAsync({
type: "base64"
}).then(function (content) {
window.location.href = "data:application/zip;base64," + content ;
});
}
当我们一次获得一名大三或大四学生的回复数据时,以上代码工作正常并且能够在 zip 文件夹中下载 csv 文件。但是当我们同时收到初级和高级数据时,它会下载不同的 zip 文件,或者有时只生成一个 zip 文件。但我希望两个文件都在一个 zip 文件夹中。谁能指导我如何在一个 zip 文件夹中下载不同的 csv 文件。
this.studentdata =[{studentId: "Senior"
StudentName: "Rock"},{studentId: "Junior"
StudentName: "John"}]
上述变量中可用的此类数据
dataset = [{studentId: "Senior"
StudentName: "Rock",studentaddress:"US",studentmarks:"56",studentgrade:"A"},{studentId: "Junior"
StudentName: "John",studentaddress:"UK",studentmarks:"59",studentgrade:"B"}]
此类数据来自json
提供不同的文件名,您为两种记录提供了相同的文件名,并且在 zip 中不能有多个同名文件。如果你的目标是有多个 excel 表,那么这个问题是错误的。在这种情况下,您需要像那样创建 excel。
这里你没有正确表达你的问题。感谢您在 stackbliz 上创建演示。无论如何,这是因为您的迭代不会等待每个可观察对象完成后再继续下一个,并且您已经在评论中告诉我们这是真的。
首先你需要了解rxjs中observable、promise的概念。一旦你有了正确的理解,就可以通过一些额外的运算符,如 merge、mergeAll、forkjoin 等 https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin
现在回答你的问题:
总是对这样的事情使用 Promises,所以下面是一个例子,但是,我相信也有 RXJS 方法可以解决这个问题,所以你可能想探索一下。
请完成 http://bluebirdjs.com/docs/getting-started.html 以串行迭代异步。
import * as Bluebird from 'bluebird';
async generateCSVfiles() {
//first iterate through everything in series
await Bluebird.mapSeries(this.studentdata, (data) => {
return new Promise((resolve, reject) => {
this.service.getStudentDetails(student.studentId, student.StudentName).subscribe(res => {
...
//once you finish your conditionals
resolve();
})
});
});
//then, once complete, run download zip
this.downloadzip();
}
下面是我为 csv 文件创建数据并在 zip 文件夹中下载 csv 文件的代码:
generateCSVfiles()
{
this.studentdata.forEach(function (student)
{
this.service.getStudentDetails(student.studentId).subscribe
(res => {
var dataSet = JSON.parse (res);
// start
if (student.studentId == "Senior") {
const header = ["studentId","studentName","studentaddress", "studentmarks", "studentgrade"];
const replacer = (key, values) => values === null ? '' : values // specify how you want to handle null values here
this.seniordata = dataSet.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
this.seniordata.unshift(header.join(','));
this.seniordata = this.seniordata.join('\r\n');
}
else (student.studentId == "Junior") {
const header = ["studentId","studentName","studentaddress", "studentmarks", "studentgrade"];
const replacer = (key, values) => values === null ? '' : values // specify how you want to handle null values here
this.juniordata = dataSet.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
this.juniordata.unshift(header.join(','));
this.juniordata = this.juniordata.join('\r\n');
}
this.downloadzip();
}
}.bind(this)
}
public downloadzip()
{
let zip = new JSZip();
// Fill CSV variable
// i am getting two separate zip file by below logic but need to
//implement logic here to add two different file in one zip folder
zip.file( 'Studentrecord'+'.csv', this.juniordata);
zip.file( 'Studentrecord'+'.csv', this.seniordata);
zip.generateAsync({
type: "base64"
}).then(function (content) {
window.location.href = "data:application/zip;base64," + content ;
});
}
当我们一次获得一名大三或大四学生的回复数据时,以上代码工作正常并且能够在 zip 文件夹中下载 csv 文件。但是当我们同时收到初级和高级数据时,它会下载不同的 zip 文件,或者有时只生成一个 zip 文件。但我希望两个文件都在一个 zip 文件夹中。谁能指导我如何在一个 zip 文件夹中下载不同的 csv 文件。
this.studentdata =[{studentId: "Senior"
StudentName: "Rock"},{studentId: "Junior"
StudentName: "John"}]
上述变量中可用的此类数据
dataset = [{studentId: "Senior"
StudentName: "Rock",studentaddress:"US",studentmarks:"56",studentgrade:"A"},{studentId: "Junior"
StudentName: "John",studentaddress:"UK",studentmarks:"59",studentgrade:"B"}]
此类数据来自json
提供不同的文件名,您为两种记录提供了相同的文件名,并且在 zip 中不能有多个同名文件。如果你的目标是有多个 excel 表,那么这个问题是错误的。在这种情况下,您需要像那样创建 excel。
这里你没有正确表达你的问题。感谢您在 stackbliz 上创建演示。无论如何,这是因为您的迭代不会等待每个可观察对象完成后再继续下一个,并且您已经在评论中告诉我们这是真的。
首先你需要了解rxjs中observable、promise的概念。一旦你有了正确的理解,就可以通过一些额外的运算符,如 merge、mergeAll、forkjoin 等 https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin
现在回答你的问题: 总是对这样的事情使用 Promises,所以下面是一个例子,但是,我相信也有 RXJS 方法可以解决这个问题,所以你可能想探索一下。
请完成 http://bluebirdjs.com/docs/getting-started.html 以串行迭代异步。
import * as Bluebird from 'bluebird';
async generateCSVfiles() {
//first iterate through everything in series
await Bluebird.mapSeries(this.studentdata, (data) => {
return new Promise((resolve, reject) => {
this.service.getStudentDetails(student.studentId, student.StudentName).subscribe(res => {
...
//once you finish your conditionals
resolve();
})
});
});
//then, once complete, run download zip
this.downloadzip();
}