0

I have a base64 string as follow:

Base64 String

I would like this base64 string ( or any base64 String) to be turned into a pdf, then downloaded in React Native. I am using expo for this. I have looked all over the place and could not find an answer.

1 Answer 1

2

If you just want to show the pdf in react-native.The react-native-pdf package can do the job.Use a source obj like this.

const source = {uri:"data:application/pdf;base64,JVBERi0xLjcKJc..."};

If you want to download base64 to pdf file, it's also simple.

var RNFetchBlob = require('react-native-fetch-blob').default;

const DocumentDir = RNFetchBlob.fs.dirs.DocumentDir;
let pdfLocation = DocumentDir + '/' + 'test.pdf';
RNFetchBlob.fs.writeFile(pdfLocation, pdf_base64Str, 'base64');
export async function downloadFile(url){
    let binary = await getPdfBinary(url);
    const base64Str = base64_encode(binary);
    const DocumentDir = RNFetchBlob.fs.dirs.DocumentDir;
    let pdfLocation = DocumentDir + '/' + 'test.pdf';
    RNFetchBlob.fs.writeFile(pdfLocation, base64Str, 'base64');
}

I'm sorry I didn't notice that you are using expo. As I have never written codes about the file system part in the expo. After a lot try, it finally works. But only for android. I think you may hope the pdf file should be saved to an external storage path so the user can see it in the file app. But for ios, It is hard to reach that. A possible way is to use the share dialog. If you just want to save the pdf file to the document folder in the app(not see by the user), FileSystem.writeAsStringAsync is enough!Hope this is helpful!

import * as  FileSystem from 'expo-file-system';
import { Platform } from 'react-native';

async function getPdfBinary(url) {
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", url, true);
        xhr.responseType = "arraybuffer"; // get the binary 
        xhr.setRequestHeader('content-type', 'application/json');
        xhr.onload = function (event) {
            var arrayBuffer = xhr.response;
            var byteArray = new Uint8Array(arrayBuffer);
            var len = byteArray.byteLength;
            var binary = ""
            for (var i = 0; i < len; i++) {
                binary += String.fromCharCode(byteArray[i]);
            }
            resolve(binary);
        }
        xhr.send();
    })
}

function base64_encode(str) {
    var c1, c2, c3;
    var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var i = 0,
        len = str.length,
        string = '';

    while (i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if (i == len) {
            string += base64EncodeChars.charAt(c1 >> 2);
            string += base64EncodeChars.charAt((c1 & 0x3) << 4);
            string += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if (i == len) {
            string += base64EncodeChars.charAt(c1 >> 2);
            string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            string += base64EncodeChars.charAt((c2 & 0xF) << 2);
            string += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        string += base64EncodeChars.charAt(c1 >> 2);
        string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
        string += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
        string += base64EncodeChars.charAt(c3 & 0x3F)
    }
    return string
}


const downloadForAos = async (pdfBase64Str) => {
    const folder = FileSystem.StorageAccessFramework.getUriForDirectoryInRoot("test");
    const permissions = await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync(folder);
    if (!permissions.granted) return;

    let filePath = await FileSystem.StorageAccessFramework.createFileAsync(permissions.directoryUri, "test.pdf", "application/pdf");
    // let filePath = "content://com.android.externalstorage.documents/tree/primary%3Atest/document/primary%3Atest%2Ftest.txt";
    console.log(pdfBase64Str, "====");
    try {
        await FileSystem.StorageAccessFramework.writeAsStringAsync(filePath, pdfBase64Str, { encoding: FileSystem.EncodingType.Base64 });
        alert("download success!")
    } catch (err) {
        console.log(err);
    }
}

const downloadForIos = async () => {
    alert("try do it by yourself")
}

export async function downloadPdf(url) {
    let binary = await getPdfBinary(url);
    console.log(binary, "=====")
    const base64Str = base64_encode(binary);
    if (Platform.OS === "ios") {
        downloadForIos(base64Str);
    } else {
        downloadForAos(base64Str);
    }
}

Sign up to request clarification or add additional context in comments.

14 Comments

Your image is not base64, you should encode it to base64. If you have the raw file, I think it should be more easy.
My image is a string. Do you know what type it is then?
I know. If you open a pdf file with a text editor, you will see strings like this. Where you get this?
I got this from my backend.
No. Maybe you can do this in your backend. In python, read the file and then base64 encode it. In react-native, you get the base64 string directly!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.