B4A Class [B4X] PDF Generator - B4X Cross Platform - Class 100% B4X Code

Hi,

This class (cPDF.bas) generate PDF File with limited fonctionnalities (but enough for me)
  • Add pages with different paper size (use constants or custom size)
  • PDF standards font (Courier, Helvetica, Times, Symbol and Zapfdingbats), style (Normal, Bold, Italic, Underline and StrikeThrough), encoding cp1252
  • draw text : single line of text at position x, y
  • draw text flow with explicit and automatic CR at current x,y position with alignment (left, center, right)
  • Measure text (width and height)
  • Measure multiline text (width and height)
  • draw line
  • draw rectangle
  • draw images (only png )
  • use pdf commands directly
  • save to file with/without compression
Source full commented, example for B4J and B4A, I don't use B4I (but should be OK)
dependencies :
  • B4XCollections
  • RandomAccessFile

Help welcome to add support for :
  • png image with spacecolor 6 (alpha channel)
  • jpg image
  • loading font from file

1673250547389.png

1672644892353.png

1672644909961.png

1672644931064.png

1673250525180.png



spsp
 

Attachments

  • 1672644870818.png
    1672644870818.png
    7.1 KB · Views: 570
  • pdfgen.zip
    86.4 KB · Views: 94
Last edited:

ivanomonti

Well-Known Member
Licensed User
Longtime User
i am trying to create a pdf with your class but i have this error

s = "L'amore è come una rosa: ha bisogno di essere curato e nutrito per crescere e prosperare."

while trying to clean the text by changing the text passed with a string type variable it crashes

ERROR:
L
'
a
m
o
r
e
 
è
 


Error occurred on line: 128 (B4XBytesBuilder)
java.lang.ArrayIndexOutOfBoundsException: length=256; index=-24
    at java.lang.reflect.Array.get(Array.java:196)
    at anywheresoftware.b4a.shell.ArraysUtils.getElement(ArraysUtils.java:76)
    at anywheresoftware.b4a.shell.Shell.getArrayElement(Shell.java:584)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:383)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
    at b4a.example.cpdf._gmultilinetextsize(cpdf.java:1233)
    at b4a.example.cpdf._outtextflow(cpdf.java:497)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1114)
    at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1069)
    at b4a.example.as_tabmenuadvanced._tabclickevent(as_tabmenuadvanced.java:1824)
    at b4a.example.as_tabmenuadvanced._xpnl_tab_click(as_tabmenuadvanced.java:1984)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:8160)
    at android.view.View.performClickInternal(View.java:8137)
    at android.view.View.access$3700(View.java:888)
    at android.view.View$PerformClick.run(View.java:30236)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:246)
    at android.app.ActivityThread.main(ActivityThread.java:8625)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
 
Last edited:

spsp

Member
Licensed User
Longtime User
i am trying to create a pdf with your class but i have this error

s = "L'amore è come una rosa: ha bisogno di essere curato e nutrito per crescere e prosperare."

while trying to clean the text by changing the text passed with a string type variable it crashes

ERROR:
L
'
a
m
o
r
e
 
è
 


Error occurred on line: 128 (B4XBytesBuilder)
java.lang.ArrayIndexOutOfBoundsException: length=256; index=-24
    at java.lang.reflect.Array.get(Array.java:196)
    at anywheresoftware.b4a.shell.ArraysUtils.getElement(ArraysUtils.java:76)
    at anywheresoftware.b4a.shell.Shell.getArrayElement(Shell.java:584)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:383)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
    at b4a.example.cpdf._gmultilinetextsize(cpdf.java:1233)
    at b4a.example.cpdf._outtextflow(cpdf.java:497)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1114)
    at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1069)
    at b4a.example.as_tabmenuadvanced._tabclickevent(as_tabmenuadvanced.java:1824)
    at b4a.example.as_tabmenuadvanced._xpnl_tab_click(as_tabmenuadvanced.java:1984)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:8160)
    at android.view.View.performClickInternal(View.java:8137)
    at android.view.View.access$3700(View.java:888)
    at android.view.View$PerformClick.run(View.java:30236)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:246)
    at android.app.ActivityThread.main(ActivityThread.java:8625)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Hello,

Could you post your project ?

spsp
 

ivanomonti

Well-Known Member
Licensed User
Longtime User
@spsp not at the moment, it's a privately funded project, but I can replicate the code as soon as I have the time.
 

ivanomonti

Well-Known Member
Licensed User
Longtime User
@spsp,

title string:
pdf.sProperty(pdf.PropertyAuthor,"spsp"). _
sProperty(pdf.PropertyTitle,m.Get("ms_gpt_01_05").As(String).Trim). _
sProperty(pdf.PropertyKeywords,"B4X,PDF,Cross platform")


string text:
Dim s As String
s=m.Get("ms_gpt_01_05").As(String).Replace(" ",Chr(32)).Replace(Chr(34),"").Trim
Log(s)


B4X:
Private Sub TextToPdf(m As Map)
    
    Dim pdf As cPDF
    'initialize with mm unit
    pdf.Initialize("mm")
    
    'set properties
    pdf.sProperty(pdf.PropertyAuthor,"spsp"). _
        sProperty(pdf.PropertyTitle,m.Get("ms_gpt_01_05").As(String).Trim). _
        sProperty(pdf.PropertyKeywords,"B4X,PDF,Cross platform")
    
    'add a page
    pdf.pageAdd(pdf.pageSizeA4PortraitWidth,pdf.pageSizeA4PortraitHeight)

    'set current position 10mm from the left, 287mm from the bottom
    pdf.sX(10).sY(287)

    Dim s As String

    s=m.Get("ms_gpt_01_05").As(String).Replace(" ",Chr(32)).Replace(Chr(34),"").Trim
    
    Log(s)


    pdf.sFont(pdf.fontHelvetica,pdf.fontNormal,14,pdf.colorBlack)

    pdf.outtextflow(10,200,pdf.AlignCenter,s)

    'save to file with compression if data compressed are smaller
    savePDF(pdf,"test.pdf",pdf.CompressAlways)
    
    'open with default viewer
    openPDF("test.pdf")
    
End Sub
 

spsp

Member
Licensed User
Longtime User
@spsp,

title string:
pdf.sProperty(pdf.PropertyAuthor,"spsp"). _
sProperty(pdf.PropertyTitle,m.Get("ms_gpt_01_05").As(String).Trim). _
sProperty(pdf.PropertyKeywords,"B4X,PDF,Cross platform")


string text:
Dim s As String
s=m.Get("ms_gpt_01_05").As(String).Replace(" ",Chr(32)).Replace(Chr(34),"").Trim
Log(s)


B4X:
Private Sub TextToPdf(m As Map)
   
    Dim pdf As cPDF
    'initialize with mm unit
    pdf.Initialize("mm")
   
    'set properties
    pdf.sProperty(pdf.PropertyAuthor,"spsp"). _
        sProperty(pdf.PropertyTitle,m.Get("ms_gpt_01_05").As(String).Trim). _
        sProperty(pdf.PropertyKeywords,"B4X,PDF,Cross platform")
   
    'add a page
    pdf.pageAdd(pdf.pageSizeA4PortraitWidth,pdf.pageSizeA4PortraitHeight)

    'set current position 10mm from the left, 287mm from the bottom
    pdf.sX(10).sY(287)

    Dim s As String

    s=m.Get("ms_gpt_01_05").As(String).Replace(" ",Chr(32)).Replace(Chr(34),"").Trim
   
    Log(s)


    pdf.sFont(pdf.fontHelvetica,pdf.fontNormal,14,pdf.colorBlack)

    pdf.outtextflow(10,200,pdf.AlignCenter,s)

    'save to file with compression if data compressed are smaller
    savePDF(pdf,"test.pdf",pdf.CompressAlways)
   
    'open with default viewer
    openPDF("test.pdf")
   
End Sub
Hello,

The problem comes from the 'è' char.

I will check the library

spsp
 

spsp

Member
Licensed User
Longtime User
@spsp,

title string:
pdf.sProperty(pdf.PropertyAuthor,"spsp"). _
sProperty(pdf.PropertyTitle,m.Get("ms_gpt_01_05").As(String).Trim). _
sProperty(pdf.PropertyKeywords,"B4X,PDF,Cross platform")


string text:
Dim s As String
s=m.Get("ms_gpt_01_05").As(String).Replace(" ",Chr(32)).Replace(Chr(34),"").Trim
Log(s)


B4X:
Private Sub TextToPdf(m As Map)
   
    Dim pdf As cPDF
    'initialize with mm unit
    pdf.Initialize("mm")
   
    'set properties
    pdf.sProperty(pdf.PropertyAuthor,"spsp"). _
        sProperty(pdf.PropertyTitle,m.Get("ms_gpt_01_05").As(String).Trim). _
        sProperty(pdf.PropertyKeywords,"B4X,PDF,Cross platform")
   
    'add a page
    pdf.pageAdd(pdf.pageSizeA4PortraitWidth,pdf.pageSizeA4PortraitHeight)

    'set current position 10mm from the left, 287mm from the bottom
    pdf.sX(10).sY(287)

    Dim s As String

    s=m.Get("ms_gpt_01_05").As(String).Replace(" ",Chr(32)).Replace(Chr(34),"").Trim
   
    Log(s)


    pdf.sFont(pdf.fontHelvetica,pdf.fontNormal,14,pdf.colorBlack)

    pdf.outtextflow(10,200,pdf.AlignCenter,s)

    'save to file with compression if data compressed are smaller
    savePDF(pdf,"test.pdf",pdf.CompressAlways)
   
    'open with default viewer
    openPDF("test.pdf")
   
End Sub
Hello,

Bug is fixed, ZIP file in post #1 updated. (only cPDF.bas file has been changed)

Thanks for reporting this bug to me.

spsp

spsp
 

ivanomonti

Well-Known Member
Licensed User
Longtime User
Hello,

Bug is fixed, ZIP file in post #1 updated. (only cPDF.bas file has been changed)

Thanks for reporting this bug to me.

spsp

spsp
I can't find the zip
 

Almora

Active Member
Licensed User
Longtime User
Hello.

I'm testing this library right now. It's simple and fun to create pdf.
However, I have a problem to solve.
Namely, I have text for several pages. Now, when I insert a longer text, the page ends, the text as much as possible is on the PDF, the rest is not. How to detect the end of a PDF page so that further text goes to the next page?
how can we do this..
 

MichalK73

Well-Known Member
Licensed User
Longtime User
how can we do this..
I was looking for a PDF generator for printing from a web server. I couldn't wait for someone to correct or add pagination or other things. I used Python which has very good and rich libraries to generate PDF. I combined B4J with Python code execution and the generated PDF is now available in B4J.
As I do it will not work with B4A.
 
Top