Converting a buffer response into a PDF format is a crucial task in any application that needs to generate and download a PDF file in a React Native environment. However, there is an issue that arises when we try to download the PDF file on devices with an Android version above 9, as it does not open directly. To solve this issue, we can convert the response data into buffer format.
In this article, we will walk through a simple method to convert a buffer response into PDF format using React Native. We will cover all the necessary steps, including installation, importing libraries, and implementing the download button.
### Step 1 - Installation
To begin with, we need to install the following libraries:
react-native-fs buffer You can install these libraries using npm:
npm install buffer
### Step 2 - Importing Libraries
After installation, we need to import the libraries in our React Native file. We need to import Buffer from the buffer library and RNFS from the react-native-fs library.
import RNFS from 'react-native-fs'
### Step 3 - Implementing the Download Button
Next, we need to create a download button that will ask the user for permission to download and save the file. The askPermission function will request permission from the user, and if allowed then we can write to the user's device.
<TouchableOpacity onPress={askPermission}>
<Block
style={{ width: 40,
height: 40,
borderRadius: 10,
backgroundColor: 'white',
justifyContent: 'center',
borderWidth: 1,
borderColor: '#F1F4F7' }}>
<AntDesign name={'download'}
size={20}
style={{
color: baseTheme.COLORS.PRIMARY,
alignSelf: 'center' }} />
</Block>
</TouchableOpacity>
### Step 4: Ask for External Storage Permission
In this step, we will ask the user to allow for external storage to save the downloaded file on the device. If the user has already granted permission, we will directly call the downloadPdf() method.
const askPermission = () => {
async function requestExternalWritePermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: 'Pdf creator needs External Storage Write Permission',
message: 'Pdf creator needs access to
Storage data in your Internal storage.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
downloadPdf()
} else {
alert('WRITE_EXTERNAL_STORAGE permission denied')
}
} catch (err) {
alert('Write permission err', err)
console.warn(err)
}
}
if (Platform.OS === 'android') {
requestExternalWritePermission()
} else {
downloadPdf()
}
}
In the askPermission() function, we use the PermissionsAndroid library to request WRITE_EXTERNAL_STORAGE permission. The user will see a dialog box asking for permission to access external storage. If the user grants permission, we call the downloadPdf() function. If not, an alert will show up with a message stating that WRITE_EXTERNAL_STORAGE permission was denied.
If the app is running on a non-Android platform, we will skip the requestExternalWritePermission() function and call the downloadPdf() function directly.
### Step 5: Downloading the PDF
Once the downloadPdf() function is called, the server sends the response in the form of a buffer. First, we convert the buffer response into base64 format using the Buffer.from() method. Then, we convert it into a toString format. Once we have the toStringBuff for the PDF we want to save, we need to create the path where we will save the file and save it to the app’s document directory.
PatientDetailServices.getPrescriptionPdf(appointmentId)
.then(response => {
if (response.status == 200) {
let buffer = response.data.buffer.data
const buff = Buffer.from(buffer, 'base64')
let toStringBuff = buff.toString('base64')
var path = RNFS.DownloadDirectoryPath
+ `/AppointmentDate${appointmentDetail && appointmentDetail.date}.pdf`;
// write the file
RNFS.writeFile(path, toStringBuff, 'base64')
.then((success) => {
showToastWithGravity('Download Successfully')
})
.catch((err) => {
showToastWithGravity(err.message);
});
} else if (response.status == 500) {
showToastWithGravity('Internal server error.')
}
else if (response.status == 404) {
showToastWithGravity('No pdf found.')
}
else {
showToastWithGravity('Error !!')
}
}).catch(error => {
showToastWithGravity('Some error occurred.')
})
}
If the user provides access, then the above function makes a call to the server. In response, we get the buffer. First, we convert the buffer into base64 format using Buffer.from(buffer, 'base64'), then we convert it into a toString format. Next, we define the path where the file will be saved. After defining the path, we use the RNFS.writeFile() method to download the PDF.
### Summary
In conclusion, using a combination of react-native-buffer and react-native-fs allows for an easy way to convert the response buffer into a PDF downloadable form. By following the above steps, we can request a PDF file from the server, convert the response into a buffer, and download it as a PDF file. This solution works seamlessly across different Android versions and is a great way to save and download PDF files in a React Native application.
By using the necessary libraries and implementing the appropriate code, it is possible to create a PDF file download feature in your React Native application. Additionally, using the appropriate permissions and saving the files in the appropriate location will allow you to avoid any issues when downloading and saving files.
You can find the complete source code for this implementation on GitHub: