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('\r\n', '\n');
        content = content.replaceAll('\r', '\n');
        String[] fileLines = content.split('\n');
        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端进行相关解析,但是有大小的限制。篇中有错误地方欢迎指出,有不懂欢迎留言。
Salesforce LWC学习(二十七) File Upload的更多相关文章
- Salesforce LWC学习(二十一) Error浅谈
		
本篇参考:https://developer.salesforce.com/docs/component-library/documentation/en/lwc/data_error https:/ ...
 - Salesforce LWC学习(二十六) 简单知识总结篇三
		
首先本篇感谢长源edward老哥的大力帮助. 背景:我们在前端开发的时候,经常会用到输入框,并且对这个输入框设置 required或者其他的验证,当不满足条件时使用自定义的UI或者使用标准的 inpu ...
 - Salesforce LWC学习(二十五) Jest Test
		
本篇参看: https://trailhead.salesforce.com/content/learn/modules/test-lightning-web-components https://j ...
 - Salesforce LWC学习(二) helloWorld程序在VSCode中的实现
		
上一篇我们简单的描述了一下Salesforce DX的配置以及CLI的简单功能使用,此篇主要简单描述一下LWC如何实现helloWorld以及LWC开发时应该注意的一些规范. 做国内项目的同学直观的感 ...
 - Salesforce LWC学习(二十三) Lightning Message Service 浅谈
		
本篇参考: https://trailhead.salesforce.com/content/learn/superbadges/superbadge_lwc_specialist https://d ...
 - Salesforce LWC学习(二十二) 简单知识总结篇二
		
本篇参看: https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.reactivity_fi ...
 - Salesforce LWC学习(三十七) Promise解决progress-indicator的小问题
		
本篇参考:https://developer.salesforce.com/docs/component-library/bundle/lightning-progress-indicator/exa ...
 - Salesforce LWC学习(二十四) Array.sort 浅谈
		
本篇参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort sal ...
 - Salesforce LWC学习(二十八) 复制内容到系统剪贴板(clipboard)
		
本篇参考: https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipb ...
 
随机推荐
- C# 根据出生年月 计算天数/计算X岁X月X天字符串
			
public class TimeTool { //根据出生年月计算 整数天 private static int GetAgeByBirthdate(DateTime birthdate) { Da ...
 - 兼容低版本IE浏览器的一些心得体会(持续更新)
			
前言: 近期工作中,突然被要求改别人的代码,其中有一项就是兼容IE低版本浏览器,所以优雅降级吧. 我相信兼容低版本IE是许多前端开发的噩梦,尤其是改别人写的代码,更是痛不欲生. 本文将介绍一些本人兼容 ...
 - 关于Chrome浏览器自动同步的问题
			
Chrome浏览器是开发者最喜欢的浏览器,没有之一,那么公司办公和在家办公的话数据需要有一致性,这个时候就用到了浏览器的自动同步的功能 因为网络的问题,谷歌账户很难登录,基本需要VPN翻墙处理之后才能 ...
 - 滑动窗口(Sliding Window)技巧总结
			
什么是滑动窗口(Sliding Window) The Sliding Problem contains a sliding window which is a sub – list that run ...
 - [BUUOJ记录] [极客大挑战 2019]RCE ME
			
前面考察取反或者异或绕过,后面读Flag那里我用脏方法过了,没看出来考察啥 进入题目给出源码: <?php error_reporting(0); if(isset($_GET['code']) ...
 - HTML5 Drag & Drop
			
一定要区分不同事件产生的对象 源元素 属性:draggable = "true" 事件: ondragstart:开始拖拽 ondragend:拖拽结束 目标元素 事件: ondr ...
 - 开发者的福音,LR.NET模块化代码生成器
			
代码生成器,是快速开发平台的核心功能之一,是一种用来帮助缺乏经验或者时间的开发者快速生成规范代码的工具,可以在极大程度上提升开发者的工作效率, 能有效避免重复工作.但稍有经验的开发者都明白,代码生成器 ...
 - map 地图组件
			
地图选择器网址 http://datav.aliyun.com/tools/atlas/#&lat=31.769817845138945&lng=104.29901249999999& ...
 - 使用java爬虫从雪球网下载股票数据
			
雪球网也是采用Ajax方式展示数据,我依然采用开发者工具查看其访问地址和返回数据. 访问使用到的库是jsoup,解析返回的json用的类库是jackson,二者的依赖是: <!-- jsoup ...
 - 20190919-02安装Xshell和CRT远程工具 000 008
			
Linux远程登录及相关工具介绍 Linux一般作为服务器使用,而服务器一般放在机房,你不可能在机房操作你的Linux服务器.这时我们就需要远程登录到Linux服务器来管理维护系统. Linux系统中 ...