angular - 使用带有 Ionic 4 的 Papa Parse 从 CSV 数据导入特定列
问题描述
我有代码使用 Papa Parse 插件将 CSV 数据拉入我的 Ionic 4 应用程序,但我想拉入特定的数据字段 - 不确定如何将其拉出。
例如,如果我只想显示“名字”和“姓氏”而不是所有字段怎么办?
虚拟数据.csv
Date,"First Name","Last Name","Email","Amount","Currency","InvoiceID","Country"
08.22.2019,"Simon","Grimm","saimon@devdactic.com","50,00","EUR","0001","GER"
08.21.2019,"Simon","Grimm","saimon@devdactic.com","45,00","EUR","0002","GER"
08.19.2019,"Simon","Grimm","saimon@devdactic.com","40,00","EUR","0003","GER"
08.18.2019,"Simon","Grimm","saimon@devdactic.com","35,00","EUR","0004","GER"
08.17.2019,"Simon","Grimm","saimon@devdactic.com","30,00","EUR","0005","GER"
08.16.2019,"Simon","Grimm","saimon@devdactic.com","25,00","EUR","0006","GER"
TS 脚本页面
import { Component, OnInit } from '@angular/core';
import { Papa } from 'ngx-papaparse';
import { Platform } from '@ionic/angular';
import { File } from '@ionic-native/file/ngx';
import { SocialSharing } from '@ionic-native/social-sharing/ngx';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-examination-test',
templateUrl: './examination-test.page.html',
styleUrls: ['./examination-test.page.scss'],
})
export class ExaminationTestPage {
csvData: any[] = [];
headerRow: any[] = [];
constructor(
private http: HttpClient,
private papa: Papa,
private plt: Platform,
private file: File,
private socialSharing: SocialSharing,
) {
this.loadCSV();
}
private loadCSV() {
this.http
.get('./assets/Sins.csv', {
responseType: 'text'
})
.subscribe(
data => this.extractData(data),
err => console.log('something went wrong: ', err)
);
}
private extractData(res) {
let csvData = res || '';
this.papa.parse(csvData, {
complete: parsedData => {
this.headerRow = parsedData.data.splice(0, 1)[0];
this.csvData = parsedData.data;
}
});
}
exportCSV() {
let csv = this.papa.unparse({
fields: this.headerRow,
data: this.csvData
});
if (this.plt.is('cordova')) {
this.file.writeFile(this.file.dataDirectory, 'Sins.csv', csv, {replace: true}).then( res => {
this.socialSharing.share(null, null, res.nativeURL, null).then(e =>{
// Success
}).catch(e =>{
console.log('Share failed:', e)
});
}, err => {
console.log('Error: ', err);
});
} else {
// Dummy implementation for Desktop download purpose
var blob = new Blob([csv]);
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.download = 'newdata.csv';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
}
trackByFn(index: any, item: any) {
return index;
}
}
HTML 脚本
<ion-header>
<ion-toolbar color="primary">
<ion-title>
Devdactic CSV
</ion-title>
<ion-buttons slot="start">
<ion-button (click)="exportCSV()">
Export
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content scrollX="true">
<table border="1" class="data-table">
<tbody>
<tr>
<td *ngFor="let header of headerRow" text-center>
<b>{{ header }}</b>
</td>
</tr>
<tr *ngFor="let row of csvData; let i = index">
<td
*ngFor="let data of row; let j = index; trackBy: trackByFn"
class="data-col"
>
<ion-input type="text" [(ngModel)]="csvData[i][j]"></ion-input>
</td>
</tr>
</tbody>
</table>
</ion-content>
解决方案
检查后:
private extractData(res) {
let csvData = res || '';
this.papa.parse(csvData, {
complete: parsedData => {
this.headerRow = parsedData.data.splice(0, 1)[0];
this.csvData = parsedData.data;
}
});
}
离开你是为了结果,似乎它把每一行都留给你作为数组的条目。
我会做两件事,具体取决于情况,但这假设 csv 每次总是以相同的 8 列结束。首先是一个界面:
interface InvoiceDetails {
date: moment();
firstName: string;
lastName: string;
email: string;`enter code here`
amount: number;
currency: string
invoiceId: string;
country: string;
}
然后我会为了方便添加一个枚举:
enum Column {
Date = 0,
FirstName = 1,
LastName = 2,
Email = 3,
Amount = 4,
Currency = 5,
InvoiceID = 6,
Country = 7
}
然后我会在你的 extractData 方法中,添加一个方法:
private extractData(res) {
let csvData = res || '';
this.papa.parse(csvData, {
complete: parsedData => {
this.headerRow = parsedData.data.splice(0, 1)[0];
this.csvData = this.remapToInvoiceDetails(parsedData.data);
}
});
}
然后 remapToInvoiceDetails 看起来像这样:
remapToInvoiceDetails(csvData: string[]) {
const invoices: InvoiceDetails[] = [];
for (const data of csvData) {
invoices.push({
date: data[Column .Date],
firstname: data[Column .FirstName],
lastName: data[Column .LastName],
email: data[Column .Email],
amount: data[Column .Amount],
currency: data[Column .Currency],
invoiceID: data[Column .InvoiceID],
country: data[Column .Country],
});
}
return invoices;
}
通过这样做,您可以将数据置于一个允许您使用智能感知的结构中,并且您可以更轻松地挑选出您想要的属性。也就是说,假设您现在像这样定义 csvData:
csvData: Invoices[] = [];
但是我现在只称它为发票或更合适的名称,因为现在它已经结构化了。注意这是因为你总是得到 8 列,并且没有空检查,所以也需要添加。
推荐阅读
- ms-access - 是否可以将照片放在报告上并在打印视图/打印时消失?
- android - SwipeRefreshLayout 中的 Android ViewPager
- keras - Keras 在极其简单的测试代码中拟合 ValueError
- javascript - 删除 Google 表单提交的文件
- java - 我无法让我的包按照我想要的方式编译
- apache-kafka - 在 Kafka Streams DSL 中使用内部连接获取记录密钥
- powershell - Powershell + 7zip 批量提取和重命名 - 收到“没有要处理的文件”消息
- scala - Geotrellis.spark._ 从当前主服务器拉出时不是包 Geotrellis 的成员吗?
- javascript - 是 React.ComponentType
流的一部分? - typo3 - TYPO3 v9 使用 Microsoft SQL Server 2016