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

Hi,

This class cPDF.bas (version 0.6 - 2024-01-03) 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, justify)
  • Measure text (width and height)
  • Measure multiline text (width and height)
  • draw line
  • draw rectangle
  • draw images (only PNG, all format that can be loaded with xui.loadbitmap)
  • 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 wih colorspace = 6
  • JPG image
  • loading font from file

1673250547389.png

1672644892353.png

1672644909961.png

1704277206392.png




spsp
 

Attachments

  • 1672644870818.png
    1672644870818.png
    7.1 KB · Views: 811
  • 1672644931064.png
    1672644931064.png
    48.8 KB · Views: 2,406
  • pdfgen.zip
    284.4 KB · Views: 145
Last edited:

ivanomonti

Expert
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

Active 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

Expert
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

Expert
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

Active 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

Active 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
 

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.
 

ProjectGroup19

Active Member
Licensed User
I'm unable to display png images like the attached image in the pdf. Could I be doing something wrong??
B4X:
pdf.outImage(xui.DefaultFolder,"test 2022.png",10,20,180,180)
 

Attachments

  • test 2022.png
    test 2022.png
    214.3 KB · Views: 126
Last edited:

DonManfred

Expert
Licensed User
Longtime User
I'm trying to add the attached image to the pdf
Does the example provided work for you? For me it is working...

You have adapted the manifest of your app to add FileProvider? AND you are using fileprovider-Library?

Upload a small project showing the problem. Hard to guess anything on the informations you provided.
 

josejad

Expert
Licensed User
Longtime User
I'm unable to display png images like the attached image in the pdf
I think you should have created a new thread indicating you're using this library.

I've not used it, but as far as I can see, the file has to meet a few requirements.

Looking the properties of your file, they seem to be different than the image in the example. Try to play with you file

1685612681716.png
 

ProjectGroup19

Active Member
Licensed User
I think you should have created a new thread indicating you're using this library.
Noted
I've not used it, but as far as I can see, the file has to meet a few requirements.

Looking the properties of your file, they seem to be different than the image in the example. Try to play with you file

View attachment 142507

The cPDF version I have states;
draw an image
only PNG


I didn't know PNG with Colorspace= DeviceRGB, DeviceGray or Indexed (palette). Thanks for the clarification :)🙏


I will have to create a new thread on How to convert a PNG image to the DeviceRGB, DeviceGray or Indexed (palette).
 
Last edited:

james_sgp

Active Member
Licensed User
Longtime User
spsp, an awesome library...so easy to use.

But I`m having a little trouble, I`m downloading an image from the internet and saving it as a PNG but it isn`t showing in the PDF file. I am loading PNG`s from assets and they are showing fine.

B4X:
            mp.MediaManager.SetMediaWithExtra(pdfImg, myi.photo, "", CreateMap(mp.MediaManager.REQUEST_CALLBACK: Me))
            Wait For (pdfImg) SMM_MediaReady (Success As Boolean, Media As SMMedia)
            If Success Then
                Dim x As B4XView = pdfImg
                Dim bmp As Bitmap = x.Snapshot
                Dim Out As OutputStream
                Out = File.OpenOutput(xui.DefaultFolder, "image.png", False)
                bmp.WriteToStream(Out, 100, "PNG")
                Out.Close       
                Sleep(0)
                pdf.outImage(xui.DefaultFolder,"image.png",10,220,0,150)
            End If

Any advice?

Thanks James
 

spsp

Active Member
Licensed User
Longtime User
spsp, an awesome library...so easy to use.

But I`m having a little trouble, I`m downloading an image from the internet and saving it as a PNG but it isn`t showing in the PDF file. I am loading PNG`s from assets and they are showing fine.

B4X:
            mp.MediaManager.SetMediaWithExtra(pdfImg, myi.photo, "", CreateMap(mp.MediaManager.REQUEST_CALLBACK: Me))
            Wait For (pdfImg) SMM_MediaReady (Success As Boolean, Media As SMMedia)
            If Success Then
                Dim x As B4XView = pdfImg
                Dim bmp As Bitmap = x.Snapshot
                Dim Out As OutputStream
                Out = File.OpenOutput(xui.DefaultFolder, "image.png", False)
                bmp.WriteToStream(Out, 100, "PNG")
                Out.Close     
                Sleep(0)
                pdf.outImage(xui.DefaultFolder,"image.png",10,220,0,150)
            End If

Any advice?

Thanks James
Hi,

This library doesn't support all colorspace in PNG image. (see post #10)

spsp
 
Top