B4A Library PDFWriter

Hello everyone,

Here is yet another library: PDFWriter.
Linked by user mwhetmore at this topic, you can now create your own PDF files and save them!
The library has 3 declarations:

I. PDFWriter
B4X:
Dim PDFWriter1 As PDFWriter
Declare this in globals so you can benifit from all main methods for writing your PDF File.


1.1 Initialize
B4X:
PDFWriter1.Initialize("PDFWriter1",PaperSize.A4_WIDTH, PaperSize.A4_HEIGHT)

This initializes your PDF writer and gives in an eventname for when the pdf has been created, and it creates a new document with the papersizes than you can choose. (A1, A2, A3, and a lot more!).

1.2 addLine
B4X:
PDFWriter1.addLine(int fromLeft, int fromBottom, int toLeft, int toBottom)

Adds a line to your PDF file. The parameters are self-explanatory.

1.3 addRawContent
B4X:
PDFWriter1.addRawContent(String rawContent)

Adds raw content to your pdf file.
For example: PDFWriter1.addRawContent("0 1 0 rg\n")

1.4 addRectangle
B4X:
PDFWriter1.addRectangle(int fromLeft, int fromBottom, int toLeft, int toBottom)

Adds a rectangle to your pdf file.

1.5 addText
B4X:
PDFWriter1.addText(int leftPosition, int topPositionFromBottom, int fontSize, String text)
PDFWriter1.addText2(int leftPosition, int topPositionFromBottom, int fontSize, String text, String transformation)

This will add text to your PDF file.
The difference between addText and addText2 is that you can add a transformation to your text, see chapter III. PDFStandardFonts.

1.6 ConverseDocument
B4X:
PDFWriter1.ConverseDocument
This wll create you a PDF file. Sub ConversionDone will be raised when the conversion has been done.

B4X:
Sub PDFWriter1_ConversionDone (Content As String)
   PDFContent = Content
   ProgressDialogHide
   ToastMessageShow("Conversion has been done.",False)
End Sub

1.7 CreateNewDocument
B4X:
PDFWriter1.CreateNewDocument(int Width, int Height)
This wll create a new PDF document with the given Width and Height in Papersizes, like in the initialize method.

1.8 newPage
B4X:
PDFWriter1.newPage
This wll create a new PDF page in the same document.

1.9 outputToFile
B4X:
PDFWriter1.outputToFile(String Directory, String FileName, String pdfContent, String encoding)
This will save your pdf content in the given Directory with the given filename with the given encoding.

B4X:
PDFWriter1.outputToFile(File.DirDefaultExternal,"myNewPDF.pdf",PDFContent,"ISO-8859-1")

2.0 outputToScreen
B4X:
PDFWriter1.outputToScreen
This will show your pdfcontent in a label. (note that it won't show the pdf itself but the content!)

B4X:
Label1.Text = PDFWriter1.outputToScreen

2.1 setFont
B4X:
PDFWriter1.setFont(String subType, String baseFont)
PDFWriter1.setFont2(String subType, String baseFont, String encoding)

This will set the font in your PDF file.
The difference between setFont and setFont2 is that you can add a encoding to your text in setFont2, see chapter III. PDFStandardFonts.




II. PDFPaperSizes
B4X:
Dim PaperSize As PDFPaperSizes

With PaperSize you can select, when you create a new document (or with initialize), what paper you would like to use to work with.
Here are all the options:

A0_WIDTH
A0_HEIGHT
A1_WIDTH
A1_HEIGHT
A2_WIDTH
A2_HEIGHT
A3_WIDTH
A3_HEIGHT
A4_WIDTH
A4_HEIGHT
A5_WIDTH
A5_HEIGHT
A6_WIDTH
A6_HEIGHT
A7_WIDTH
A7_HEIGHT
A8_WIDTH
A8_HEIGHT
A9_WIDTH
A9_HEIGHT
A10_WIDTH
A10_HEIGHT
B0_WIDTH
B0_HEIGHT
B1_WIDTH
B1_HEIGHT
B2_WIDTH
B2_HEIGHT
B3_WIDTH
B3_HEIGHT
B4_WIDTH
B4_HEIGHT
B5_WIDTH
B5_HEIGHT
B6_WIDTH
B6_HEIGHT
B7_WIDTH
B7_HEIGHT
B8_WIDTH;
B8_HEIGHT
B9_WIDTH
B9_HEIGHT
B10_WIDTH
B10_HEIGHT
LETTER_WIDTH
LETTER_HEIGHT
TABLOID_WIDTH
TABLOID_HEIGHT
LEDGER_WIDTH
LEDGER_HEIGHT
LEGAL_WIDTH
LEGAL_HEIGHT
STATEMENT_WIDTH
STATEMENT_HEIGHT
EXECUTIVE_WIDTH
EXECUTIVE_HEIGHT
FOLIO_WIDTH
FOLIO_HEIGHT
QUARTO_WIDTH
QUARTO_HEIGHT

III. PDFStandardFonts
B4X:
Dim Fonts As PDFStandardFonts

And to end, you can choose between a lot of available fonts.
I won't put them here, but it varies from Times New Roman, to Courier, and some more.

IV. License

The library is licensed under BSD!
So you just have to mention the author. (not me!)
Author: Javier Santho Domingo ([email protected])


In the attachments, you can find the library files and 2 text files:
A readme.txt and Sample.txt
The project was just to big to upload here at the forum.
So just copy the content of Sample.txt in a new Basic4Android Project and
check the PDFWriter at the right hand pane in the library tab of the IDE, and run the project.

Have fun.

Tomas
 

Attachments

  • PDFWriter1.0.zip
    18.7 KB · Views: 1,554
  • PDFWriter1.1.zip
    25.6 KB · Views: 2,685
Last edited:

Smee

Well-Known Member
Licensed User
Longtime User
Just returned to PDFWriter after a 6 month break. Thanks to gmilias for the response to one of my old questions. I too figured out the rotate issue at some point but your post reminded me of it. If only I could figure out how to add a custom font. I really need to be able to use a script font to add a "fake" electronic signature block to the bottom of the report. I don't need an actual signature...just a cursive/script style to be used in a report. If anyone knows how to do that, it would be appreciated. My other option has been to use a custom font in a label and then capture/save that as an image. I then print that image to the pdf in the signature block. Unfortunately, it's a bit blurry and the corners of the canvas show up. So, that's not really a great option...ha...Being able to print the actual text with a script font would be far better. Thanks!

Hmmm yes we all seem to come back :) Although sorry i cannot help, been looking for something similar myself
 

hibrid0

Active Member
Licensed User
Longtime User
I like to know how can I center a text?
I know this library havent that function, and I try to create one and I cant.
I try something like this:

B4X:
Sub center_text(texto As String)
' Ancho maximo de la hoja en puntos, se resta el tamaño del texto en puntos,luego se divide en 2 el restante y se suma al inicio y al final de la linea.
' Aumento_lados= (papersize.width - text.leght)/2
' Texto_centrado= aumento_lados+text.lenght+aumento_lados

'Dim texto As String
Dim aumento_lados As Int
Dim aumento_espacio As String
Dim texto_centrado As String

aumento_lados= (PaperSize.LETTER_WIDTH - (texto.Length*8))/2

For i= 0 To (aumento_lados/4) -1

    If  i <= aumento_lados Then
    aumento_espacio = aumento_espacio & "_"
    Log(aumento_espacio)
    End If
   
Next

texto_centrado= aumento_espacio &texto & aumento_espacio

Return texto_centrado

End Sub

But I really dont know how I get the font width of my text.
 

luciano deri

Active Member
Licensed User
Longtime User
Problem of dimension in addimage2.
DFWriter1.addImage2(82,23,20,100,firma) give me the same result of
DFWriter1.addImage2(82,23,100,20,firma) and
PDFWriter1.addImage2(282,23,100,100,firma).
Firma is png attached
 

Attachments

  • SGN_OR2015293.png
    SGN_OR2015293.png
    5.9 KB · Views: 221

hibrid0

Active Member
Licensed User
Longtime User
Problem of dimension in addimage2.
DFWriter1.addImage2(82,23,20,100,firma) give me the same result of
DFWriter1.addImage2(82,23,100,20,firma) and
PDFWriter1.addImage2(282,23,100,100,firma).
Firma is png attached

Hi I solve this with this rutine:
LoadBitmapSample, CreateScaledBitmap and I add the code to run the garbage collector for bitmaps.

B4X:
Sub insertar_imagen2 (nombre_imagen AsString, izquierda As Double, arriba As Double)dim img_load asbitmap
img_Logo=LoadBitmapSample("", nombre_imagen,239, 180)

img_Logo=CreateScaledBitmap(img_Logo, 239, 180,True)
PDFWriter1.addImage(mm2Points(izquierda),mm2Points(arriba), img_Logo)
Log("Liberamos Memoria")
Dim Obj1,obj2 AsReflector
Obj1.Target = img_Logo
Obj1.RunMethod("recycle")
End Sub
 

GudEvil

Member
Licensed User
Longtime User
Hi..nice library,
but I have marathi (indian ) text stored in mysql utf-8 encoding . it is retrieved n showen correctely in android. but when I create pdf cant able to see characters.

any help

pdfwriter1.addtext2(fonts.subtype,fonts.times_new_romen,"UTF-8") ?????
pdfwriter1.outputToFile(File.DirRootExternal,"myNewPDF.pdf",Content,"UTF-8") ????

encoding I tried ISO-8859-3 also

can use new fonts with typeface?? n how to use it??

thanks
 

dieterp

Active Member
Licensed User
Longtime User
I have been playing around with adding images today with relative success. What I have noticed is that when I add images that have a transparent background the background colour is set to black. If I change the background colour to white (To blend in with the white background of the pdf report) the report doesn't generate (It hangs with the 'Generating Document' process dialog). Does anyone know if there is a way around this?
 

DARDENNE Marc Soveto

New Member
Licensed User
Longtime User
Tankyou for this very useful lib!
How may I to make a landscape document?
It is possible to define all doc orientation or I will have to rotate every element of the document?

Miquel


It is quite simple
PDFWriter1.Initialize("PDFWriter1",PaperSize.A4_HEIGHT,PaperSize.A4_WIDTH) ' Landscape
instead of
PDFWriter1.Initialize("PDFWriter1",PaperSize.A4_WIDTH,PaperSize.A4_HEIGHT)

imply pass paper size heigtht instead of paper size Width when initializing PDF

Marc
 

rleiman

Well-Known Member
Licensed User
Longtime User
Hi Everyone,

Please explain what PDFWriter1.addRawContent is and what can be entered as parameters and what they are used for.

Thanks.
 

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Here is a PDFWriter Example (also the PDF it outputs)

This example prints a 5 PDF Pages Header / Footer and 3 - 8 player brackets on a page

PLEASE NOTE: There are a LOT of hard coded values in this program. It is just an example PROTOTYPE to see if I could do what I needed to do.

ALSO NOTE: I use dips for all my offsets (not sure if dips are needed or whole numbers work fine. will work that out later)

Enjoy

BobVal
 

Attachments

  • PDFWriterExample.zip
    8.7 KB · Views: 280
  • brackets.pdf
    87.8 KB · Views: 246

rleiman

Well-Known Member
Licensed User
Longtime User
Hi Everyone,

I found out my document width is 612 and I tried to use this coding to figure out the width of some text I want to centre horizontally in the document but it reports the text width is 414 which I believe is larger that it actually is given the fact that the document is 612 wide.

B4X:
Private Sub GetTextWidth(Act As Activity, Text As String, TextSize As Int) As Int
            Dim Cvs         As Canvas
            Dim FmtLabel    As Label
            Dim JavaObj     As JavaObject

            Cvs.Initialize(Act)

            FmtLabel.Initialize("")
            FmtLabel.TextSize = TextSize
            FmtLabel.Text     = Text

            JavaObj = FmtLabel
            JavaObj.RunMethod("setPadding",            Array As Object(0, 0, 0, 0))
            JavaObj.RunMethod("setIncludeFontPadding", Array As Object(False))

            Return Cvs.MeasureStringWidth( FmtLabel.Text, FmtLabel.Typeface, FmtLabel.TextSize)
End Sub

Calling the above function results in the text not positioned in the centre horizontally. It gets placed towards the left side of the document.

Any help would be appreciated.

B4X:
            Dim HeaderText      As String = "This is some test text."
            Dim HeaderSize      As Int    = 14
            Dim HeaderWidth     As Int    = GetTextWidth(Activity, HeaderText, HeaderSize)

B4X:
           PDFWriter1.addText((PaperSize.LETTER_WIDTH-HeaderWidth) / 2, _
                Abs(35dip-PaperSize.LETTER_HEIGHT), HeaderSize, HeaderText)
 

Attachments

  • Screen Shot 2016-02-07 at 09.37.08.png
    Screen Shot 2016-02-07 at 09.37.08.png
    100.6 KB · Views: 185
Last edited:

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I have been doing it this way:

B4X:
Private Sub DoPDF_Footer
       '-------------------------------------------------------------------------------------------------------------------------------------------------------
       '  Output footer text and giving Credit where credit is due
       '-------------------------------------------------------------------------------------------------------------------------------------------------------
  Dim FooterText  As String =  "PDFWriter.jar by Javier Santho Domingo ([email protected])"
  Dim FooterSize  As Int     = 6
  Dim FooterWidth As Int    = GetTextWidth(FooterText, FooterSize, False)

  mPDFWriter.setFont(mPDFFonts.SYMBOL,  mPDFFonts.HELVETICA)
  mPDFWriter.setFont(mPDFFonts.SUBTYPE, mPDFFonts.HELVETICA)

 '-------------------------------------------------------------------------------------
 ' Draw Rectangle at bottom of screen
 '-------------------------------------------------------------------------------------
  mPDFWriter.addRectangle(25dip, DEFINE_START_OF_PDF_FOOTER, (mPDFPaperSize.LETTER_WIDTH-50dip), 15dip)

 '------------------------------------------------------------------------------
 ' Center the above text in the rectangle
 '-------------------------------------------------------------------------------
  mPDFWriter.addText((mPDFPaperSize.LETTER_WIDTH-FooterWidth) / 2, DEFINE_START_OF_PDF_FOOTER + 5dip, FooterSize, FooterText)
End Sub

Public  Sub GetTextWidth(Text As String, TextSize As Int, MonoSpace As Boolean) As Int
  Dim FmtLabel  As Label
  Dim JavaObj  As JavaObject

  FmtLabel.Initialize("")
  FmtLabel.TextSize = TextSize
  FmtLabel.Text  = Text
       
       If MonoSpace Then FmtLabel.Typeface = Typeface.CreateNew(Typeface.MONOSPACE, Typeface.STYLE_NORMAL)

  JavaObj = FmtLabel
  JavaObj.RunMethod("setPadding",  Array As Object(0, 0, 0, 0))
  JavaObj.RunMethod("setIncludeFontPadding", Array As Object(False))

  Return mCanvas.MeasureStringWidth(FmtLabel.Text, FmtLabel.Typeface, FmtLabel.TextSize)
End Sub

I have been using a Canvas to Measure the String width.
NOW I am sure there is a difference in screen verses the printer. But I have only noticed a real minor difference if any.

Hope this works for you

Need to go Superbowl party (Go Packers Go --- Oh wait we didn't make it - Oh well will just have to drink a lot)

BobVal
 

rleiman

Well-Known Member
Licensed User
Longtime User
Got the app to run, but the text in the footer still displays towards the left side and not in the centre. When I use monoface = true the text displays closer to the left side then not using monoface = true.

I'm displaying the PDF on a Mac using the Preview app. I still can't figure out how the pdf file in your post is showing the header and footer text in the centre.

Do you have a sample app that just outputs a header and footer showing the text in the centre that the B4A community can look at.

I appreciate all the time you have taken to upload the coding so far.

Hope you had fun at your party. :)
 
Last edited:

Alberto Michelis

Well-Known Member
Licensed User
Longtime User
Hi, how to draw a rectangle fill with a rgb color?
Or a web page where I can find all the possible raw commands?
Thanks
 

rleiman

Well-Known Member
Licensed User
Longtime User
Using this coding I found out that PaperSize.LETTER_WIDTH gives 612 and HeaderWidth which is returned by GetTextWidth is 1825 which is returned by MeasureStringWidth in GetTextWidth. It seems that MeasureStringWidth is a different scale compared to the number returned by PaperSize.LETTER_WIDTH.

The text string I used is font size 14 and the string is 73 characters long and when the pdf document is viewed it prints across the entire page. I did that to see what number comes back from MeasureStringWidth to resent the entire width of the pdf document.

Is there a way to get MeasureStringWidth and PaperSize.LETTER_WIDTH to show the same number? Once they are the same number, centring text horizontally should be easier for text not spanning the entire document width.

B4X:
            Dim HeaderText      As String = "1234567890123456789012345678901234567890123456789012345678901234567890123"
            Dim HeaderSize      As Int    = 14
            Dim HeaderWidth     As Int    = GetTextWidth(HeaderText, HeaderSize, True)

ToastMessageShow(HeaderWidth,False)
ToastMessageShow(PaperSize.LETTER_WIDTH,False)

B4X:
Sub GetTextWidth(Text As String, TextSize As Int, MonoSpace As Boolean) As Int

    Dim Cvs         As Canvas
    Dim FmtLabel  As Label
    Dim JavaObj  As JavaObject
    Dim intStringWidth As Int

      FmtLabel.Initialize("")
      FmtLabel.TextSize = TextSize
      FmtLabel.Text  = Text
   
    If MonoSpace Then
        FmtLabel.Typeface = Typeface.CreateNew(Typeface.MONOSPACE, Typeface.STYLE_NORMAL)
    End If

      JavaObj = FmtLabel
      JavaObj.RunMethod("setPadding",  Array As Object(0, 0, 0, 0))
      JavaObj.RunMethod("setIncludeFontPadding", Array As Object(False))

    FmtLabel.Text = LTrim(FmtLabel.Text)
    FmtLabel.Text = RTrim(FmtLabel.Text)

    Cvs.Initialize(Activity)
    intStringWidth = Cvs.MeasureStringWidth(FmtLabel.Text, FmtLabel.Typeface, FmtLabel.TextSize)

      Return intStringWidth
End Sub
 

Robert Valentino

Well-Known Member
Licensed User
Longtime User
The PDFWriterExample.zip I posted above is a complete example

I believe that is why I was using 6 for a text size. NOT necessary the text size I was writing out but what I found gave me the right proportions for PDFWriter

My app allows the user to print by creating PDFs (using PDFWriter) or print directly to a Bluetooth printer or IP Address.
When trying to make the code work I had lots of problems printers spacing for centering text as well

As you will see from the code below I choose a 16.6 printer font which came close to lining up with a 6 text size for centering my footer.

B4X:
private Sub DoBT_Footer
  Dim FooterText  As String =  "Bowling Brackets -  Copyright 2013-" &mThisYear &" (c) - Better Office Business Systems (BOBs)"   
  Dim FooterSize  As Int  = 6
  Dim FooterWidth As Int  = GetTextWidth(FooterText, FooterSize, False)
  
'       mBTPrinter.mPCL3.SendESCBytes("(s0p16.66h1s3b4102T")
       mBTPrinter.mPCL3.FontCGTimes(16.6, False)
      
       mBTPrinter.mPCL3.MoveToRow(mBTPrinter.mPCL3.mBitsHigh-25)
       mBTPrinter.mPCL3.CenterText(FooterWidth, FooterText)
      
       mBTPrinter.mPCL3.DrawRectangle(mBTPrinter.mPCL3.mBitsHigh-68, 15)
       mBTPrinter.mPCL3.EjectPaper
End Sub

When trying to write out a Larger font. I used 14pt Arial and while still using the 6 text size to measure in B4A.

The text is close to center but not prefect (good enough for my bowling reports)

B4X:
'----------------------------------------------------------------------------------
'  This CenterText is such a FUDGE job
'  
'  NEED TO RELOOK AT THIS CODE SOMETIME LATER       - Jan 2016
'
'  I am doing whatever it takes to just make my text come close to
'    center for the time being. 
'----------------------------------------------------------------------------------
Public  Sub CenterText(TextWidth As Int, Text As String)
        
       Dim ConvertWidth As Int
       Dim FromLeft     As Int
      
         ConvertWidth = TextWidth * 5.80                           ' Multiple text width by 5.80   '(160dip divided by 300dpi = 5.3 was not enough to work on all centers so bump to 5.8)
      
        FromLeft    = ((300 * 7.5) - ConvertWidth) / 2       ' Paper usable page width times 300dpi
      
#if Debug      
         Log("TW: " &TextWidth &"  CW: " &ConvertWidth &"  FL:" &FromLeft &"  PW:" &(300*7.5))
#end if         


           SendESCBytes3("*p", FromLeft, "X")   'FromLeft, "H")
         Write(Text)        
         Return      
'       End If
  
'       FromLeft = ((mResolution / 75)-ConvertWidth)/2
'       FromLeft = (mBitsWide-ConvertWidth)/2
'       If ConvertWidth > mResolution Or FromLeft < 0 Then FromLeft = 0
  
'       FromLeft = FromLeft * 10
  
'        SendESCBytes3("&a", FromLeft, "H")
'       SendESCBytes3("&a", FromLeft, "R")  
'       SendESCBytes3("*p", FromLeft, "X")
'  
'       Write(Text)
End Sub
      Dim BracketNumWidth    As Int     = GetTextWidth(BracketNum, 6, False)

  mBTPrinter.mPCL3.SendESCBytes3("&u", 300, "D")  ' Set Unit of Measure to 160      
       mBTPrinter.mPCL3.FontArial(14, True)
  mBTPrinter.mPCL3.SendESCBytes4("*p", 35, "x", BracketPosn(0) - 25, "Y")        
       mBTPrinter.mPCL3.CenterText(BracketNumWidth, BracketNum)

I am sure it is just my old age, but I could not come up with a good method for measuring strings that would work with PDF's and Printers dpi
So just took what look OK and moved on with the coding. Once the project is done I will readdress this issues have HUGE block comments says "NEED TO RELOOK AT HOW TO DO THIS BETTER" in hopes I will see them and do something about it.

I do not understand what the Page Width and Height in PDFWriter are representing. I understand what my printer is but do not know how to go from dips to PCL units or Decipoints which my printer wants.

I do not know if ANYTHING I am saying helps you guys. Printing was never my strong suit.


BobVal
 
Top