zoukankan      html  css  js  c++  java
  • Salesforce LWC学习(二十七) File Upload

    本篇参考:

    https://developer.salesforce.com/docs/component-library/bundle/lightning-file-upload/documentation

    https://developer.salesforce.com/docs/component-library/bundle/lightning-input/specification

    在salesforce中,上传附件是一个经常做的操作,在标准的功能基础上,lwc自然也封装了自定义的实现。我们有上传文档需求的时候,通常有以下的几点需求和考虑:

    • 是否支持多文件上传
    • 是否支持大文件上传
    • 是否可以限制上传文件的类型
    • 是否可以对文件进行解析(目前demo中仅限csv)

    根据上述的几点需求和考虑,本篇采用两种方式来实现文件上传操作来契合这些要求。

    一. lightning-file-upload实现大文件上传

    使用此种方式的优缺点:

    优点:

    • 支持大文件上传;
    • 可以限制上传文件类型;
    • 支持多文件上传;

    缺点:

    • 不支持文件解析。

    demo如下:

    fileUploadSample.html:上面的链接中给出了 lightning-file-upload的使用方法,通过设置 label展示上传组件的label名称,record-id用来指定当前上传的这些文件将作为 note & Attachment绑定在哪条数据下,accept指定了限制的格式, uploadfinished是组件自身封装的事件,用于上传完成之后执行的事件,multiple设置 true/false来指定当前的组件是否支持多个文件上传。

    <template>
        <lightning-card title="File Upload">
            <lightning-file-upload
                label="上传附件"
                name="fileUploader"
                accept={acceptedFormats}
                record-id={recordId}
                onuploadfinished={handleUploadFinishedEvent}
                multiple>
        </lightning-file-upload>
        </lightning-card>
    </template>

    fileUploadSample.js:方法用来指定当前只接受csv,上传成功以后toast信息展示相关的上传文件名称。

    import { LightningElement, api } from 'lwc';
    import {ShowToastEvent} from 'lightning/platformShowToastEvent';
    export default class FileUploadSample extends LightningElement {
        @api recordId;
    
        get acceptedFormats() {
            return ['.csv'];
        }
        handleUploadFinishedEvent(event) {
            const uploadedFiles = event.detail.files;
            let uploadedFilesName = uploadedFiles.map(element => element.name);
            let uploadedFileNamesStr = uploadedFilesName.join(',');
    
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Success',
                    message: uploadedFiles.length + ' Files uploaded Successfully: ' + uploadedFileNamesStr,
                    variant: 'success',
                }),
            );
        }
    }

    结果展示:

    1. 页面初始化样子

     2. 上传两个文件的UI效果,点击done即调用 onuploadfinished这个对应的handler

     3. 展示toast消息

     4. 上传的文件正常的挂到了 Notes & Attachment上面

     二. lightning-input 实现csv文件上传以及解析

    此种方法优点

    • 支持上传文件解析

    此种方法缺点

    • 对文件上传大小有严格限制

    demo如下:

     FileUploadUsingInputController:用于存储文件以及对csv内容进行解析,需要注意的是,当前方法只针对单个csv的单个sheet页进行解析。

    public with sharing class FileUploadUsingInputController {
        @AuraEnabled
        public static String saveFile(Id recordId, String fileName, String base64Data) {
            base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
            Blob contentBlob = EncodingUtil.base64Decode(base64Data);
            String content = bitToString(contentBlob, 'UTF-8');
            content = content.replaceAll('
    ', '
    ');
            content = content.replaceAll('
    ', '
    ');
            String[] fileLines = content.split('
    ');
            System.debug('*** ' + JSON.serialize(fileLines));
            for(Integer i = 1; i < fileLines.size(); i++) {
                //TODO 遍历操作
                system.debug('execute');
            }
    
            // inserting file
            ContentVersion cv = new ContentVersion();
            cv.Title = fileName;
            cv.PathOnClient = '/' + fileName;
            cv.FirstPublishLocationId = recordId;
            cv.VersionData = EncodingUtil.base64Decode(base64Data);
            cv.IsMajorVersion = true;
            Insert cv;
            return 'successfully';
        }
    
        public static String bitToString(Blob input, String inCharset){
            //转换成16进制
            String hex = EncodingUtil.convertToHex(input);
            //一个String类型两个字节 32位(bit),则一个String长度应该为两个16进制的长度,所以此处向右平移一个单位,即除以2
            //向右平移一个单位在正数情况下等同于除以2,负数情况下不等
            //eg 9  00001001  >>1 00000100   结果为4
            final Integer bytesCount = hex.length() >> 1;
            //声明String数组,长度为16进制转换成字符串的长度
            String[] bytes = new String[bytesCount];
            for(Integer i = 0; i < bytesCount; ++i) {
                //将相邻两位的16进制字符串放在一个String中
                bytes[i] =  hex.mid(i << 1, 2);
            }
            //解码成指定charset的字符串
            return EncodingUtil.urlDecode('%' + String.join(bytes, '%'), inCharset);
        }
    }

    fileUploadUsingInput.html:展示上传组件以及button

    <template>
        <lightning-card title="File Upload Using Input">
            <lightning-layout multiple-rows="true">
                <lightning-layout-item size="12">
                    <lightning-input label="" name="file uploader" onchange={handleFilesChange} type="file" accept={acceptedType}></lightning-input><br/>
                    <div class="slds-text-body_small">{fileName}
                    </div>
                </lightning-layout-item>
                <lightning-layout-item>
                    <lightning-button label={UploadFile} onclick={handleSave} variant="brand"></lightning-button>
                </lightning-layout-item>
            </lightning-layout>
            <template if:true={showLoadingSpinner}>
                <lightning-spinner alternative-text="Uploading now"></lightning-spinner>
            </template>
        </lightning-card>
    </template>

    fileUploadUsingInput.js:因为用string存储,所以对文件大小有字节的限制。

    import { LightningElement, track, api } from 'lwc';
    import saveFile from '@salesforce/apex/FileUploadUsingInputController.saveFile';
    import {ShowToastEvent} from 'lightning/platformShowToastEvent';
    
    export default class FileUploadUsingInput extends LightningElement {
        @api recordId;
        @track fileName = '';
        @track UploadFile = 'Upload File';
        @track showLoadingSpinner = false;
        filesUploaded = [];
        file;
        fileContents;
        fileReader;
        content;
        MAX_FILE_SIZE = 1500000;
    
        get acceptedType() {
            return ['.csv'];
        }
    
        handleFilesChange(event) {
            if(event.target.files.length > 0) {
                this.filesUploaded = event.target.files;
                this.fileName = event.target.files[0].name;
            }
        }
    
        handleSave() {
            if(this.filesUploaded.length > 0) {
                this.file = this.filesUploaded[0];
                if (this.file.size > this.MAX_FILE_SIZE) {
                    window.console.log('文件过大');
                    return ;
                }
                this.showLoadingSpinner = true;
                this.fileReader= new FileReader();
    
                this.fileReader.onloadend = (() => {
                    this.fileContents = this.fileReader.result;
                    let base64 = 'base64,';
                    this.content = this.fileContents.indexOf(base64) + base64.length;
                    this.fileContents = this.fileContents.substring(this.content);
                    this.saveToFile();
                });
                this.fileReader.readAsDataURL(this.file);
            }
            else {
                this.fileName = '选择一个csv文件上传';
            }
        }
    
    
        saveToFile() {
            saveFile({ recordId: this.recordId, fileName: this.file.name, base64Data: encodeURIComponent(this.fileContents)})
            .then(result => {
                this.isTrue = true;
                this.showLoadingSpinner = false;
    
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Success!!',
                        message: this.fileName + ' - 上传成功',
                        variant: 'success',
                    }),
                );
    
            })
            .catch(error => {
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: '上传失败',
                        message: error.message,
                        variant: 'error',
                    }),
                );
            });
        }
    }

    结果展示:

    1. csv中做以下的数据

    2. UI效果

     

     3. debug log中打印出来的内容

    4. 格式化以后的效果 ,我们可以对数组进行二次操作,通过逗号进行分割就可以获取每一个cell对应的值,通常我们获取数据中的for循环 index为1,即跳过首行标题行。

     总结:篇中主要讲述了关于lwc中文件上传以及文件解析的简单操作。第一种方式适合大文件上传,可自定制化不强但功能强悍。第二种方式可以对数据在apex端进行相关解析,但是有大小的限制。篇中有错误地方欢迎指出,有不懂欢迎留言。

  • 相关阅读:
    python2.7下同步华为云照片的爬虫程序实现
    python 下字符串格式时间比较
    C# Socket通信 小案例
    win 10 安装 mysql解压版 步骤
    Android 连接 SQL Server (jtds方式)——下
    Android 连接 SQL Server (jtds方式)——上
    Android 项目建立步骤
    ubuntu 配置android开发环境
    ubuntu 安装eclipse
    ubuntu 配置Java jdk
  • 原文地址:https://www.cnblogs.com/zero-zyq/p/13749103.html
Copyright © 2011-2022 走看看