Base64 String to Pdf Download

Save base64 string as PDF at client side with JavaScript

You can create an anchor like the one showed below to download the base64 pdf:

<a download=pdfTitle href=pdfData title='Download pdf document' />

where pdfData is your base64 encoded pdf like "data:application/pdf;base64,JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nO1cyY4ktxG911fUWUC3kjsTaBTQ1Ytg32QN4IPgk23JMDQ2LB/0+2YsZAQzmZk1PSPIEB..."

android - download base64 encoded pdf file and open it

Found a thread online and solved it this way: https://www.py4u.net/discuss/614761

Add provider_paths.xml to xml resource folder

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>

In your manifest add a FileProvider:

 <application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>

Prepare to download files to any directory your app owns, such as getFilesDir(), getExternalFilesDir(), getCacheDir() or getExternalCacheDir().

val privateDir = context.getFilesDir()

Download file taking its progress into account (DIY):

val downloadedFile = myFancyMethodToDownloadToAnyDir(url, privateDir, fileName)

Copy it to Downloads folder:

private val DOWNLOAD_DIR = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)

val finalUri : Uri? = copyFileToDownloads(context, downloadedFile)

fun copyFileToDownloads(context: Context, downloadedFile: File): Uri? {
val resolver = context.contentResolver
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, getName(downloadedFile))
put(MediaStore.MediaColumns.MIME_TYPE, getMimeType(downloadedFile))
put(MediaStore.MediaColumns.SIZE, getFileSize(downloadedFile))
}
resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
} else {
val authority = "${context.packageName}.provider"
val destinyFile = File(DOWNLOAD_DIR, getName(downloadedFile))
FileProvider.getUriForFile(context, authority, destinyFile)
}?.also { downloadedUri ->
resolver.openOutputStream(downloadedUri).use { outputStream ->
val brr = ByteArray(1024)
var len: Int
val bufferedInputStream = BufferedInputStream(FileInputStream(downloadedFile.absoluteFile))
while ((bufferedInputStream.read(brr, 0, brr.size).also { len = it }) != -1) {
outputStream?.write(brr, 0, len)
}
outputStream?.flush()
bufferedInputStream.close()
}
}

Once in download folder you can open file from app like this:

val authority = "${context.packageName}.provider"
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(finalUri, getMimeTypeForUri(finalUri))
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)
} else {
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
}
try {
context.startActivity(Intent.createChooser(intent, chooseAppToOpenWith))
} catch (e: Exception) {
Toast.makeText(context, "Error opening file", Toast.LENGTH_LONG).show()
}

//Kitkat or above
fun getMimeTypeForUri(context: Context, finalUri: Uri) : String =
DocumentFile.fromSingleUri(context, finalUri)?.type ?: "application/octet-stream"

//Just in case this is for Android 4.3 or below
fun getMimeTypeForFile(finalFile: File) : String =
DocumentFile.fromFile(it)?.type ?: "application/octet-stream"

how to download base64 string as pdf in IE version 11 & same for mozilla firefox

You can check following code it's working for IE 11 and other browsers.

 function downloadFile(pdfBase64, fileName) {
// IE doesn't allow using a blob object directly as link href
// instead it is necessary to use msSaveOrOpenBlob
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
var byteCharacters = atob(pdfBase64);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var blob = new Blob([byteArray], { type: 'application/pdf' });
window.navigator.msSaveOrOpenBlob(blob, fileName);
return;
}

// For Other Browsers
const linkSource = 'data:application/pdf;base64,' + pdfBase64;
const link = document.createElement('a');
link.href = linkSource;
link.download = fileName;
document.body.appendChild(link);
link.click();
link.remove();

window.addEventListener("focus", function () {
URL.revokeObjectURL(link.href);
}, { once: true });}

Download PDF from Base64 string

The example here seems helpful: http://php.net/manual/en/function.readfile.php

In your case:

<?php
$decoded = base64_decode($base64);
$file = 'invoice.pdf';
file_put_contents($file, $decoded);

if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>

This should force the download to occur.

Base64 String to pdf JavaScript React Native then download

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);
}
}

Node.js - Download locally docx or pdf encoded as base64 string

I've solved with this solution:

const express = require("express");
const atob = require("atob");
const router = express.Router();
const fs = require('fs');

router.post("/evaluate", function(req, res) {
var oResume = req.body.resume;
var sMimeType = oResume.mimeType;
var sFileExtension = oResume.fileExtension;
var sBase64 = oResume.content.replace(/(\r\n|\n|\r)/gm, "");
var sBinaryString = atob(sBase64);
var len = sBinaryString.length;
var aBytes = new Uint8Array(len);

for (var i=0; i<len; i++) {
aBytes[i] = sBinaryString.charCodeAt(i);
}
var blob = Buffer.from(aBytes.buffer);

fs.writeFile("cvs/out."+sFileExtension, blob, function(err) {
console.log(err);
});

res.status(200).send("OK");
});

module.exports = router;


Related Topics



Leave a reply



Submit