B4J Question Apache PDFBox

amaxco

Member
Licensed User
Longtime User
Hi,

I am inquiring about whether there is any implementation of the above library in B4J and if it has a built-in viewer.

Regards
 

Daestrum

Expert
Licensed User
Longtime User
I played with this a while back, didn't seem too hard to use with javaobjects.
You can render the generated page to an ImageView.
This is the code I used to get a true A4 sized image on my screen. It returns an (fx) Image that I just put into an ImageView.
B4X:
Sub renderPage(p As Int) As Image ' p is page number
 Dim scrn As JavaObject
 Dim dpi As Float = scrn.InitializeStatic("javafx.stage.Screen").RunMethodJO("getPrimary",Null).RunMethod("getDpi",Null)
 Return utils.RunMethodjo("toFXImage",Array(renderer.RunMethod("renderImageWithDPI",Array(p,dpi)),Null))
End Sub
 
Upvote 0

amaxco

Member
Licensed User
Longtime User
I played with this a while back, didn't seem too hard to use with javaobjects.
You can render the generated page to an ImageView.
This is the code I used to get a true A4 sized image on my screen. It returns an (fx) Image that I just put into an ImageView.
B4X:
Sub renderPage(p As Int) As Image ' p is page number
Dim scrn As JavaObject
Dim dpi As Float = scrn.InitializeStatic("javafx.stage.Screen").RunMethodJO("getPrimary",Null).RunMethod("getDpi",Null)
Return utils.RunMethodjo("toFXImage",Array(renderer.RunMethod("renderImageWithDPI",Array(p,dpi)),Null))
End Sub

Thank you for your reply.

I really want to display the whole document in a viewer similar to Acrobat Reader. I thought the webview could handle that in a similar manner as the WebBrowser object that we used in VB6, in connection of Acrobat Reader.

Regards,
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
The android webview does not have a PDF viewer integrated.
Edit: Sorry, B4J forum... I dont think B4 webview does not have a PDF-Viewer integrated too.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I did find an alternative - it uses a webview and a free js library. (ViewerJS)
Seems simple to get it display pdf's (it also can display other file types too)

The code is
B4X:
Sub AppStart ....
...
Dim wv As WebView
Dim engine As JavaObject
wv.Initialize("")
wv.PrefWidth = 600
wv.PrefHeight = 600
MainForm.RootPane.AddNode(wv,0,10,-1,-1)
engine = asJO(wv).RunMethodJO("getEngine",Null)

' where you unpacked the viewer to
Dim viewer As String = "C:/temp/ViewerJS/index.html"

' the file you want to display
Dim testfile As String = "C:/temp/pdftest.pdf"

Dim s As String = File.GetUri("",viewer) & "#" & File.GetUri("",testfile)
engine.RunMethod("load",Array(s))
Log(s)
End Sub
Sub asJO(o As JavaObject)As JavaObject
Return o
End Sub
 

Attachments

  • ViewerJS.png
    ViewerJS.png
    42.3 KB · Views: 324
Last edited:
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
@Erel - sorry that was just a snippet of the code I used , I can post the full code if you want.
Some of the missing bits (all javaobjects)
B4X:
thisDoc.InitializeNewInstance("org.apache.pdfbox.pdmodel.PDDocument",Null)
renderer.InitializeNewInstance("org.apache.pdfbox.rendering.PDFRenderer",Array(thisDoc))
utils.InitializeStatic("javafx.embed.swing.SwingFXUtils")
 
Upvote 0

amaxco

Member
Licensed User
Longtime User
@Erel - sorry that was just a snippet of the code I used , I can post the full code if you want.
Some of the missing bits (all javaobjects)
B4X:
thisDoc.InitializeNewInstance("org.apache.pdfbox.pdmodel.PDDocument",Null)
renderer.InitializeNewInstance("org.apache.pdfbox.rendering.PDFRenderer",Array(thisDoc))
utils.InitializeStatic("javafx.embed.swing.SwingFXUtils")

I appreciate if you could post the full code and an example app, unless it it requires a reply from @Erel
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
here is the code - I was just trying out creating pdf and printing.(never got round to adding bells and whistles like page size, margins etc)

There are very few comments in the code as I was writing it directly from the api docs.
 

Attachments

  • pdfboxtest.zip
    2.1 KB · Views: 387
Upvote 0

amaxco

Member
Licensed User
Longtime User
here is the code - I was just trying out creating pdf and printing.(never got round to adding bells and whistles like page size, margins etc)

There are very few comments in the code as I was writing it directly from the api docs.

Thrown error

Waiting for debugger to connect...
Program started.
ط£ط؛ط³ 23, 2017 9:43:16 ظ… org.apache.pdfbox.pdmodel.font.FileSystemFontProvider loadDiskCache
WARNING: New fonts found, font cache will be re-built
ط£ط؛ط³ 23, 2017 9:43:16 ظ… org.apache.pdfbox.pdmodel.font.FileSystemFontProvider <init>
WARNING: Building on-disk font cache, this may take a while
ط£ط؛ط³ 23, 2017 9:43:29 ظ… org.apache.pdfbox.pdmodel.font.FileSystemFontProvider <init>
WARNING: Finished building on-disk font cache, found 662 fonts
Error occurred on line: 55 (pdfLib)
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
at b4j.example.pdflib._savedocument(pdflib.java:222)
at b4j.example.main._appstart(main.java:102)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:613)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:231)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
at b4j.example.main.start(main.java:38)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.FileNotFoundException: c:\temp\pdftest.pdf (The system cannot find the path specified)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1118)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1106)
... 31 more
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Looks like you don't have a c:/temp directory in which to save the pdf file.
Caused by: java.io.FileNotFoundException: c:\temp\pdftest.pdf (The system cannot find the path specified)
 
Upvote 0

amaxco

Member
Licensed User
Longtime User
Looks like you don't have a c:/temp directory in which to save the pdf file.

Hi Daestrum,

You are correct! Creating the folder has fixed the problem.

In my first post I mentioned a viewer which is my prime concern. Of course your wrapper of rendering will be useful to other members, in addition to what @warwound had done https://www.b4x.com/android/forum/threads/jpdfjet.37842/

What I truly need is the viewer you explained about, showing a screenshot, in your post #6

Regards
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
The code I posted in post #6, is the entire code needed to show the viewer and load a file into it.
a, create a webview.
b, get the engine object of the webview.
c, create the uri to the VeiwerJS index.html and add '#' and the uri of the file you want to display
d, load the uri into the webengine

Display file =)
 
Upvote 0

amaxco

Member
Licensed User
Longtime User
I executed the code without error but nothing appears. Below is my modified code.
1. In the Process_Globals - I have Private webview2 As WebView
2. the AppStart - I have webview2.Initialize("")
3. I have a button to trigger ShowPdfFile

Sub ShowPdfFile()
'ShowPdfFile("C:/temp/pdftest.pdf")
engine = asJO(webview2).RunMethodJO("getEngine",Null)
webview2.PrefWidth=Pane2.width-25
webview2.PrefHeight=Pane2.height-25
Dim viewer As String = "C:/temp/ViewerJS/index.html"
Dim testfile As String = "C:/temp/pdftest.pdf"
Dim s As String = File.GetUri("",viewer) & "#" & File.GetUri("",testfile)
engine.RunMethod("load",Array(s))
Log(s)
End Sub

This is Log(s) output:
file:/C:/temp/ViewerJS/index.html#file:/C:/temp/pdftest.pdf

What could I have done wrong
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Have you checked that the ViewerJS.zip (from http://viewerjs.org/) unpacked correctly into c:/temp/ViewerJS directory.
 
Last edited:
Upvote 0

amaxco

Member
Licensed User
Longtime User
I am able to show ViewrJS in the webview!

Alas! The pdf file is not showing. I will continue trying and later feed you back
 
Upvote 0

amaxco

Member
Licensed User
Longtime User
Please note that the viewer show the file name in the title bar. Still the file content does not display.
 

Attachments

  • ViewerJs_01.png
    ViewerJs_01.png
    40.9 KB · Views: 289
Upvote 0
Top