本篇參考:html
https://developer.salesforce.com/docs/component-library/bundle/lightning-file-upload/documentationapi
https://developer.salesforce.com/docs/component-library/bundle/lightning-input/specification數組
在salesforce中,上傳附件是一個常常作的操做,在標準的功能基礎上,lwc天然也封裝了自定義的實現。咱們有上傳文檔需求的時候,一般有如下的幾點需求和考慮:this
根據上述的幾點需求和考慮,本篇採用兩種方式來實現文件上傳操做來契合這些要求。url
一. lightning-file-upload實現大文件上傳spa
使用此種方式的優缺點:debug
優勢:3d
缺點:code
demo以下:component
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端進行相關解析,可是有大小的限制。篇中有錯誤地方歡迎指出,有不懂歡迎留言。