1
    function openNewWindow(strPreviewId) {
        let newWindowViewer = window.open("");
        var index = mapPreviewIdWithFile[strPreviewId].indexOf('base64,');
        var attachBody = mapPreviewIdWithFile[strPreviewId].substring(index + 7);
        var attachmentMimeType = mapPreviewIdWithFile[strPreviewId].substring(0, index + 7);
        newWindowViewer.document.write("<iframe width='100%' height='100%' src='" + attachmentMimeType + " " + encodeURI(attachBody) + "'></iframe>");

    }

finally the iframe gets created like below:

<iframe width="100%" height="100%" src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAA9AAAALaCAYAAADZQrs6AAAAAXNSR0IArs4..."></iframe>

For files like more than 10MB the attachBody changes to 26 MB, thus it fails to render in the new window. Is there any other library or workaorund which handles large files.

UPDATE

I was trying with canvas, but with canvas the full inage is bnot being shown, only a part is being shown.

        if (attachmentMimeType.indexOf('bmp') > -1 || attachmentMimeType.indexOf('gif') > -1 || attachmentMimeType.indexOf('jpeg') > -1 ||
            attachmentMimeType.indexOf('jpg') > -1 || attachmentMimeType.indexOf('pdf') > -1 || attachmentMimeType.indexOf('png') > -1) {
            newWindowViewer.document.write('<canvas id="c"></canvas>');
            var canvas = newWindowViewer.document.getElementById("c");
            var ctx = canvas.getContext("2d");

            var image = new Image();
            image.onload = function() {
                ctx.drawImage(image, 0, 0, image.height, image.width);
            };
            image.src = attachmentMimeType + " " + encodeURI(attachBody);
        } else {
            newWindowViewer.document.write("<iframe width='100%' height='100%' src='" + attachmentMimeType + " " + encodeURI(attachBody) + "'></iframe>");
        }
Nagendra Singh
  • 153
  • 3
  • 11

1 Answers1

5

The issue which you are facing is most probably because of the character length limit which is set for your brower. URLs over 2,000 characters will not work in the most popular web browsers. This SO answer explains it very well.

Alternatively you can try using IMG instead of IFRAME.

let attachBody = ""; // Add base64 string
let newWindowViewer = window.open("");
newWindowViewer.document.write("<img src=\""+ attachBody +"\" >");

Working demo fiddle here. Which is having a base64 encoded file(5.7M) opening properly in a new window.

Update 1

For pdf file you try by injecting blob data in a script tag. A sample script below.

printPreview = (data, type = 'application/pdf') => {
    let blob = null;
    blob = this.b64toBlob(data, type);
    const blobURL = URL.createObjectURL(blob);
    const newWindowViewer = window.open(blobURL);
    const theDoc = newWindowViewer.document;
    const theScript = theDoc.createElement('script');
    function injectThis() {
        window.print();
    }
    theScript.innerHTML = `window.onload = ${injectThis.toString()};`;
    theDoc.body.appendChild(theScript);
};

b64toBlob = (content, contentType) => {
    contentType = contentType || '';
    const sliceSize = 512;
     // method which converts base64 to binary
    const byteCharacters = window.atob(content); 

    const byteArrays = [];
    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        const slice = byteCharacters.slice(offset, offset + sliceSize);
        const byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
    }
    const blob = new Blob(byteArrays, {
        type: contentType
    }); // statement which creates the blob
    return blob;
};

However, I've not tested it.

James
  • 2,874
  • 4
  • 30
  • 55