こんにちは、アンダーソンです。
ここ最近ファイルアップロードの仕組みを作ることがあったので
まとめておこうと思います。
Contents
標準でもコンポーネントがある
LWCでは標準でファイルアップロードのコンポーネントが用意されています。
<lightning-file-upload
label="Attach receipt"
name="fileUploader"
accept=".csv,.doc,.xsl,.pdf"
record-id="XXXXXXXX98766"
onuploadfinished={handleUploadFinished}
multiple>
</lightning-file-upload>
これが標準の基本形になります。
record-idには対象のレコードIDが入るような感じです。
レコードページとかに配置して@api recordIdで対象のレコードにファイルをアップする流れです。
今回はカスタムで作成
カスタムの場合lightning-inputを使ってtypeをfile指定します。
<lightning-input label="カスタムファイルアップ" accept={acceptedFormats} name="file uploader" onchange={handleFilesChange} type="file" multiple></lightning-input>
JavaScriptの方ではあらかじめファイルを指定しておきます。
get acceptedFormats() {
return ['.pdf', '.png'];
}
次にonchangeを押した際にアップされたファイルを読み込ませておきます。
handleFilesChange(event){
if(event.target.files.length > 0) {
this.filesUploaded = event.target.files
this.fileNames = event.target.files[0].name
}
}
次にボタンを準備しておき、ボタンを押した際にファイルリーダーを起動させて読み込ませます。
saveFile(){
const reader = new FileReader();
reader.onload = function() {
fileContent = reader.result;
var base64Mark = 'base64,';
var dataStart = fileContent.indexOf(base64Mark) + base64Mark.length;
fileContent = fileContent.substring(dataStart);
this.saveFileApex();
}
reader.readAsDataURL(this.filesUploaded[0])
}
saveFileApex(){
savefiles({recordId:this.recordId,base64Data:encodeURIComponent(this.fileContents),fileName:this.fileNames})
.then(() => {
alert('成功')
})
.catch(error => console.error(error))
}
呼び出すApexはこんな感じ
@AuraEnabled
public static void savefiles(String recordId,String base64Data, String fileName){
base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
ContentVersion cv = new ContentVersion(
Title = fileName,
VersionData = EncodingUtil.base64Decode(base64Data),
PathOnClient = '/' + fileName,
FirstPublishLocationId = recordId
);
insert cv;
}

アップしてデータをみてみると、、

うまくアップできました。
背景
なぜ標準を使わなかったのかなんですが、今回サイト経由でファイルをアップしてもらう必要があり、そこでこの流れを使うことになりました。
海外では結構やってる人いるみたいですが日本語での解説がほとんど見つからなかったので参考にしていただけるとありがたいです!