View a PDF in React Native - pdf

Can anyone please provide sample code for displaying a PDF in React Native? iOS and Android.
This is what I've tried:
render: function() {
return <WebView
source={require('./my.pdf')}
/>
}
^ This results in a Red Screen of Death with the "Unable to resolve module" error.
render: function() {
return <WebView
source={{uri: 'my.pdf'}}
/>
}
^ This gives an "Error Loading Page" message in the WebView. "The requested URL was not found on this server"
I know iOS is capable of showing a PDF in a UIWebView. I assume Android can do the same. There must be something in how the source is specified that I'm missing.

Okay, for future generations, here's how I solved this problem:
Updated September 13, 2017:
There is a new NPM module that makes this entire process much easier. I would suggest using it going forward instead of my original answer below:
react-native-pdf
Once installed, rendering the PDF is as easy as this:
export default class YourClass extends Component {
constructor(props) {
super(props);
this.pdf = null;
}
render() {
let yourPDFURI = {uri:'bundle-assets://pdf/YourPDF.pdf', cache: true};
return <View style={{flex: 1}}>
<Pdf ref={(pdf)=>{this.pdf = pdf;}}
source={yourPDFURI}
style={{flex: 1}}
onError={(error)=>{console.log(error);}} />
</View>
}
}
Just put your actual pdf in the android/app/src/main/assets/pdf folder of your project.
Original Answer:
iOS
render: function() {
return <WebView source={{uri: 'My.pdf'}}/>
}
The trick is that you need to include My.pdf into your project in Xcode and make sure it's added to your build target.
Just copying it into your React Native project folder wasn't enough. It had to be part of the Xcode project itself.
Android
It appears that Android did not provide a native PDF viewer until 5.0 (Lollipop). To get around this, I've had to make use of three key techniques:
Pull the PDF out of my APK bundle and store it in the files folder for my app. This SO answer was very helpful in accomplishing this:
Android: How to copy files from 'assets' folder to sdcard?
I tweaked the code a bit so that the file wasn't going to an sdcard but to my app's files folder. Here's what I added to my MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("pdf");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (files != null) for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open("pdf/" + filename);
File outFile = new File(getFilesDir(), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
Log.e("tag", "Copy was a success: " + outFile.getPath());
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + "pdf/" + filename, e);
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// NOOP
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// NOOP
}
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
I also made sure my PDF is in the assets/pdf folder under android/app/src/main
I then utilized the react-native-fs package to get the absolute URL to my PDF, which is now in the files folder:
var RNFS = require('react-native-fs');
var absolutePath = RNFS.DocumentDirectoryPath + '/My.pdf';
With all of this in place, I used react-native-pdf-view to actually load and display the PDF:
import PDFView from 'react-native-pdf-view';
render: function() {
var absolutePath = RNFS.DocumentDirectoryPath + '/My.pdf';
return <PDFView
ref={(pdf)=>{this.pdfView = pdf;}}
src={absolutePath}
style={ActharStyles.fullCover} />
}
Good luck!

A simple solution for this problem is to set <WebView> source/uri to this:
https://drive.google.com/viewerng/viewer?embedded=true&url={your pdf url}’

Just add style={{flex:1}} in the opening View Tag of your return and you should be fine.

The Amazon S3 Presigned URL contains query string contains "?" and "&" which confuses the outer URL.
So you have to Encode the S3 Presigned URL before passing it to the Google Doc Viewer.
Like this:
var encodedUrl = encodeURIComponent(presigned_url);
var iFrameUrl = 'https://docs.google.com/gview?url=' + encodedUrl;

In case of pdf url this will do
openLink(url) {
return Linking.canOpenURL(url)
.then(supported => {
if (!supported) {
console.log("Can't handle url: " + url);
this.showFlashMessage('Not supported in your device');
} else {
return Linking.openURL(url);
}
})
.catch(err => console.error('An error occurred', err));
}

Related

How to download files through development vscode extension on code-server?

I wrote a vscode extension. Now you want to download a file in the vscode working directory by developing extensions. But no files were obtained through vscode vscode.Uri.file.
const downloadPanel = vscode.window.createWebviewPanel(
"view",
"下载",
vscode.ViewColumn.Two,
{
enableScripts: true,
retainContextWhenHidden: true,
}
)
if (vscode.workspace.workspaceFolders === undefined) {
throw new Error("not found!");
}
const filePath = vscode.workspace.workspaceFolders[0].uri.fsPath;
let downloadContent = vscode.commands.registerCommand('download.click', () => {
console.log("filePath = " + filePath);
const onDiskPath = vscode.Uri.file(
path.join(context.extensionPath, "resources","blockchain.svg")
);
// And get the special URI to use with the webview
const catGifSrc = panel.webview.asWebviewUri(onDiskPath) + "";
getWebviewContent(catGifSrc);
function getWebviewContent(_src: string) {
return '<html><head><script></script></script></head><body><div>download</div></body></html>';
}
When clicking the link, the file is not found! Currently, only nginx proxy can be used for full path downloading. Is there any other plan or solution?

flutter png and then create PDF file to printer

I am working in new flutter project that capture a widget to PNG image with a barcode and a few text like this one and send the data to the printer via native code. But I had many issues. For example printing is too slow with ios devices (android print speed is ok). So I decide to print from PDF for ios and I have a few questions:
which package do I have to use for printing the PDF.
also can u provide me with the correct code for converting to PDF
thank you
You can check out this package:
https://pub.dev/packages/printing
examples from the package:
final doc = pw.Document();
doc.addPage(pw.Page(
pageFormat: PdfPageFormat.a4,
build: (pw.Context context) {
return pw.Center(
child: pw.Text('Hello World'),
); // Center
}));
then
await Printing.layoutPdf(
onLayout: (PdfPageFormat format) async => doc.save());
hope it works for you.
Thank Me Later
Future printPng() async {
try {
RenderRepaintBoundary boundary = _globalKey.currentContext!
.findRenderObject() as RenderRepaintBoundary;
// if it needs repaint, we paint it.
if (boundary.debugNeedsPaint) {
Timer(const Duration(seconds: 1), () => printPng());
return null;
}
ui.Image image = await boundary.toImage(pixelRatio: 3.0);
ByteData? byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
var pngBytes = byteData!.buffer.asUint8List();
final imageToPrint = await flutterImageProvider(MemoryImage(pngBytes));
final doc = pw.Document();
doc.addPage(pw.Page(build: (pw.Context context) {
return pw.Center(child: pw.Image(imageToPrint)); // Center
}));
await Printing.layoutPdf(
onLayout: (PdfPageFormat format) async => doc.save());
return pngBytes;
} catch (e) {
print(e);
return null;
}
}

How to Push Realm File to Internal Storage in React Native from Application

I am working on a application which ships whole database file shared within React Native Code to user internal storage. For pushing file to internal storage on Android I am using Realm the code we have done work correctly for iOS but for Android I am getting file not found (aka. The Realm is not pushing an file to Internal Storage Android)
Here what I done until now
export default new Realm({
path:Platform.OS === 'ios'
? RNFS.MainBundlePath +'/www/RippleEffect.realm'
: RNFS.DocumentDirectoryPath +'/RippleEffect.realm',
schema: [apply_it,
case_study,
got_it,
got_it_2,
got_it_2_question,
got_it_2_question_answer,
got_it_question,
got_it_question_answer,
howto,
howto_screens,
info,
info_screens,
model,
profile,
profile_result,
profile_statements,
related_topic,
special_assets_table_teens,
topic_audio,
topic_equivalence,
topics,
true_story,
your_mind,
],
readOnly: true
});
Use this two dependency
import Realm from 'realm';
import RNFS from 'react-native-fs'
And In App Class
const App = () => {
Realm.copyBundledRealmFiles();
return (
<App/>
);
};
For those who are working React Native with Realm DB
I solve this issue by pushing realm file from assets folder to internal folder(user mobile ) and thus I was able to read an write about database.
File dbDirectory = new File(MainApplication.getFileDirectory() + "/db");
/**
* Check for database
* directory
*/
if(!dbDirectory.exists()){
if(dbDirectory.mkdirs()){
moveDBFileToCard("database.realm");
}
}
private void moveDBFileToCard(String databaseFileName) {
try{
AssetManager assetsManagerFiles = getAssets();
/**
* Intialize Stream
*/
InputStream inputStream;
OutputStream outputStream;
inputStream = assetsManagerFiles.open(databaseFileName);
System.out.println("File Path = " + MainApplication.getFileDirectory() + "/db" + "/" + databaseFileName);
File fileDB = new File(MainApplication.getFileDirectory() + "/db" + "/" + databaseFileName);
if (fileDB.exists()) {
fileDB.delete();
}
outputStream = new FileOutputStream(MainApplication.getFileDirectory() + "/db" + "/" + databaseFileName);
byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
inputStream.close();
outputStream.flush();
outputStream.close();
}catch (IOException io){
io.printStackTrace();
}
}
And also removed
readOnly: true from file as it was giving issue to filter quesry on 0.60 version

ListDir which contains only pdf files

I need a help regarding Ionic-4 code.I want to list the directories which contains only PDF files in it using lisDir method.
Thanks in advance.
Try the following code, this should work in Android, I didn't get time to test this but should work;
constructor(public navCtrl: NavController, public platform: Platform,
private filePath: FilePath, private file: File) {
this.platform.ready().then(() => {
this.file.listDir(file.externalDataDirectory, '').then((result) => {
console.log(result);
for (const fl of result) {
if (fl.isDirectory == true && fl.name != '.' && fl.name != '..') {
// Code if its a folder
} else if (fl.isFile == true) {
const fName = fl.name; // File name
const path = fl.fullPath; // File path
if(fName.toLowerCase().endsWith('.pdf')) {
// do Something
}
}
}
});
});
}

Access sd card in android for uploading a file to my php server using phonegap

I want to go to select a file from sdcard and upload it to server. is it possible to access the sdcard in android via phonegap as how we are picking a image from gallery and uploading. I went through samples but all are specifying the file name also like eg: mnt/sdcard/read.txt. But i want to goto only sdcard so that user can select his own file is it possible to do.
U can easily do that its very easy
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccessUpload, fail);
function onFileSystemSuccessUpload(fileSystem) {
// get directory entry through root and access all the folders
var directoryReader = fileSystem.root.createReader();
// Get a list of all the entries in the directory
directoryReader.readEntries(successReader,fail);
}
function successReader(entries) {
var i;
for (i=0; i<entries.length; i++) {
//alert(entries[i].name);
if(entries[i].isDirectory==true)
{
var directoryReaderIn = entries[i].createReader();
directoryReaderIn.readEntries(successReader,fail);
}
if(entries[i].isFile==true)
{
entries[i].file(uploadFile, fail);
}
}
};
function uploadFile(file) {
var target=""; //the url to upload on server
var ft = new FileTransfer(),path = "file://"+ file.fullPath,name = file.name;
ft.upload(path, target, win, fail, { fileName: name });
// var ft = new FileTransfer();
//ft.upload(file.fullPath, target, win, fail, options);
function win(r) {
alert("Code = " + r.responseCode);
alert("Response = " + r.response);
alert("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
}
}