How to Preview and Download Files in LWC Using Base64

Introduction

In Salesforce Lightning Web Components (LWC), you might need to display Base64-encoded files such as PDFs, images, or text inside a modal and allow users to download them. This guide will show you how to:

Preview Base64 files inside a modal.
Support multiple file types (PDF, images, and text).
Enable a download button to save the file locally.

1️⃣ Understanding Base64 in LWC

Base64 encoding converts binary data into a text format that can be easily stored or transferred. However, to preview and download the file correctly, we need to convert Base64 back into a Blob.

2️⃣ Creating the LWC Component

📌 Step 1: Create filePreview.html

This file contains:

  • A Show Preview button to open the modal.
  • A modal to display PDF, images, or text files.
  • A Download button to save the file.

filePreview.html

<template>
    <lightning-button label="Show Preview" onclick={handleShowModal}></lightning-button>

    <template if:true={isModalOpen}>
        <section class="slds-modal slds-fade-in-open">
            <div class="slds-modal__container">
                <!-- Modal Header -->
                <header class="slds-modal__header">
                    <button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" 
                        title="Close" onclick={handleCloseModal}>
                        <lightning-icon icon-name="utility:close" alternative-text="Close" size="small"></lightning-icon>
                    </button>
                    <h2 class="slds-text-heading_medium">File Preview</h2>
                </header>

                <!-- Modal Body -->
                <div class="slds-modal__content slds-p-around_medium">
                    <!-- PDF Preview (Using Embed) -->
                    <template if:true={isPdf}>
                        <embed src={previewUrl} type="application/pdf" width="100%" height="500px" />
                    </template>

                    <!-- Image Preview -->
                    <template if:true={isImage}>
                        <img src={previewUrl} alt="Preview Image" style="max-width:100%; max-height:500px;" />
                    </template>

                    <!-- Text Preview -->
                    <template if:true={isText}>
                        <pre>{decodedText}</pre>
                    </template>
                </div>

                <!-- Modal Footer -->
                <footer class="slds-modal__footer">
                       <lightning-button label="Download File" onclick={handleDownload}></lightning-button>
                    <lightning-button label="Close" onclick={handleCloseModal}></lightning-button>
                </footer>
            </div>
        </section>

        <div class="slds-backdrop slds-backdrop_open"></div>
    </template>
</template>

📌 Step 2: Create filePreview.js

This JavaScript file:
✔ Converts Base64 to Blob for correct file handling.
✔ Enables preview and download functionality.

filePreview.js

import { LightningElement, track } from 'lwc';
export default class FilePreview extends LightningElement {
    @track isModalOpen = false;
    @track previewUrl;
    @track decodedText;
    @track isPdf = false;
    @track isImage = false;
    @track isText = false;
    fileType;
    fileName;
    fileTypeCode = 'IMG'; // Add your File Type IMG, PDF , TXT
    base64Data  = ""; // BASE64 text
    
    handleShowModal() {
        let base64String = this.addFileType(this.base64Data);

        if (base64String.startsWith("data:application/pdf")) {
            this.previewUrl = base64String;
            this.isPdf = true;
            this.isImage = false;
            this.isText = false;
            this.fileName = "document.pdf";
            this.fileType = "application/pdf";
        } else if (base64String.startsWith("data:image")) {
            this.previewUrl = base64String;
            this.isPdf = false;
            this.isImage = true;
            this.isText = false;
            this.fileType = "image/png";
            this.fileName = "document.png";
        } else {
            this.decodedText = atob(base64String.split(",")[1]); // Decode Base64
            this.isPdf = false;
            this.isImage = false;
            this.isText = true;
        }

        this.isModalOpen = true;
    }

    handleCloseModal() {
        this.isModalOpen = false;
        this.previewUrl = null;
        this.decodedText = null;
        this.isPdf = false;
        this.isImage = false;
        this.isText = false;
    }

    // Convert Base62 to Base64 (Assuming Base62 is encoding Base64 data)
    addFileType(base62) {
        
        if(this.fileTypeCode == 'IMG')
            return `data:image;base64,${base62}`;
        
        if(this.fileTypeCode == 'PDF')
          return `data:application/pdf;base64,${base62}`;
       
        if(this.fileTypeCode == 'TXT')
          return `data:text/plain;base64,${base62}`;

    }

     handleDownload() {
        if (!this.previewUrl) return;

        // Extract Base64 content
        let base64Data = this.previewUrl.split(",")[1];

        // Convert Base64 to binary data (Blob)
        let byteCharacters = atob(base64Data);
        let byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        let byteArray = new Uint8Array(byteNumbers);
        let blob = new Blob([byteArray], { type: this.fileType });

        // Create Object URL and trigger download
        let link = document.createElement("a");
        link.href = URL.createObjectURL(blob);
        link.download = this.fileName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }
}

Conclusion

With this approach, you can seamlessly preview and download Base64-encoded files in LWC without using an <iframe>. This solution works for PDFs, images, and text files efficiently.

💡 Want more Salesforce LWC tutorials? Keep visiting Apexvine.in for more! 🚀