lwc CSV
CSVアップロード
https://developers.tam-bourine.co.jp/entry/2020/11/09/120000
https://www.linkedin.com/pulse/lwc-csv-file-uploader-create-records-saiful-islam?articleId=6653229623884779521
https://www.lightningdesignsystem.com/components/file-selector/#CSS-Class-Overview
https://medium.com/lightningpundit/upload-content-document-after-record-creation-ae7eed19a288
てかコードブロック書けるようになってるやん。
うれしい。
html
<template>
<lightning-card title="CSVアップロード" icon-name="custom:custom15">
<div style="padding: 0 20px;">
<div style="
padding: 10px 0 0 0;
">
<lightning-input type="file" name="csv" label="CSV" onchange="{handleCsvUpload}" accept="text/csv"></lightning-input>
</div>
<p style="padding: 10px 0 0 0;">{fileName}</p>
<div style="
padding: 20px 0 10px 0;
margin: 0 0 0 -5px;
">
<div if:true="{isLoaded}" class="slds-is-relative" style="
height: 60px;
margin: 0 0 -10px 0;
">
<lightning-spinner alternative-text="Loading..." variant="brand"></lightning-spinner>
</div>
<div if:false="{isLoaded}">
<div if:true="{isSend}">
<lightning-button variant="brand" label="送信" title="Primary action" onclick="{handleUpload}" class="slds-m-left_x-small">
</lightning-button>
</div>
<div if:false="{isSend}">
<lightning-button variant="brand" label="送信" disabled="" title="Primary action" onclick="{handleUpload}" class="slds-m-left_x-small">
</lightning-button>
</div>
</div>
</div>
</div>
</lightning-card>
</template>
meta
(html comment removed: ?xml version="1.0" encoding="UTF-8"?)
<lightningcomponentbundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiversion>48.0</apiversion>
<isexposed>true</isexposed>
<targets>
<target>lightning__HomePage</target>
</targets>
</lightningcomponentbundle>
js
`
// Lightning Web Componentから @wire, @api をインポート
import { LightningElement, api } from 'lwc';
// ShowToastEvent(ポップアップメッセージ)をインポート
import {ShowToastEvent} from 'lightning/platformShowToastEvent';
// Apex Classの定義
import insertCsvData from "@salesforce/apex/csvUploder.insertCsvData";
export default class CsvUploader extends LightningElement {
// アップロードファイル
@api file = null;
// ファイル名(画面表示用)
@api fileName;
// 送信フラグ
@api isSend = false;
@api isLoaded = false;
// ファイルの中身
data;
// ファイルを選択すると発火
handleCsvUpload(event) {
// 選択したアップロードファイルを取得
this.file = event.detail.files;
// ファイル名を取得
this.fileName = this.file[0].name;
// ファイルが選択されたらボタンをアクティブ化
this.isSend = this.file;
// FileReaderオブジェクトの生成
const fileReader = new FileReader();
// ファイルの読み込みが完了したら実行
fileReader.onloadend = () => {
// 読み込み結果を設定
this.data = fileReader.result;
}
// ファイルを読み込み
fileReader.readAsText(this.file[0]);
}
// csvアップロード処理
handleUpload() {
// アップロードファイルを選択していないと送信させない
if (!this.file) {
return
}
// ローディング表示をtrue
this.isLoaded = true;
Promise.resolve().then(() => {
return new Promise((resolve, reject) => {
// ファイルを改行で分割しフィールドごとに配列で取得
const rows = this.data.split(/\r\n|\n/);
console.log(rows);
// データをjson形式で取得
const outputJson = [];
for(let i=1 ; i<rows.length ;="" i++)="" {="" const="" cols="rows[i].split(',');" outputjson.push({="" name:="" cols[0],="" site:="" cols[1],="" billingstate:="" cols[2],="" phone:="" cols[3],="" type:="" cols[4],="" });="" }="" apexでインポート処理="" insertcsvdata({="" jsondata:="" json.stringify(outputjson)="" })="" .then(result=""> {
this.data = result;
resolve(this.data);
// 成功ポップアップメッセージ表示
this.dispatchEvent(
new ShowToastEvent({
title: 'Success!!',
message: 'Success!!',
variant: 'success',
}),
);
})
// 失敗ポップアップメッセージ表示
.catch(error => {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error!!',
message: error,
variant: 'error',
}),
);
})
});
})
.catch(error => {
console.log(error)
})
// 最終処理
.finally(() => {
// input fileを初期化
this.template.querySelectorAll('lightning-input').forEach(each => {
each.value = "";
});
// アップロードファイルを初期化
this.file = null;
// 送信ボタンを非アクティブ化
this.isLoaded = false;
});
}
}
apex
public with sharing class csvUploder {
@AuraEnabled
public static void insertCsvData(String jsonData) {
// importデータ格納用変数
List<account> importData = new List<account>();
// 引数のデータをリストで取得
List<object> readData = (List<object>)JSON.deserializeUntyped(jsonData);
System.debug(readData);
// リストをループ
for(Object o : readData) {
Map<string, object=""> m = (Map<string, object="">)o;
// 項目の値を取得
Account a = new Account();
a.Name = (String)m.get('Name');
a.Site = (String)m.get('Site');
a.BillingState= (String)m.get('BillingState');
a.Phone= (String)m.get('Phone');
a.Type = (String)m.get('Type');
importData.add(a);
}
try {
insert importData;
}
catch(DmlException e) {
throw e;
}
}
}
`
上記まんま動く。
CSVの中にカンマがある場合は
apex部分は下記参考に対応できる
`
public class lwcCSVUploaderController {
@AuraEnabled
public static List<account> saveFile(String base64Data) {
String data = JSON.deserializeUntyped(base64Data).toString();
list<account> lstCCToInsert = new list<account>();
list<string> lstCSVLines = data.split('\n');
for(Integer i = 1; i < lstCSVLines.size(); i++){
Account acc = new Account();
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);
}
acc.Name = csvRowData[0];
acc.Site = csvRowData[1];
acc.AccountSource = csvRowData[2];
lstCCToInsert.add(acc);
}
insert lstCCToInsert;
return [Select Id, Name, Site, AccountSource From Account Where CreatedDate>=:Date.TODAY()];
}
}
`
</string,></string,></rows.length>