B4J Library jNxtReportsB4J: Library to view reports generated by Next-Reports

************** UPDATE - 11 MARCH 2021 ******************************
The source files which I used for this library have been uploaded in this thread.
Since I have stopped working with this library and my Java knowledge is minimal, I hope that someone may use these files to find a fix for the problem listed below.
Note that the libs folder is empty - due to size limitations.
This folder contained the following files - all are available online (although I suspect some might be redundant):
commons-jexl-2.1.1
commons-logging-1.1.1
itext-2.1.7
itextpdf-5.0.6
itext-rtf-2.1.7
jcalendar-1.3.2
jtds-1.3.1
nextreports-engine-X.X
poi-3.7
xstream-1.3.1
xstream-1.4.7

*************************************************************************



*******************************************************************

IMPORTANT NOTE - 11 MAY 2020
*******************************************************************
This library works fine with Java 8.


Unfortunately, there is an important issue with OpenJDK 11.
Although non-UI apps still run fine (tested with ABMaterial app), UI apps can only run fine from the IDE.
When UI apps are packed with B4JPackager11, when the program tries to generate a report, this error appears:


As there is currently no fix for this problem, if you need to have reports on an OpenJDK11 UI-app, you need to consider other reporting libraries (e.g Jasper reports, ABMReport in ABMateriral).

*****************************************************************

jNxtReportsB4J Library allows B4J programs to handle report files generated by NextReports.

It contains just one function, which receives all its parameters in a list.

LIMITATIONS:
Library was compiled with Java 8. So, I assume, it will require Java 8 to run.

Only table reports are supported.
Charts are NOT supported.

Report files can be exported CSV, TXT, XLS, XML, PDF, HTML or RTF format.

If a report contains images, then images are automatically displayed only in the HTML format export case. In order to display images in other formats, you must edit the MANIFEST.MF file (see instructions in Step 6 below).

Output files are always exported in your application folder (i.e. where your application’s Jar file is located).


TESTING:
The demo and library supplied here have been tested on Windows 7 and Windows 8.1, running Java 8, with reports generated by Next Reports Version 8.1., against a Microsoft SQL Server database.

HOW TO USE:
Step 1
Copy your report file (i.e. a file with “report” extension, generated by Next Reports), including any images necessary for your report,into a folder of your choice.
(Next Reports by default saves report files at C:\Users\YourUserName\.nextreports-8.1\output\YourConnectionName\Reports.)

Step 2
Extract the jNxtReportsB4J.zip (it contains 3 files: jNxtReportsB4J.jar, jNxtReportsB4J.xml, nextreports-engine-8.1.jar) to the Additional Libraries folder of B4J.

Step 3
Download and save to the Libraries folder of B4J the applicable Jar files listed in the “Additional Jar” section of the demo program. All files are available on the web.

Step 4
Copy the appropriate JDBC Jar file (necessary for the database type you are using), into the Libraries folder of B4J.

Step 5
Edit, as necessary, the code of NxtReportsDemo. This demo operates on a Microsoft SQL SERVER database, outputs the report in the format specified and then opens it for viewing.
You must, at least, specify your own report name and report location (the folder where you saved your report in Step 1) plus the url and driverclass parameters applicable to your database.

Step 6 (Images)
If your report contains images, these are automatically displayed ONLY in html format. In order to display them in other formats, you must add a Class-Path parameter in the MANIFEST.MF file of the Jar file of your program. In order to do this, you must have 7-Zip and Notepad++ installed (or other programs with similar functionality). Follow these steps:
  1. Locate your Jar file (in the Objects folder of your application).
  2. Right click on you Jar file and open it with 7-Zip
  3. Enter in the META-INF folder
  4. Open the MANIFEST.MF program with Notepad++
  5. Add a line similar to this: Class-Path: .\reports\
The Class-Path should point to the folder where you have stored the images of your report – see Step 1. In my example, this is a folder called “reports” which is located in my application folder (which is also the current folder). You can specify an absolute path or a relative path, as I did above.
Now the MANIFEST.MF file will look like this:

Manifest-Version: 1.0
JavaFX-Version: 2.2
JavaFX-Application-Class: b4j.example.main
Created-By: JavaFX Packager
Main-Class: anywheresoftware.b4a.keywords.Common
Class-Path: .\reports\


Next, save changes and close Notepad++.
7-Zip will ask you if MANIFEST.MF file should be updated.
Press Yes.
Close 7-Zip.
You can now run your Jar file and the images will be displayed regardless of format output.
 

Attachments

  • jNxtReportsB4J.zip
    486.9 KB · Views: 762
  • NxtReportsDemo.zip
    1.6 KB · Views: 590
  • Source jNxtReportsB4J.zip
    11.5 KB · Views: 83
Last edited:

Harris

Expert
Licensed User
Maybe someone else has confronted this issue and has some light to shed.

Solved it...

Seems the params system doesn't handle multiple values well, or I just can't figure it out. Works well in NR designer, but I can't seem to pass them.
However, I used single value to define each of 2 params - drvid and termid (driver and terminal ).

In the NR query, I use IF function to determine what was selected.
Different terminals have different drivers. Terminals may only see drivers that belong to them, however regional mangers can see all terminals at any time in the same report. The selector below also restricts who can see what by setting the terminal first (based on user login) and then restricting the list of drivers / vehicles.

IF (${termid} = "-1" ,
IF ( ${drvid} = "-1" , eventmast.drvid > -1 , eventmast.drvid = ${drvid}) ,
IF ( ${drvid} = "-1" , eventmast.drvid = e1.pk AND e1.terminal = ${termid} , eventmast.drvid = ${drvid}) )

report_sel.jpg
 

JuliamnHeim

Member
Licensed User
I have been using this lib for a while. Great work.
Is there any way to set the query timeout as I am finding if a query takes more than 60secs the report time's out.
Thanks
 

magi6162

Well-Known Member
Licensed User
How can I use next report with ABM?
if it's not asking too much, a small example would be welcome,
Thanks for your help.


Nice!

I have it working with ABMaterial as well. This example uses the start and end date params... NextReport 9.1...
Including all jars turned my 5 meg app jar into 12 meg. Nice to have the (small) engine included (as opposed to separate server - yet is available).
Beats the 900 meg of JasperSoft...
Now, to try this on my Ubuntu remote server...

pdfFolder = File.DirApp &"/www/"&AppName&"/rptout_"&Main.comp_id
repout=pdfFolder&"/"&fn 'name of output report

The output report folder was created during login for the site user.
It prepends the directory to the output report name.... Seems to work, however an Output Directory property would be nice, as well as output report name.

For complex reports that involves much data processing, I find it easier to create the report if you normalize the data first. Output processed data to a temp table for the report to use, where each column has the complex computed values. Then all you have to do is render column text.

This report's query in Next Reports... It get's funcky due to long type DateTime values sent by the android app to MySQL.
B4X:
SELECT
    e1.First_name,
    e1.Last_name,
    s1.start,
    s1.end,
    s1.worktype,
    FROM_UNIXTIME(s1.start / 1000) as SD,
    FROM_UNIXTIME(s1.end / 1000)   as ED,
    SUBTIME(    FROM_UNIXTIME(s1.end / 1000) , ( FROM_UNIXTIME(s1.start / 1000))  ) as ST
FROM
    emp e1,
    shifthist s1
WHERE
   e1.PK = s1.empid AND DATE(FROM_UNIXTIME(s1.start / 1000)) >= ${sdate} AND DATE(FROM_UNIXTIME(s1.start / 1000)) <= ${edate}
   ORDER BY e1.Last_name, e1.First_name


As a simple test example - On RUN REPORT, the pdf is loaded in ABMPDFViewer. From viwer, you can download or print.
pdf1.SetDocument("../rptout_"&Main.comp_id&"/"&name)

View attachment 58827
 

Harris

Expert
Licensed User
The Run_Report is where the report calling magic happens. (see attached .bas)

All reports built with NextReports are stored in a folder. These report names are stored in a table for user selection.
Different reports expose / hide various input params (for user to set).

I see from your other codes posted in other questions you asked - you are getting quite proficient with this framework (ABM).
Good for you!
It took me much longer since we were all new to this and had to figure much out on our own - trying not to stress @ab too much.
As you can see - there is very little you CAN'T do! All without writing one freakin line of JS, HTML5, php, ajax or whatever else the rest of the world uses to hack together a functional web app.

Me bias? You bet your ass I am! B4J and ABM has to be the most functional, easiest development platform ever produced. Although the price could use some adjustment. FREE is way to cheap!
 

Attachments

  • reportsPage.zip
    11.9 KB · Views: 258

roberto64

Active Member
Licensed User
Hello, I have a problem with Nextreports 9.1 does not display the barcode qundo execio com b4j there are instructions to make reports that displays everything like the program of Nextreports 9.1 also with java instructions.
regards
 

Harris

Expert
Licensed User
The Class-Path should point to the folder where you have stored the images of your report – see Step 1. In my example, this is a folder called “reports” which is located in my application folder (which is also the current folder). You can specify an absolute path or a relative path, as I did above.
Now the MANIFEST.MF file will look like this:

Manifest-Version: 1.0
JavaFX-Version: 2.2
JavaFX-Application-Class: b4j.example.main
Created-By: JavaFX Packager
Main-Class: anywheresoftware.b4a.keywords.Common
Class-Path: .\reports\


Next, save changes and close Notepad++.
7-Zip will ask you if MANIFEST.MF file should be updated.
Press Yes.
Close 7-Zip.
You can now run your Jar file and the images will be displayed regardless of format outpu


This is my MANIFEST.MF

Can I embed the image file path in B4J so it puts it in the MANIFEST.MF?
Will the image file path get over-written with each compile of my app?

Thanks


B4X:
Manifest-Version: 1.00
Main-Class: abmtripinspect.ti.com.main
Class-Path: libs/jCore.jar libs/ABMaterial.jar
 libs/jDateUtils.jar libs/jServer.jar libs/jSQL.jar
 libs/JavaObject.jar libs/Json.jar libs/jStringUtils.jar
 libs/jExcel.jar libs/jFileWatcher.jar libs/Archiver.jar
 libs/ByteConverter.jar libs/Encryption.jar libs/OkHttp.jar
 libs/jNxtReportsB4J.jar libs/ABPDFBox.jar libs/jFX8Print.jar
 libs/pngtastic-1.1.jar libs/microsoft-translator-java-api-0.6.2-jar-with-dependencies.jar libs/prettytime-4.0.1.Final.jar
 libs/commons-lang3-3.4.jar libs/jetty_b4j.jar libs/c3p0-0.9.5.2.jar
 libs/c3p0-oracle-thin-extras-0.9.5.2.jar libs/mchange-commons-java-0.2.11.jar libs/jxl.jar
 libs/okhttp-3.5.0.jar libs/okio-1.11.0.jar libs/pdfbox-app-2.0.8.jar
 libs/jfx.jar libs/nextreports-engine-9.1.jar libs/commons-jexl-2.1.1.jar
 libs/commons-logging-1.1.3.jar libs/itext-2.1.7.jar libs/itext-rtf-2.1.7.jar
 libs/itextpdf-5.0.6.jar libs/xstream-1.3.1.jar libs/xstream-1.4.7.jar
 libs/poi-3.7.jar libs/mysql-connector-java-5.1.44-bin.jar
 

Philip Chatzigeorgiadis

Active Member
Licensed User
This is my MANIFEST.MF

Can I embed the image file path in B4J so it puts it in the MANIFEST.MF?
Will the image file path get over-written with each compile of my app?

Thanks


B4X:
Manifest-Version: 1.00
Main-Class: abmtripinspect.ti.com.main
Class-Path: libs/jCore.jar libs/ABMaterial.jar
 libs/jDateUtils.jar libs/jServer.jar libs/jSQL.jar
 libs/JavaObject.jar libs/Json.jar libs/jStringUtils.jar
 libs/jExcel.jar libs/jFileWatcher.jar libs/Archiver.jar
 libs/ByteConverter.jar libs/Encryption.jar libs/OkHttp.jar
 libs/jNxtReportsB4J.jar libs/ABPDFBox.jar libs/jFX8Print.jar
 libs/pngtastic-1.1.jar libs/microsoft-translator-java-api-0.6.2-jar-with-dependencies.jar libs/prettytime-4.0.1.Final.jar
 libs/commons-lang3-3.4.jar libs/jetty_b4j.jar libs/c3p0-0.9.5.2.jar
 libs/c3p0-oracle-thin-extras-0.9.5.2.jar libs/mchange-commons-java-0.2.11.jar libs/jxl.jar
 libs/okhttp-3.5.0.jar libs/okio-1.11.0.jar libs/pdfbox-app-2.0.8.jar
 libs/jfx.jar libs/nextreports-engine-9.1.jar libs/commons-jexl-2.1.1.jar
 libs/commons-logging-1.1.3.jar libs/itext-2.1.7.jar libs/itext-rtf-2.1.7.jar
 libs/itextpdf-5.0.6.jar libs/xstream-1.3.1.jar libs/xstream-1.4.7.jar
 libs/poi-3.7.jar libs/mysql-connector-java-5.1.44-bin.jar


Hello Harris.

When I was working on the NextReports library, I asked this question to Erel (since my Java knowledge is next to nil):

https://www.b4x.com/android/forum/threads/next-reports-and-classpath.56991/#post-359040

From what I understood at that time, each time you recompile your project, you need to make the changes in the MANIFEST.MF.
I do not really know if there is way to automatically include the proper folder in the MANIFEST.MF using B4J (or any other tool).


However, Erel also suggested an option about running the file without the -jar parameter.
It's been a long time since, so I do not remember what results I got from this second option (probably I was not succesful, that's why I went with manually editing the MANIFEST.MF file), but you can try it for yourself.
For me, manual edit of MANIFEST.MF was no big issue, since I only used this library once or twice. However, I understand that manually editing the MANIFEST.MF can be trouble.
So, If indeed there is a way to make automatic changes, it would really take out a lof of the hassle.
 
Last edited:

Harris

Expert
Licensed User
#MergeLibraries: False

In my app, the #MergeLibraries: False caused what you see in the manifest.mf. All of the required libraries are to be found in the libs folder.
My normal jar is reduced from 14 meg to 500 k using this method. This is huge when uploading an update to a remote server - particularly over a limited bandwidth connection (sat).

The point is: these are all statements of the Class-Path. The compiler is already doing this - but for jar files only...
Perhaps we could trick it by creating a jar for this purpose that would be added as a path - "./reports.jar" would be where the images are stored.

In your requirements, how does NR know that .\reports\ is the path for IT to use for image location? There could be anything in the class-path that looks like this but nothing specific to NR??? Would it have to be the FIRST item of a class-path???
Weird science...

Thanks
 

Philip Chatzigeorgiadis

Active Member
Licensed User
#MergeLibraries: False

In my app, the #MergeLibraries: False caused what you see in the manifest.mf. All of the required libraries are to be found in the libs folder.
My normal jar is reduced from 14 meg to 500 k using this method. This is huge when uploading an update to a remote server - particularly over a limited bandwidth connection (sat).

The point is: these are all statements of the Class-Path. The compiler is already doing this - but for jar files only...
Perhaps we could trick it by creating a jar for this purpose that would be added as a path - "./reports.jar" would be where the images are stored.

In your requirements, how does NR know that .\reports\ is the path for IT to use for image location? There could be anything in the class-path that looks like this but nothing specific to NR??? Would it have to be the FIRST item of a class-path???
Weird science...

Thanks

OK. Here is an idea.
According to NextReports:

"The code takes care to copy those images to the folder where exported
report is generated (current directory). For HTML that is enough to view images.
For other types like PDF, RTF, DOCX, EXCEL, you will have to add the folder where you copy images to the CLASSPATH (because report images are loaded from classpath)."


Since your code already has the \lib in the classpath, try copying the image files of the report in the \lib folder.
It might just do the trick.

By the way, did you try Erel's second suggestion? (assuming c:\users\ is the folder where the images were copied)

2. Run it without the -jar parameter.

It should be something like:

java -cp <yourjar>;c:\users\* b4j.example.main


As I said, I am not experienced in java, so I did not spend much time trying this option - since the MANIFEST.MF editing provided a satisfactory solution for my purposes.
So, Erel's suggestion might also work.

Please keep me posted about your results.
Thanks.
 

Harris

Expert
Licensed User
Hummm, I can try the libs folder but that is not ultimately where I would prefer to store image files. In fact, the folder would be a property of the user (company - ./comp_93/ ).

Seems classpath is a one time setting... All and any who reference it are bound to the single PATH set.
I don't know how much support - or features the dev of NR is willing to support these days, but it is a request worthy of asking since the current method is (mostly) unworkable.


My post on NR forum - added to same issue...

http://www.next-reports.com/forum/4-support/2313-image-not-found-java-reports-engine.html#3510

Thanks
 
Last edited:

keirS

Well-Known Member
Licensed User
Hummm, I can try the libs folder but that is not ultimately where I would prefer to store image files. In fact, the folder would be a property of the user (company - ./comp_93/ ).

Seems classpath is a one time setting... All and any who reference it are bound to the single PATH set.
I don't know how much support - or features the dev of NR is willing to support these days, but it is a request worthy of asking since the current method is (mostly) unworkable.


My post on NR forum - added to same issue...

http://www.next-reports.com/forum/4-support/2313-image-not-found-java-reports-engine.html#3510

Thanks

You can change the CLASSPATH at run time. See https://www.b4x.com/android/forum/t...amically-at-run-time-using-inline-java.80596/
 

Harris

Expert
Licensed User
http://www.next-reports.com/forum/4-support/2645-dynamic-support-for-image-locations.html#3511

New post above to NR asking for some guidance.

A thought as a work around.... (or permanent solution)

I typically pre-process data to a temp table for reporting purposes anyway. This dramatically reduces the engines work and report complexity.
I could add the required images to a blob (MySQL image type) of my temp table since I know it's name and location. Image files are not big per se (500k - 2meg), so this additional step should be quick. This would be the only time I would store such files in a table (blob) since, over the long term, it is problematic - but perhaps perfect in this situation. Temp tables are dropped and recreated for each new report instance.

There is a Image SQL column as a choice when creating / designing a report.

I shall "report" back with my findings....

You can change the CLASSPATH at run time
If the classpath was changed, is it for the current session? Concurrent users will require different path locations.

Thanks
 

keirS

Well-Known Member
Licensed User
No it's for the JVM. You can in theory unload JAR files from the CLASSPATH as well but that's more complicated.
 

Harris

Expert
Licensed User
I shall "report" back with my findings....
Simple test adding pics to a blob and display with NR Image SQL Column.

Seems this will do fine without having to resort to trying to load from disk path (at this juncture). It takes just a couple of seconds to load the jpg's into the temp table blob (which was mediumblob in MySQL) using the proper method.
B4X:
Sub checkpics

    Dim SQL As SQL = DBM.GetSQL
    Dim users As List = DBM.SQLSelect(SQL, "SELECT * FROM users", Null)
    If users.Size > 0 Then
        Dim user As Map = users.Get(0)
        Dim pics As String = user.Get("s1")
        If pics.Length < 2 Then
            Try
                Dim path As String = File.DirApp & "/www/" & ABMShared.AppName & "/images/dumb"
                Dim fn As List = File.ListFiles(path)

              For i = 0 To 8
                    Dim str As String = fn.Get(i)
                  Dim usr As Map = users.Get(i)
                  Dim pk As Int = usr.Get("userid")
                  
                  Dim InputStream1 As InputStream     ' add images here to a blob as well
                  InputStream1 = File.OpenInput(path , str)
                  Dim OutputStream1 As OutputStream
                  OutputStream1.InitializeToBytesArray(1000)
                  File.Copy2(InputStream1, OutputStream1)
                  Dim Buffer() As Byte 'declares an empty array
                  Buffer = OutputStream1.ToBytesArray
                  Log(" about to add pic to: "&path&"  File: "&str)
                  SQL.ExecNonQuery2("Update users Set pic = ? Where userid = "&pk, Array As Object(Buffer))
                  SQL.ExecNonQuery("Update users Set s1 = '"&str&"' Where userid = "&pk)
              Next
            
            Catch
                  
              Log(" No Such Directory or not enough records exist! "&LastException.Message)
                  
            End Try   
            
        Else
            Log(" Pics are populated")           
        End If
    End If
        
    DBM.CloseSQL(SQL)
    
    
End Sub
 

Attachments

  • NR_blob.JPG
    NR_blob.JPG
    90.9 KB · Views: 250
Last edited:

Harris

Expert
Licensed User
BTW, thanks for helping me see the light.

As for most things we try to accomplish in B4X, there is often an other way to accomplish a task - if the direct approach seems elusive.
Our discussion forced me to expand the scope and explore the alternatives - rather than be narrow minded and hell bent on the initial perception of the problem.

Hopefully, the next time I (we) are confronted with something similar, we shall look to alternates first!

I really like NextReports. I have tried many report tools but you are hard pressed to find others with this simplicity, performance and price. Like B4J - free is hard to beat and this community is priceless!
 

Philip Chatzigeorgiadis

Active Member
Licensed User
Simple test adding pics to a blob and display with NR Image SQL Column.

Seems this will do fine without having to resort to trying to load from disk path (at this juncture). It takes just a couple of seconds to load the jpg's into the temp table blob (which was mediumblob in MySQL) using the proper method.
B4X:
Sub checkpics

    Dim SQL As SQL = DBM.GetSQL
    Dim users As List = DBM.SQLSelect(SQL, "SELECT * FROM users", Null)
    If users.Size > 0 Then
        Dim user As Map = users.Get(0)
        Dim pics As String = user.Get("s1")
        If pics.Length < 2 Then
            Try
                Dim path As String = File.DirApp & "/www/" & ABMShared.AppName & "/images/dumb"
                Dim fn As List = File.ListFiles(path)

              For i = 0 To 8
                    Dim str As String = fn.Get(i)
                  Dim usr As Map = users.Get(i)
                  Dim pk As Int = usr.Get("userid")
                
                  Dim InputStream1 As InputStream     ' add images here to a blob as well
                  InputStream1 = File.OpenInput(path , str)
                  Dim OutputStream1 As OutputStream
                  OutputStream1.InitializeToBytesArray(1000)
                  File.Copy2(InputStream1, OutputStream1)
                  Dim Buffer() As Byte 'declares an empty array
                  Buffer = OutputStream1.ToBytesArray
                  Log(" about to add pic to: "&path&"  File: "&str)
                  SQL.ExecNonQuery2("Update users Set pic = ? Where userid = "&pk, Array As Object(Buffer))
                  SQL.ExecNonQuery("Update users Set s1 = '"&str&"' Where userid = "&pk)
              Next
          
            Catch
                
              Log(" No Such Directory or not enough records exist! "&LastException.Message)
                
            End Try 
          
        Else
            Log(" Pics are populated")         
        End If
    End If
      
    DBM.CloseSQL(SQL)
  
  
End Sub

Cool solution!
It's fine-tuned for your requirements and does the trick!
 
Last edited:

codie01

Active Member
Licensed User
Hi Philip,

I am forced to update my version of Java to accommodate new libraries here, like keystoressl. I have succeed in making the jump except your jnextreports lib. Are you able to recompile it to java 11, or is this library based on jars that wont simply work.

If so then I will need to urgently find an alternative.

Kind Regards Philip
 

Philip Chatzigeorgiadis

Active Member
Licensed User
I
Hi Philip,

I am forced to update my version of Java to accommodate new libraries here, like keystoressl. I have succeed in making the jump except your jnextreports lib. Are you able to recompile it to java 11, or is this library based on jars that wont simply work.

If so then I will need to urgently find an alternative.

Kind Regards Philip
Hello.

Please see the May 2020 update in the first post of this thread: there is an issue with OpenJDK11, which - after a few failed attempts - I quit trying to solve.
As I have stopped working on this library, by the end of the week I will upload my source files, so anyone may have a go at fixing this.
 

codie01

Active Member
Licensed User
Thanks Philip,

ill have a go at it :) you have done a good job, i have had a lot of use out of it! Thanks

Philip
 
Top