React Native: How to read and display xml file - react-native

How can I display the .xml file to the screen. I can display the pdf file using react-native-pdf but how can I display the text in .XML file or read it.

solution to display the text in .XML file or read it
I'm showing you how can you read any file. If you can read any file, storing that to some state, then rendering is not an issue, I hope so.
Here is how to read a local file in react-native :
var RNFS = require('react-native-fs');
import DocumentPicker from 'react-native-document-picker';
selectFiles = () => {
let that = this;
try {
DocumentPicker.pickMultiple({
type: [DocumentPicker.types.allFiles],
}).then((results) => {
console.log(results[0]);
//that.setState({language: results[0].type});
RNFS.readFile(results[0].uri)
.then((file) => {
that.setState({
code: file
});
})
.catch((error) => console.log('err: ' + error));
//the `code` state holds your xml file, just display it however you want... use 3rd party library for syntax highlight or whatever you want
});
} catch (err) {
if (DocumentPicker.isCancel(err)) {
// User cancelled the picker, exit any dialogs or menus and move on
} else {
throw err;
}
}
};

Related

How to create a .pdf or .csv file automatically in React Native for Android 11 (or later)

The following code works up to Android 10, it is creating a csv file in the DCIM folder:
import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
export async function saveCSV() {
const permission = await MediaLibrary.requestPermissionsAsync();
if (permission.status != 'granted') {
console.log("Permission not Granted!")
return;
}
// CSVLocation
const directoryUri = FileSystem.documentDirectory;
const fileUri = directoryUri + `formData.csv`;
// Save to DCIM folder
const asset = await MediaLibrary.createAssetAsync(fileUri);
try {
const album = await MediaLibrary.getAlbumAsync('album');
if (album == null) {
console.log("ASSET", asset)
await MediaLibrary.createAlbumAsync('album', asset, true);
} else {
await MediaLibrary.addAssetsToAlbumAsync([asset], album, true)
.then(() => {
console.log('File Saved Successfully!');
})
.catch((err: string) => {
console.log('Error In Saving File!', err);
});
}
} catch (e) {
console.log(e);
}
}
Previously this line of code was executed in another function to create a file in the fileUri used above:
await FileSystem.writeAsStringAsync(fileUri, CSVheader + newInfo);
This issue has been described here: https://github.com/expo/expo/issues/12060
In short: Expo Media library is able to save image/video/audio assets so it will fail with other file types. Weirdly enough it was working fine with .pdf and .csv up to Android 10.
In the link above, and also on stackoverflow there are solutions using StorageAccessFramework. However, the user needs to create a subdirectory inside Downloads every time a file needs to be saved. I would like to make it automatically without any popups (after permission is granted).
The destination folder doesn't matter as long as it is accessible by the user later.

I am converting Images to pdf using a npm library in react native why it is giving error of null object?

I am using react-native-image-to-pdf library to convert images to pdf in my react native app. from https://www.npmjs.com/package/react-native-image-to-pdf
var photoPath = ['https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350','https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350'];
const myAsyncPDFFunction = async () => {
try {
const options = {
imagePaths: photoPath,
name: 'PDFName',
};
const pdf = await RNImageToPdf.createPDFbyImages(options);
console.log(pdf.filePath);
} catch(e) {
console.log(e);
}
}
but this is giving error Error: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
I have also tried giving path as ['./assets/a.png', './assets/b.png']
but still getting same error
Based on the usage example, your photoPath needs to be a local file path and not a remote path.
My recommendation is to first use rn-fetch-blob to download the remote image to the device, and then pass your new local image path to react-native-image-to-pdf. Something like:
RNFetchBlob
.config({
// add this option that makes response data to be stored as a file,
// this is much more performant.
fileCache : true,
})
.fetch('GET', 'http://www.example.com/file/example.png', {
//some headers ..
})
.then(async (res) => {
// the temp file path
console.log('The file saved to ', res.path())
const options = {
imagePaths: [res.path()],
name: 'PDFName',
};
const pdf = await RNImageToPdf.createPDFbyImages(options);
})
from file path remove the text 'file://; with empty string('').
const options = {
imagePaths: [uri.replace('file://', '')],
name: 'FileName',
quality: .9, // optional compression paramter
};
replace('file://', '') it's work for me

DocumentPicker in React-Native not working properly for Android devices

I have implemented a document picker in my react native application and it is working fine for iOS. However in Android, I am having a weird issue
When I open the document picker and the navigation takes to the file explorer (Downloads section) in Android phone, though I am able to select the pdf file but, when it comes to the application back, it stuck to the page and the file is not there. I have attached the screenshot Same behaviour when the file explorer takes to the recent files. Only when from the recent files, I select the google drive and try to select the pdf from there, it works as expected and I can see the file in my application and the app do not stuck.
Here is what I have written for the pdf document picker
selectPDF = async ()=>{
var imageList = [...this.state.files];
try {
const results = await DocumentPicker.pickMultiple({
type: [DocumentPicker.types.pdf],
});
for (const res of results) {
console.log(
res.uri,
res.type, // mime type
res.name,
res.size
);
const fileName = res.uri.replace("file://","");
let data1 = ''
RnFetchBlob.fs.readStream(
fileName,
'base64',
4095
)
.then((ifstream)=>{
//let data1 = ''
ifstream.open()
ifstream.onData((data)=>{
data1 += data;
})
ifstream.onEnd(() => {
let base64 = data1
imageList.push({
imageName:res.name,
image:base64,
mime:res.type,
size:res.size
})
this.setState({
...this.state,
openCamera:false,
lastFileName:imageList[imageList.length - 1].imageName,
files:imageList
})
})
})
}
} catch (err) {
if (DocumentPicker.isCancel(err)) {
this.closeModal();
} else {
throw err;
}
}
}
Can anyone throw some light as to what I may be missing. Is some configuration needs to be set on device level or any other thing.
you can use something like this,
const [file, setFile] = useState(null);
const selectFile = async () => {
try {
const results = await DocumentPicker.pickMultiple({
type: [DocumentPicker.types.allFiles],
});
setFile(results);
} catch (err) {
if (DocumentPicker.isCancel(err)) {
alert('Canceled');
} else {
alert('Unknown Error: ' + JSON.stringify(err));
throw err;
}
}
};
now you can call file in your function
and to use it you can do like this
<TouchableOpacity
activeOpacity={0.5}
onPress={selectFile}>
<Text>Select File</Text>
</TouchableOpacity>

React Native RNFetchBlob getting the URI of the file after download

I am developing a React Native project. What I am trying to do now is that I am downloading and saving the downloaded file to the device. I am using this package, https://www.npmjs.com/package/rn-fetch-blob for downloading the file.
This is my code
RNFetchBlob.config({
fileCache: true,
})
.fetch('GET', 'https://static.standard.co.uk/s3fs-public/thumbnails/image/2016/05/22/11/davidbeckham.jpg?w968', {
})
.then((res) => {
Alert.alert(res.path());
})
After download, res.path returns the path like this.
I am trying to convert it to the URI to be displayed using the Image component. I tried binding the following state object to the Image component.
{
uri: res.path()
}
It did not work. That is why as a next attempt, I am trying to convert the path into URI and display the uri. How can I do that?
Try providing the path of the file where you want to download it,
const directoryFile = RNFS.ExternalStorageDirectoryPath + "/FolderName/";
RNFS.mkdir(directoryFile);
const urlDownload = input.url;
let fileName;
fileName = "filename.zip";
let dirs = directoryFile + fileName;
RNFetchBlob.config({
// response data will be saved to this path if it has access right.
path: dirs
}).fetch("GET", urlDownload, {
//some headers ..
})
.then(res => {
console.log("The file saved to ", res.path());
//RNFS.moveFile(dirs, directoryFile + fileName); // -> uncomment this line if it still does not store at your desired path
alert("File Downloaded At Folder");
})
.catch(err => {
console.log("Error: " + err);
});

Download using jsPDF on a mobile devices

I have a page that includes a download button using jsPDF. On desktop machines it downloads the page as it should. However, pdf.save() does not work on my tablet or phone.
I tried to add a special case for mobile devices to open the PDF in a new window, since mobile devices don't download things the same as desktops, with the idea being that once the PDF is open in a new window the user can choose to save it manually.
var pdf = new jsPDF('p', 'pt', 'letter');
var specialElementHandlers = {
'#editor': function (element, renderer) {
return true;
}
};
html2canvas($("#pdf-area"), {
onrendered: function (canvas) {
$("#pdf-canvas").append(canvas);
$("#pdf-canvas canvas").css("padding", "20px");
}
});
var options = {
pagesplit: true
};
function download(doctitle) {
pdf.addHTML($("#pdf-area")[0], options, function () {
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
pdf.output('dataurlnewwindow');
} else {
pdf.save(doctitle);
}
});
}
But the download function still does nothing on my tablet/phone. I tested it with this to make sure the pdf.output() function was working:
pdf.addHTML($("#pdf-area")[0], options, function () {
pdf.output('dataurlnewwindow');
});
and it does still work on desktop, but does nothing on mobile.
jsPDF won't download files on mobile apps by this pdf.save(). I have tried and searched for this issue but could not find a complete solution in one place. I am using the file and file-opener plugin. I have developed the solution in Ionic React. Install below modules.
npm i jspdf
npm install cordova-plugin-file
npm install #ionic-native/file
npm install cordova-plugin-file-opener2
npm install #ionic-native/file-opener
ionic cap sync
Go to your file and add these import statements.
import { jsPDF } from "jspdf";
import 'jspdf-autotable';
import { FileOpener } from '#ionic-native/file-opener;
import { File } from '#ionic-native/file';
import { isPlatform } from "#ionic/react";
Check the pdfDownload function
const pdfDownload = async () => {
var doc = new jsPDF();
doc.setFontSize(40);
doc.text("Example jsPDF", 35, 25)
let pdfOutput = doc.output();
if (isPlatform("android")) {
// for Android device
const directory = File.externalRootDirectory + 'Download/';
const fileName = `invoice-${new Date().getTime()}.pdf`
File.writeFile(directory, fileName, pdfOutput, true).then(succ => {
FileOpener.showOpenWithDialog(directory + fileName, 'application/pdf')
.then(() => console.log('File opened'))
.catch(error => console.log('Error opening file', error));
},
err => {
console.log(" writing File error : ", err)
})
} else if (isPlatform("ios")) {
// for iOS device
console.log('ios device')
const directory = File.tempDirectory;
const fileName = `invoice-${new Date().getTime()}.pdf`
File.writeFile(directory, fileName, pdfOutput, true).then(success => {
FileOpener.showOpenWithDialog(directory + fileName, 'application/pdf')
.then(() => console.log('File opened'))
.catch(e => console.log('Error opening file', e));
},
err => {
console.log(" writing File error : ", err)
})
} else {
// for desktop
doc.save("invoice.pdf");
}
}
I had similar issue.
jsPDF won't download file on phones/ tablets / ipads using "pdf.save()".
Do it through File plugin if you are using cordova/phonegap, this will save pdf file in downloads folder (Android) - for the ios you can access pdf file through a path (which is saved somewhere in temp directory) and can send or share.
Hope this helps you.
Here is the solution of download on mobile with jspdf
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))
{
var blob = pdf.output();
window.open(URL.createObjectURL(blob));
}
else
{
pdf.save('filename.pdf');
}
Here is the example if you're using the Cordova platform for your development:
https://github.com/saharcasm/Cordova-jsPDF-Email
The workaround of the pdf not being downloaded in the devices is to use cordova-plugin-file.
Use the output method on the doc that will give you the raw pdf which needs to be written & saved in a file.
For example,
var doc = new JsPDF();
//... some work with the object
var pdfOutput = doc.output("blob"); //returns the raw object of the pdf file
The pdfOutput is then written on an actual file by using the file plugin.
The easiest way which works on both Desktop and Mobile is to use:
window.open(doc.output("bloburl"), "_blank");