VisualforceにLWCでのファイルUP方法


1.目的

Salesforce Lightningモード下にLWCでのファイルをアップロードするには<lightning-file-upload>コンポネントを使って、ファイルをアップロードできますが、Salesforce Classicモード下にLightningOut中のLWCの<lightning-file-upload>コンポネントは使えなくなりましたので、今回ClassicモードでLWCでのファイルをアップロードする方法を共有します。

2.前提

LWC用のforcetk-lwc.jsを静的リソースにアップロードする

3.ソース構成図

force-app
   └─main
       └─default
           ├─aura
           │  └─LWCContainer
           │
           ├─classes
           │   ├─CommonHandler.cls
           │   └─CommonHandler.cls-meta.xml
           ├─lwc
           │  └─lightningOutFileUpload
           │
           ├─pages
               ├─LightningOutFileUpload.page
               └─LightningOutFileUpload.page-meta.xml
Aura:LWCContainer

LWCContainer.app
<aura:application access="GLOBAL" extends="ltng:outApp">
</aura:application>
LWCContainer.app-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<AuraDefinitionBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <description>A Lightning Application Bundle</description>
</AuraDefinitionBundle>
LWCContainerController.js
({
    myAction : function(component, event, helper) {

    }
})
class:CommonHandler

CommonHandler.cls
public with sharing class CommonHandler {


    /**
     *セッションIdを取得
     */
    @AuraEnabled
    public static String getSessionId() {
        try{
            return UserInfo.getSessionId();
        } catch (Exception e) {
            throw new AuraHandledException(e.getMessage());
        }
    }
}
CommonHandler.cls-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
lwc:lightningOutFileUpload

lightningOutFileUpload.html
<template>
    <lightning-input type="file" variant="label-hidden" onchange={handleUpload}
        required={required} message-when-value-missing="添付ファイルを選択してください。">
    </lightning-input>
</template>
lightningOutFileUpload.js
import { LightningElement } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import forcetk_lwc from '@salesforce/resourceUrl/forcetk_lwc';
import getSessionId from '@salesforce/apex/CommonHandler.getSessionId';
export default class LightningOutFileUpload extends LightningElement {


    /**
     * ファイルアップロード
     * @param {*} event 
     */
    handleUpload(event) {
        let input = event.target;
        if (input.files.length > 0) {
            let file = input.files[0];
            this.client.createBlob('ContentVersion', {
                Origin: 'H', // 'H' for Chatter File, 'C' for Content Document
                PathOnClient: file.name
            }, file.name, 'VersionData', file, (response) => {
                console.log(response);
            }, (request, status, response) => {
                console.log(status);
            });
        }
    }

    /**
     * forcetk_lwcロード
     */
    renderedCallback() {
        if (this.jsinit)
            return;
        this.jsinit = true;
        Promise.all([
                loadScript(this, forcetk_lwc),
            ])
            .then(async () => {
                this.client = new forcetk.Client();
                let sessionId = await getSessionId();
                this.client.setSessionToken(sessionId);
            })
            .catch(error => {
                showToast(this, 'JSライブラリロードに失敗しました', error.message, 'error')
            });
    }
}
lightningOutFileUpload.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>
page:LightningOutFileUpload

LightningOutFileUpload.page
<apex:page standardStylesheets="false" sidebar="false" applyBodyTag="false" docType="html-5.0">
    <!-- lightning Design System -->
    <apex:includeLightning />
    <div id="lwc-container"></div>
    <script>
        $Lightning.use("c:LWCContainer", function () {//AuraAppContainer
            $Lightning.createComponent("c:lightningOutFileUpload",//LWCコンポネント
                {},//lwcコンポネントに渡すパラメータ
                "lwc-container",//divのid
                function (cmp) {//コールバック関数
                    console.log('Load Success:' + cmp);
                }
            );
        });
    </script>
</apex:page>
LightningOutFileUpload.page-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata"> 
    <apiVersion>52.0</apiVersion>
    <label>LightningOutFileUpload</label>
</ApexPage>

4.Salesforce側動作確認

➀Salesforce側Visualforce タブを作成

➁タブを開いて、ファイルをアップロードする

➂アップロードしたファイル確認

5.参考

forcetk-lwc.js:https://github.com/MADAOU/Force.com-JavaScript-REST-Toolkit/blob/master/forcetk-lwc.js