Ola
First of all, a great thanks to Alain for his brilliant BANano project, otherwise this feat would not even be close to possible. Above all else, Viva to Erel & B4X! A great thanks!! ?
Anyway, You’re not obligated to win. You’re obligated to keep trying to do the best you can every day. –Marian Wright Edelman
As you have noticed, in the BVAD3 Invoicer WebApp, we used the jsPDF library to generate our document. No, we did not html2canvas / print, we wrote code to generate the invoice template.
I must say the best part of that app also took a very long time to create. The text is not in the right position, nudge it up a little. Change the font etc etc.
Well, here is it. Well we are not there yet, but you can start exploring it. So far we have..
1. pdfDoc
A pdfDoc can contain any child element and pdfPages. Each page is designed as a separate layout and then using BANano.Loadlayout, its appended to the document. You can place any number of pdfText, pdfLine, pdfImage etc.
This is your point of contact for the document, drag this and put it in your layout and then update the settings. Any properties you set in the property bag will be applied when the .Ready call is made. This will be the first page of your document.
Then you can create other pages for your document and put these as single layouts, preferably.
2. jsPDFPage
One of the pages with text and an image. NB: All elements should have UNIQUE names otherwise some googly gook will show on your final document. As noted, each page can have its page size, orientation, font name and text color etc. For the colors, we have a color choose to help you with the RGBs, the contents of the color chooser are not used, its just there to help one choose colors.
In each page, you can add any pdf what what you want, just dont add a pdfPage inside another pdfPage. It wont work, its more simpler like that...
Then you need to open the layout with your pdfDoc and then generate members for it. Just generate for the pdfDoc and other VueElements, any pdf what what like text, circle etc DOES NOT need to be bound with BindVueElement. Internally its just a BANanoElement with data attributes, it renders absolutely nothing. As an example, check this out..
For each element, we just read what is entered in the property bag and then store it as data-attributes, we use these later when we call .Go to create your pdfDocument.
After you create all your pdfPage(s) with their child pdf dash dash dashes, its time to add to the jsPDFDoc by APPENDing the other layouts with jsPDFPage(s) that below to this to the jsPDFDoc.
BTW, if you move any pdfText, pdfImage etc etc OUTSIDE of a jsPDFDOc / jsPDFPage, it wont be written to your pdf document.
So, to merge the pages to the document, on initialize, load the jsPDFDoc layout and append the rest of the pages.
As an example
For our example, we are generating our documents when we click a button, so the code is
And whalla, your pdf document is generated. Isnt that the coolest thing!!
Finally, thanks to this community for supporting this BVAD3 project, testing and reporting bugs and helping out when needed. We are all creating the ultimate coding experience for BANano WebApps, less and less code and more use already existing tools in B4x. That Abstract Designer!
First of all, a great thanks to Alain for his brilliant BANano project, otherwise this feat would not even be close to possible. Above all else, Viva to Erel & B4X! A great thanks!! ?
Anyway, You’re not obligated to win. You’re obligated to keep trying to do the best you can every day. –Marian Wright Edelman
As you have noticed, in the BVAD3 Invoicer WebApp, we used the jsPDF library to generate our document. No, we did not html2canvas / print, we wrote code to generate the invoice template.
I must say the best part of that app also took a very long time to create. The text is not in the right position, nudge it up a little. Change the font etc etc.
Well, here is it. Well we are not there yet, but you can start exploring it. So far we have..
1. pdfDoc
A pdfDoc can contain any child element and pdfPages. Each page is designed as a separate layout and then using BANano.Loadlayout, its appended to the document. You can place any number of pdfText, pdfLine, pdfImage etc.
This is your point of contact for the document, drag this and put it in your layout and then update the settings. Any properties you set in the property bag will be applied when the .Ready call is made. This will be the first page of your document.
Then you can create other pages for your document and put these as single layouts, preferably.
2. jsPDFPage
One of the pages with text and an image. NB: All elements should have UNIQUE names otherwise some googly gook will show on your final document. As noted, each page can have its page size, orientation, font name and text color etc. For the colors, we have a color choose to help you with the RGBs, the contents of the color chooser are not used, its just there to help one choose colors.
In each page, you can add any pdf what what you want, just dont add a pdfPage inside another pdfPage. It wont work, its more simpler like that...
Then you need to open the layout with your pdfDoc and then generate members for it. Just generate for the pdfDoc and other VueElements, any pdf what what like text, circle etc DOES NOT need to be bound with BindVueElement. Internally its just a BANanoElement with data attributes, it renders absolutely nothing. As an example, check this out..
For each element, we just read what is entered in the property bag and then store it as data-attributes, we use these later when we call .Go to create your pdfDocument.
After you create all your pdfPage(s) with their child pdf dash dash dashes, its time to add to the jsPDFDoc by APPENDing the other layouts with jsPDFPage(s) that below to this to the jsPDFDoc.
BTW, if you move any pdfText, pdfImage etc etc OUTSIDE of a jsPDFDOc / jsPDFPage, it wont be written to your pdf document.
So, to merge the pages to the document, on initialize, load the jsPDFDoc layout and append the rest of the pages.
As an example
B4X:
Sub Initialize
....
'build the page html here
banano.LoadLayout(home.Here, "mypdf")
'add the pages to the document NB: use loadlayout append
banano.LoadLayoutAppend(JsPdfDoc1.Here, "mypdfpage1")
banano.LoadLayoutAppend(JsPdfDoc1.Here, "mypdfpage2")
banano.LoadLayoutAppend(JsPdfDoc1.Here, "mypdfpage4")
banano.LoadLayoutAppend(JsPdfDoc1.Here, "mypdfpage5")
banano.LoadLayoutAppend(JsPdfDoc1.Here, "mypdfpage6")
banano.LoadLayoutAppend(JsPdfDoc1.Here, "mypdfpage7")
'
home.BindVueElement(JsPdfDoc1.VElement)
....
End Sub
For our example, we are generating our documents when we click a button, so the code is
B4X:
Private Sub btnSave_Click (e As BANanoEvent)
'if you have specified a font and style, then...
JsPdfDoc1.Ready
JsPdfDoc1.addFont("./assets/mouhitu.ttf", "Mouhitsu", "normal")
JsPdfDoc1.addFont("./assets/Amiri-Regular.ttf", "Amiri", "normal")
JsPdfDoc1.Go
JsPdfDoc1.Save
End Sub
And whalla, your pdf document is generated. Isnt that the coolest thing!!
Finally, thanks to this community for supporting this BVAD3 project, testing and reporting bugs and helping out when needed. We are all creating the ultimate coding experience for BANano WebApps, less and less code and more use already existing tools in B4x. That Abstract Designer!
Last edited: