需求:在LWC中导入CSV数据,这个是常见的需求
本方法有个缺点,CSV文件在Apex代码中解析。
Salesforce有执行时间和内存的限制,估计CSV不能超过2M的内容(请大家自行验证)。
1,importCSV Lightning Web Component的作成
importCSV.js
页面的显示字段,需要修改如下的数组,填写实际需求的字段即可。
const columns = [
{label: 'Name',fieldName: 'Name'},
{label: 'Rating',fieldName: 'Rating'},
{label: 'Type',fieldName: 'Type'},
{label: 'Industry',fieldName: 'Industry'},
{label: 'Ownership',fieldName: 'Ownership'},
];
import { LightningElement, track } from 'lwc';
import ReadCSVFile from '@salesforce/apex/ImportCSVHandler.ReadCSVFile';
import SaveFile from '@salesforce/apex/ImportCSVHandler.SaveFile';
import {ShowToastEvent} from 'lightning/platformShowToastEvent';
const columns = [
{label: 'Name',fieldName: 'Name'},
{label: 'Rating',fieldName: 'Rating'},
{label: 'Type',fieldName: 'Type'},
{label: 'Industry',fieldName: 'Industry'},
{label: 'Ownership',fieldName: 'Ownership'},
];
export default class ImportCSV extends LightningElement {
@track columns = columns;
@track data;
@track fileName = '';
@track showLoadingSpinner = false;
@track isTrue = true;
filesUploaded = [];
file;
fileContents;
fileReader;
MAX_FILE_SIZE = 1500000;
handleFilesChange(event) {
if(event.target.files.length > 0) {
this.filesUploaded = event.target.files;
if(this.filesUploaded[0].size > this.MAX_FILE_SIZE){
this.isTrue = true;
this.fileName = 'File size is too large!!';
}
else{
this.isTrue = false;
this.fileName = event.target.files[0].name;
this.file = this.filesUploaded[0];
this.showLoadingSpinner = true;
this.fileReader= new FileReader();
this.fileReader.onloadend = (() => {
this.fileContents = this.fileReader.result;
this.ReadFile();
});
this.fileReader.readAsText(this.file);
}
}
else{
this.isTrue = true;
this.fileName = 'Please select a CSV file to upload!!';
}
}
ReadFile() {
ReadCSVFile({ base64Data: JSON.stringify(this.fileContents)})
.then(result => {
window.console.log(result);
this.data = result;
this.showLoadingSpinner = false;
})
.catch(error => {
window.console.log(error);
this.isTrue = true;
this.showLoadingSpinner = false;
this.dispatchEvent(
new ShowToastEvent({
title: 'Invalid data found in file',
message: error.message,
variant: 'error',
}),
);
});
}
handleSave(){
if(!this.isTrue){
this.showLoadingSpinner = true;
SaveFile({ jsonString: JSON.stringify(this.data)})
.then(result => {
this.showLoadingSpinner = false;
if(result=='SUCCESS'){
this.isTrue = true;
this.dispatchEvent(
new ShowToastEvent({
title: 'Success!!',
message: this.file.name + ' - Uploaded Successfully!!',
variant: 'success',
}),
);
}
else{
this.showLoadingSpinner = false;
this.dispatchEvent(
new ShowToastEvent({
title: 'Error',
message: result,
variant: 'error',
}),
);
}
})
.catch(error=>{
this.dispatchEvent(
new ShowToastEvent({
title: 'Error',
message: error.message,
variant: 'error',
}),
);
});
}
}
}
importCSV.html
<template>
<template if:true={showLoadingSpinner}>
<div style="z-index: 10000 !important;">
<lightning-spinner alternative-text="Uploading......" size="medium" style="z-index: 10000 !important;"></lightning-spinner>
</div>
</template>
<lightning-card title="Import CSV Data in Lightning Web Components" icon-name="doctype:csv">
<center>
<div>
<lightning-input label="" name="file uploader" onchange={handleFilesChange} type="file" multiple></lightning-input>
</div><br/>
<div class="slds-text-body_small slds-text-color_error">{fileName}</div><br/>
<div>
<lightning-button class="slds-m-top--medium" label="Import Data" onclick={handleSave} variant="brand" disabled={isTrue}></lightning-button>
</div>
</center>
</lightning-card>
<lightning-card title="Accounts" icon-name="standard:account">
<div style="width: auto;">
<template if:true={data}>
<lightning-datatable data={data} columns={columns} key-field="id" hide-checkbox-column="true"></lightning-datatable>
</template>
</div>
</lightning-card>
</template>
importCSV.js-meta.xml的内容
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>55.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__UtilityBar</target>
<target>lightning__FlowScreen</target>
<target>lightningCommunity__Page</target>
<target>lightningCommunity__Default</target>
</targets>
</LightningComponentBundle>
2,ImportCSVHandler.cls的作成
ImportCSVHandler.cls
关于数据的创建,各个字段在如下的代码段中修改。
lstAcc.add(new Account(
Name = csvRowData[0],
Rating=csvRowData[1],
Type=csvRowData[2],
Industry=csvRowData[3],
Ownership=csvRowData[4]
));
public with sharing class ImportCSVHandler {
@AuraEnabled
public static List<Account> ReadCSVFile(String base64Data) {
String data=JSON.deserializeUntyped(base64Data).toString();
List<Account> lstAcc = new List<Account>();
List<String> lstCSVLines = data.split('\n');
for(Integer i = 1; i < lstCSVLines.size(); i++){
String csvLine = lstCSVLines[i];
String prevLine = csvLine;
Integer startIndex;
Integer endIndex;
while(csvLine.indexOf('"') > -1){
if(startIndex == null){
startIndex = csvLine.indexOf('"');
csvLine = csvLine.substring(0, startIndex) + ':quotes:' + csvLine.substring(startIndex+1, csvLine.length());
}else{
if(endIndex == null){
endIndex = csvLine.indexOf('"');
csvLine = csvLine.substring(0, endIndex) + ':quotes:' + csvLine.substring(endIndex+1, csvLine.length());
}
}
if(startIndex != null && endIndex != null){
String sub = csvLine.substring(startIndex, endIndex);
sub = sub.replaceAll(',', ':comma:');
csvLine = csvLine.substring(0, startIndex) + sub + csvLine.substring(endIndex, csvLine.length());
startIndex = null;
endIndex = null;
}
}
List<String> csvRowData = new List<String>();
for(String column : csvLine.split(',')){
column = column.replaceAll(':quotes:', '').replaceAll(':comma:', ',');
csvRowData.add(column);
}
lstAcc.add(new Account(
Name = csvRowData[0],
Rating=csvRowData[1],
Type=csvRowData[2],
Industry=csvRowData[3],
Ownership=csvRowData[4]
));
}
return lstAcc;
}
@AuraEnabled
public static string SaveFile(string jsonString){
string sMessage='';
try {
List<Account> lstACCToInsert=(List<Account>)JSON.deserialize(jsonString, List<Account>.class);
insert lstACCToInsert;
sMessage='SUCCESS';
} catch (Exception e) {
sMessage=e.getMessage();
}
return sMessage;
}
}
执行效果
准备工作 创建如下CSV文件
Name,Rating,Type,Industry,Ownership
GogogoAccount03,Hot,Prospect,Agriculture,Public
效果如下
参考文章
代码原地址,本文章对代码会作稍微的修改,方便大家理解 。