見出し画像

[Salesforce]画像をリサイズしてフローからアップロード

画像をリサイズしてSalesforceのファイルにアップロードしたい。
そんなニーズがあったので、調べてみた。(Chat GPTに聞いてみた)

LWCでファイルをリサイズしてアップロードするプログラムを書いてくれた。
その後色々修正して、以下になった。


html
アップロードするとプレビューが表示される易しい仕様でコード書いてくれた

<!-- myUploader.html -->
<template>
    <label>
        <input type="file" onchange={handleImageUpload} accept="image/*"/>
    </label>
    <br /><br />
    <lightning-button label="アップロード" onclick={uploadToSalesforce} disabled={disableUpload}></lightning-button>
    <br /><br />
    <div>
        <!-- プレビュー画像の表示 -->
        <img if:true={uploadedImage} src={uploadedImage} alt="Image Preview" width={maxWidth} height={maxHeight}/>
    </div>
</template>

js
ファイルのアップロードが終わったら、アップロードボタンを有効化する
アップロード後に成功・失敗のメーセージ表示

import { LightningElement, api, track } from 'lwc';
import saveFile from '@salesforce/apex/ImageUploadController.saveFile';
import { ShowToastEvent } from 'lightning/platformShowToastEvent'; // トーストイベントをインポート

export default class MyUploader extends LightningElement {
    @api maxWidth;
    @api maxHeight;
    @api recordId;
    @track uploadedImage;
    disableUpload = true;
    filename = "";

    handleImageUpload(event) {
        const file = event.target.files[0];
        if (!file) return;
        this.filename = file.name;
        this.filename = this.filename.substring(0, this.filename.lastIndexOf('.')) + '.jpg';
        
        // Image resizing (using HTML5 Canvas)
        const reader = new FileReader();
        reader.onload = (fileLoadedEvent) => {
            const img = new Image();
            img.src = fileLoadedEvent.target.result;
            img.onload = () => {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                
                let width = img.width;
                let height = img.height;
                
                if (width > height) {
                    if (width > this.maxWidth) {
                        height *= this.maxWidth / width;
                        width = this.maxWidth;
                    }
                } else {
                    if (height > this.maxHeight) {
                        width *= this.maxHeight / height;
                        height = this.maxHeight;
                    }
                }
                
                canvas.width = width;
                canvas.height = height;
                ctx.drawImage(img, 0, 0, width, height);
                
                // Convert resized image back to base64 format
                this.uploadedImage = canvas.toDataURL('image/jpeg');
                this.disableUpload = false;
            };
        };
        reader.readAsDataURL(file);
    }

    uploadToSalesforce() {
        saveFile({ base64Data: this.uploadedImage.split(',')[1], fileName: this.filename, recordId: this.recordId })
        .then(result => {
            // ここで成功時のトーストメッセージを表示
            this.dispatchEvent(
                new ShowToastEvent({
                    title: '成功',
                    message: 'ファイルのアップロードに成功しました',
                    variant: 'success'
                })
            );
        })
        .catch(error => {
            // エラー時のトーストメッセージも表示可能
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'エラー',
                    message: 'ファイルのアップロードに失敗しました',
                    variant: 'error'
                })
            );
        });
        this.disableUpload = true;
    }
}

メタデータ
フローから呼び出せるように以下を追加しましょう
<target>lightning__FlowScreen</target>

<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
	<apiVersion>57.0</apiVersion>
	<isExposed>true</isExposed>
	<targets>
		<target>lightning__HomePage</target>
		<target>lightning__RecordPage</target>
		<target>lightning__AppPage</target>
		<target>lightning__FlowScreen</target>
	</targets>
	<targetConfigs>
		<targetConfig targets="lightning__AppPage,lightning__RecordPage,lightning__FlowScreen,lightning__HomePage">
			<property name="maxWidth" label="Max Width" type="Integer" default="800" description="Maximum width in pixels" min="10" max="2000" />
			<property name="maxHeight" label="Max Height" type="Integer" default="600" description="Maximum height in pixels" min="10" max="2000" />
			<property name="recordId" label="recordId" type="String" description="" />
		</targetConfig>
	</targetConfigs>
</LightningComponentBundle>

ファイルを指定したrecordIdに紐付けて保存するApexクラス

public class ImageUploadController {
    @AuraEnabled
    public static String saveFile(String base64Data, String fileName, String recordId) {
        ContentVersion cv = new ContentVersion();
        cv.VersionData = EncodingUtil.base64Decode(base64Data);
        cv.Title = fileName;
        cv.PathOnClient = '/' + fileName;
        insert cv;

        // Create the ContentDocumentLink and attach the file to the record
        if(String.isBlank(recordId)) {
            return null;
        }
        ContentDocumentLink cl = new ContentDocumentLink();
        cl.ContentDocumentId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId;
        cl.LinkedEntityId = recordId;
        insert cl;

        return cv.Id;
    }
}

ローコード/ノーコード開発の次は、AIにコード書いてくれる時代が来ましたね。

この記事が気に入ったらサポートをしてみませんか?