# pdf-viewer-multi-format-viewer

> PDF viewer that opens multi-format uploads via drop area with progress bar and conversion.

**Framework:** react  **Component:** PdfViewer  **Variant:** multi-format-viewer

## Get this item

**If you are an agent, fetch the JSON.** Source is inlined, so one request is enough and no tooling is required:

```
GET https://ai.syncfusion.com/r/react/js/pdf-viewer-multi-format-viewer.json
```

**Install Package(s)**

```bash
npm install @syncfusion/ej2-react-buttons @syncfusion/ej2-react-inputs @syncfusion/ej2-react-pdfviewer @syncfusion/ej2-react-progressbar
```

**Notes**

- Syncfusion release: 2026 Volume 2 (v34.1.29)
- The Syncfusion package is licensed. The composition in this file is source you own and edit. See https://ai.syncfusion.com/licensing.md

## Source files

### src/components/pdf-viewer-multi-format-viewer/PdfViewer.jsx

```jsx
import * as React from 'react';
import { PdfViewerComponent, Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView, ThumbnailView, Print, TextSelection, TextSearch, Annotation, FormFields, FormDesigner, PageOrganizer, Inject } from '@syncfusion/ej2-react-pdfviewer';
import { createElement, isNullOrUndefined } from '@syncfusion/ej2-base';
import { UploaderComponent } from '@syncfusion/ej2-react-inputs';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { ProgressBarComponent } from '@syncfusion/ej2-react-progressbar';
const SAMPLE_CSS = `
#pdfviewer {
    height: 640px;
}

#linear-pdfviewer {
    width: fit-content;
}

#uploader-pdfviewer {
    display: none;
}

.content-wrapper-pdfviewer {
    border: 1px dashed #c3c3cc;
    position: relative;
    text-align: center;
    padding: 20px 0 10px;
}

}`;

function MultiFormatViewer() {
    React.useEffect(() => {
        rendereComplete();
    }, []);
    let viewer;
    let allowedExtensions;
    let parentElement;
    let dropAreaRef = React.useRef(null);
    let filesData;
    let uploadObj = React.useRef(null);
    let linear = React.useRef(null);
    const [style, setStyle] = React.useState({ color: "" });
    let pdfViewerProgressValue = 0;
    let uploadProgressValue = 0;
    const rendereComplete = () => {
        uploadObj.current.dropArea = dropAreaRef.current;
        document.getElementById('browse').onclick = () => {
            document.getElementsByClassName('e-file-select-wrap')[0].querySelector('button').click();
            return false;
        };
    };
    allowedExtensions = '.doc, .docx, .rtf, .docm, .dotm, .dotx, .dot, .xls, .xlsx, .pptx, .pptm, .potx, .potm .jpeg, .png, .bmp, .pdf, .jpg';
    const onSelect = (args) => {
        linear.current.value == 0;
        linear.current.refresh();
        let extensions = ['doc', 'docx', 'rtf', 'docm', 'dotm', 'dotx', 'dot', 'xls', 'xlsx', 'pptx', 'pptm', 'potx', 'potm', 'jpeg', 'png', 'bmp', 'pdf', 'jpg'];
        let progressBarContainer = document.getElementById("progressBar");
        let progressBar = document.getElementById("linearProgressBar");
        let progressMessage = document.getElementById("uploadedMessage");
        document.getElementById("fileDetails").style.display = "block";
        document.getElementById("FailedMessage").style.display = "none";
        var fileSizeValidation = document.getElementById("fileSizeValidation");
        progressBarContainer.style.display = "block";
        progressBar.style.display = "flex";
        progressMessage.style.display = "none";
        fileSizeValidation.style.display = "none";
        if (!uploadObj.current.element.querySelector('li')) {
            filesData = [];
        }
        if (isNullOrUndefined(uploadObj.current.element.querySelector('.e-upload-files'))) {
            parentElement = createElement('ul', {
                className: 'e-upload-files',
            });
            document.getElementsByClassName('e-upload')[0].appendChild(parentElement);
        }
        var validFiles = args.filesData;
        if (validFiles.length === 0) {
            progressBarContainer.style.display = "block";
            progressBar.style.display = "none";
            progressMessage.style.display = "block";
            args.cancel = true;
            return;
        }
        if (!extensions.includes(validFiles[0].type)) {
            document.getElementById("FailedMessage").style.display = "block";
            document.getElementById("fileDetails").style.display = "none";
            progressBar.style.display = "none";
            progressMessage.style.display = "none";
            document.getElementById('pdfviewer_container').style.display = 'none';
            args.cancel = true;
            return;
        }
        if (validFiles[0].type != "pdf" && validFiles[0].size > 4000000) {
            fileSizeValidation.style.display = "block";
            progressBar.style.display = "none";
            document.getElementById("fileDetails").style.display = "none";
            document.getElementById('pdfviewer_container').style.display = 'none';
            args.cancel = true;
            return;
        }
        document.getElementById("fileName").innerHTML = args.filesData[0].name;
        viewer = document.getElementById('pdfviewer').ej2_instances[0];
        viewer.downloadFileName = args.filesData[0].name;
        viewer.exportAnnotationFileName = args.filesData[0].name;
        let size = document.getElementById("fileSize");
        if ((args.filesData[0].size.toString()).length <= 7) {
            size.innerHTML = ((args.filesData[0].size / 1024).toFixed(1)).toString() + " KB";
        }
        else {
            let kbsize = args.filesData[0].size / 1024;
            size.innerHTML = ((kbsize / 1024).toFixed(1)).toString() + " MB";
        }
        document.getElementById("fileSize");
        formSelectedData(validFiles[0], uploadObj.current);
        filesData = filesData.concat(validFiles);
        const totalProgress = calculateTotalProgress();
        updateProgressBar(totalProgress);
        document.getElementById("progress-status").innerHTML = totalProgress.toString() + "%";
    };
    const formSelectedData = (file, proxy) => {
        var liEle = createElement('li', {
            className: 'e-upload-file-list',
            attrs: {
                'data-file-name': file.name
            },
        });
        readURL(liEle, file);
        proxy.fileList.push(liEle);
    };
    const readURL = (li, args) => {
        var file = args.rawFile;
        var reader = new FileReader();
        var type = args.type;
        reader.addEventListener('load', function () {
            let post = JSON.stringify({
                'data': reader.result,
                'type': type
            });
            const url = "https://document.syncfusion.com/web-services/pdf-viewer/api/pdfviewer/LoadFile";
            let xhr = new XMLHttpRequest();
            xhr.open('Post', url, true);
            xhr.setRequestHeader('Content-type', 'application/json; charset=UTF-8');
            xhr.upload.addEventListener('progress', (event) => {
                if (event.lengthComputable) {
                    let progressValue = Math.round((event.loaded / event.total) * 100);
                    uploadProgressValue = progressValue;
                    const totalProgress = calculateTotalProgress();
                    updateProgressBar(totalProgress);
                    document.getElementById("progress-status").innerHTML = totalProgress.toString() + "%";
                }
            });
            xhr.onreadystatechange = function (event) {
                if (xhr.responseText != "" && xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        viewer = document.getElementById('pdfviewer').ej2_instances[0];
                        viewer.documentPath = '';
                        viewer.documentPath = xhr.responseText;
                        pdfViewerProgressValue = 20;
                        const totalProgress = calculateTotalProgress();
                        updateProgressBar(totalProgress);
                        document.getElementById("progress-status").innerHTML = totalProgress.toString() + "%";
                        document.getElementById('pdfviewer_container').style.display = 'block';
                    }
                    else {
                        console.error('Error:', xhr.statusText);
                    }
                }
            }.bind(this);
            xhr.send(post);
        }, false);
        if (file) {
            reader.readAsDataURL(file);
        }
    };
    const documentLoad = (args) => {
        pdfViewerProgressValue = 100;
        const totalProgress = calculateTotalProgress();
        updateProgressBar(totalProgress);
        document.getElementById("progress-status").innerHTML = totalProgress.toString() + "%";
        setTimeout(() => {
            document.getElementById("linearProgressBar").style.display = "none";
            document.getElementById("uploadedMessage").style.display = "block";
            uploadProgressValue = 0;
            pdfViewerProgressValue = 0;
            linear.current.value = 0;
        }, 1000);
    };
    const calculateTotalProgress = () => {
        const totalProgress = (uploadProgressValue + pdfViewerProgressValue) / 2;
        return totalProgress;
    };
    const updateProgressBar = (progress) => {
        if (linear) {
            linear.current.value = progress;
        }
    };
    const progressLoad = (args) => {
        let selectedTheme = location.hash.split('/')[1];
        selectedTheme = selectedTheme ? selectedTheme : 'Material';
        args.progressBar.theme = (selectedTheme.charAt(0).toUpperCase() +
            selectedTheme.slice(1)).replace(/-dark/i, 'Dark').replace(/contrast/i, 'Contrast');
        if (args.progressBar.theme === 'HighContrast' || args.progressBar.theme === 'Bootstrap5Dark' || args.progressBar.theme === 'BootstrapDark' || args.progressBar.theme === 'FabricDark'
            || args.progressBar.theme === 'TailwindDark' || args.progressBar.theme === 'MaterialDark' || args.progressBar.theme === 'FluentDark' || args.progressBar.theme === 'Material3Dark') {
            setStyle({ color: "White" });
        }
    };
    const ajaxRequestSuccess = (args) => {
        if (args.action === "Load") {
            pdfViewerProgressValue = 50;
            const totalProgress = calculateTotalProgress();
            updateProgressBar(totalProgress);
            document.getElementById("progress-status").innerHTML = totalProgress.toString() + "%";
        }
    };
    return (<div>
    <div className='control-section'>
        <style>{SAMPLE_CSS}</style>
      <div className='content-wrapper-pdfviewer' ref={dropAreaRef} style={{ 'textAlign': 'center', 'marginBottom': '15px' }}>
        <div style={{ 'height': 'auto', 'overflow': 'auto', marginBottom: '15px' }}>
          <ButtonComponent id='browse'>Browse...</ButtonComponent>
          <div>
            <p style={{ 'margin': '10px' }}>OR</p>
            <span id="drop">Drop files (Word, Excel, PowerPoint, Image, PDF)</span>
          </div>
        </div>
        <div id="progressBar" style={{ display: 'none' }}>
          <div id='fileDetails'>
            <p id="fileName"></p>
            <p id="fileSize"></p>
          </div>
          <div id='linearProgressBar' style={{ justifyContent: 'center', display: 'none' }}>
            <ProgressBarComponent id="linear-pdfviewer" ref={linear} type='Linear' width='250' height='60' animation={{ enable: false, duration: 2000, delay: 0 }} value={0} load={progressLoad.bind(this)}>
            </ProgressBarComponent>
            <span id='progress-status' style={{ padding: '18px 5px' }}></span>
          </div>
          <div id="uploadedMessage" style={{ display: 'none', marginTop: '10px' }}>
            <p style={{ color: 'rgb(110, 218, 110)' }}>File successfully uploaded...</p>
          </div>
          <div id="FailedMessage" style={{ display: 'none', marginTop: '10px' }}>
            <p style={{ color: 'red' }}>File not Supported!</p>
          </div>
          <div id="fileSizeValidation" style={{ display: 'none', marginTop: '10px' }}>
            <p style={{ color: 'rgb(203, 38, 38)' }}>Maximum file size is (4.0 MB) for this operation...</p>
          </div>
        </div>
        <div id="uploader-pdfviewer">
          <UploaderComponent id='fileUpload' type='file' ref={uploadObj} multiple={false} selected={onSelect} allowedExtensions={allowedExtensions}></UploaderComponent>
        </div>
      </div>
      <div id='pdfviewer_container' style={{ display: 'none' }}>
        {/* Render the PDF Viewer */}
        <PdfViewerComponent id="pdfviewer" className="e-pv-multi-format-pdfviewer" resourceUrl="https://cdn.syncfusion.com/ej2/23.2.6/dist/ej2-pdfviewer-lib" toolbarSettings={{
            showTooltip: true, toolbarItems: [
                "DownloadOption",
                "UndoRedoTool",
                "PageNavigationTool",
                "MagnificationTool",
                "PanTool",
                "SelectionTool",
                "CommentTool",
                "SubmitForm",
                "SearchOption",
                "AnnotationEditTool",
                "FormDesignerEditTool",
                "PrintOption"
            ]
        }} documentLoad={documentLoad} ajaxRequestSuccess={ajaxRequestSuccess} zoomMode="FitToPage" style={{ 'height': '640px' }}>
          <Inject services={[Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView, ThumbnailView, Print, TextSelection, TextSearch, Annotation, FormFields, FormDesigner, PageOrganizer]}/>
        </PdfViewerComponent>
      </div>
    </div>
  </div>);
}
export default MultiFormatViewer;
```
