Edit 1/24/21: OK, so what I wound up doing is using a hidden CustomListView and then using the snapshot feature to make a Bitmap, which I then sent to a PDF file. In my real business my partner does all of the reports. I really don't like all of the formatting stuff and my partner loves it.
In any case by carefully formatting the CLV with the the appropriate borders on the boxes, etc. It gave me a nice columnar layout. I only had format the header and and footer. I also had to keep track of the number of rows, and the column and when I filled the page (about 35 rows) "Print" the appropriate column, clear the CLV, and start again.
Here is the relevant code - I have left out the part that fills in the CLV:
The following is some code I used to print the footer - might be useful to someone:
And here is some ugly but effective code I used to fit the text to the views on the CLV - If you have a better solution let me know.
Note - I did not try to print directly. Just create the pdf, I have a seperate button to print and one to share the file externally if the user want to do it some other way - like email it to themselves to print form their home computer.
End of Edit
I need to create a simple phone list for printing. Name, Number, Email on 8 1/2 x 11 paper.
Ideally if I can provide a print button easily as well that would be ideal, but if I can get a pdf/html/rtf file then the user can print it.
I am not familiar with the commands, formatting for any of these things so I will have to figure it out as I go.
I need it to work on B4A and B4i, and ideally eventually B4J as well. I might want to add thumbnail pictures in the future but for now I am looking for simple.
As usual, I find any number of solutions for each platform here, but not for all.
I'm OK writing separate code for each platform if I have to but I thought I would post here first and see if anyone has any suggestions for the best/simplest way to handle this before I head down the rabbit hole of trying everything that;s available..
Thanks in advance for your ideas.
In any case by carefully formatting the CLV with the the appropriate borders on the boxes, etc. It gave me a nice columnar layout. I only had format the header and and footer. I also had to keep track of the number of rows, and the column and when I filled the page (about 35 rows) "Print" the appropriate column, clear the CLV, and start again.
Here is the relevant code - I have left out the part that fills in the CLV:
B4X:
'Code to open the file - Dim pdf As PdfDocument, DestRect As Rect
#If B4A
D = File.DirInternal
#ELSE IF B4I
D = File.DirDocuments
#END IF
If File.Exists(D, "YourFileName.pdf") Then
File.Delete(D, "YourFileName.pdf")
End If
#If B4A
ProgressDialogShow2("Formatting Page 1", False)
pdf.Initialize
pdf.StartPage(612, 792) ' (8.5 in × 11 in).
#ELSE IF B4I
HUD.ProgressDialogShow("Formatting Page 1")
Dim PDFCanvas As Canvas
pdf.Initialize(D, "ALAPhone.pdf")
PDFCanvas.InitializePDF(D, "ALAPhone.pdf", 612, 792)
#END IF
Sleep(1)
'Code to snapshot the scrollview (PrintCLD)
bmp = PrintCLV.sv.ScrollViewInnerPanel.Snapshot
'This determines whether it is column 1 or two
If Y Mod 2 = 0 Then
DestRect.Initialize(40, FPColTop, 305, (LineHeight * PrintCLV.Size) + FPColTop - 10) '(612W, 792H) 297
Else
DestRect.Initialize(305, FPColTop, 572, (LineHeight * PrintCLV.Size) + FPColTop - 10) '(612W, 792H) 297
End If
RowsLeft = TotalRows - X
'Now draw it on the pdf
#If B4A
pdf.Canvas.DrawBitmap(bmp, Null, DestRect)
If (Floor(Y / 2) + 1) > 1 Then pdf.Canvas.DrawText($"(${NumberFormat((Floor(Y / 2) + 1), 1, 0)})"$, (612 / 2), DestRect.Bottom + 30, Typeface.DEFAULT, 5, xui.Color_Black, "CENTER")
If OfficersCB.Checked = True Then
pdf.Canvas.DrawText($"(S)-Secretary, (T)-Treasurer, (L)-Literature, (G)-Group Rep, (A)-Phone List Admin"$, (612 / 2), DestRect.Bottom + 12, Typeface.DEFAULT, 3, xui.Color_Black, "CENTER")
End If
pdf.Canvas.DrawLine(DestRect.Left, DestRect.Bottom, DestRect.Right - 1, DestRect.Bottom - 1, xui.Color_Black, .5)
#ELSE IF B4I
PDFCanvas.DrawBitmap(bmp, DestRect)
If (Floor(Y / 2) + 1) > 1 Then PDFCanvas.DrawText($"(${(Floor(Y / 2) + 1)})"$, (612 / 2), DestRect.Bottom + 40, Font.CreateNew(20), xui.Color_Black, "CENTER")
If OfficersCB.Checked = True Then
PDFCanvas.DrawText($"(S)-Secretary, (T)-Treasurer, (L)-Literature, (G)-Group Rep, (A)-Phone List Admin"$, (612 / 2), DestRect.Bottom + 15, Font.CreateNew(12), xui.Color_Black, "CENTER")
End If
PDFCanvas.DrawLine(DestRect.Left, DestRect.Bottom, DestRect.Right - 1, DestRect.Bottom - 1, xui.Color_Black, 1)
PDFCanvas.Refresh
#END IF
'code to finish a page and start the next page
#If B4A
pdf.FinishPage
' #ELSE IF B4I
' PDFCanvas.NextPDFPage 'B4i only needs NextPdfPage, Not finishpage AND startPAge
#END IF
#If B4A
pdf.StartPage(612, 792)
#ELSE IF B4I
PDFCanvas.NextPDFPage
#END IF
'Code to 'close' the pdf file
#If B4A
pdf.FinishPage
#ELSE IF B4I
PDFCanvas.Release
#END IF
The following is some code I used to print the footer - might be useful to someone:
B4X:
#If B4A
pdf.Canvas.DrawBitmap(bmp, Null, DestRect)
If (Floor(Y / 2) + 1) > 1 Then pdf.Canvas.DrawText($"(${NumberFormat((Floor(Y / 2) + 1), 1, 0)})"$, (612 / 2), DestRect.Bottom + 30, Typeface.DEFAULT, 5, xui.Color_Black, "CENTER")
If OfficersCB.Checked = True Then
pdf.Canvas.DrawText($"(S)-Secretary, (T)-Treasurer, (L)-Literature, (G)-Group Rep, (A)-Phone List Admin"$, (612 / 2), DestRect.Bottom + 12, Typeface.DEFAULT, 3, xui.Color_Black, "CENTER")
End If
pdf.Canvas.DrawLine(DestRect.Left, DestRect.Bottom, DestRect.Right - 1, DestRect.Bottom - 1, xui.Color_Black, .5)
#ELSE IF B4I
PDFCanvas.DrawBitmap(bmp, DestRect)
If (Floor(Y / 2) + 1) > 1 Then PDFCanvas.DrawText($"(${(Floor(Y / 2) + 1)})"$, (612 / 2), DestRect.Bottom + 40, Font.CreateNew(20), xui.Color_Black, "CENTER")
If OfficersCB.Checked = True Then
PDFCanvas.DrawText($"(S)-Secretary, (T)-Treasurer, (L)-Literature, (G)-Group Rep, (A)-Phone List Admin"$, (612 / 2), DestRect.Bottom + 15, Font.CreateNew(12), xui.Color_Black, "CENTER")
End If
PDFCanvas.DrawLine(DestRect.Left, DestRect.Bottom, DestRect.Right - 1, DestRect.Bottom - 1, xui.Color_Black, 1)
PDFCanvas.Refresh
#END IF
And here is some ugly but effective code I used to fit the text to the views on the CLV - If you have a better solution let me know.
B4X:
#If B4J OR B4A
'B4XCod is a BXCode
If MP.BXCod.MeasureTextWidth(NameLbl.Text, NameLbl.Font) > NameLbl.Width Then
Do While MP.BXCod.MeasureTextWidth(NameLbl.Text, NameLbl.Font) > NameLbl.Width
NameLbl.TextSize = (NameLbl.TextSize - 1)
Loop
End If
If MP.BXCod.MeasureTextWidth(Phone1Lbl.Text, Phone1Lbl.Font) > Phone1Lbl.Width Then
Do While MP.BXCod.MeasureTextWidth(Phone1Lbl.Text, Phone1Lbl.Font) > Phone1Lbl.Width
Phone1Lbl.TextSize = (Phone1Lbl.TextSize - 1)
Loop
End If
If MP.BXCod.MeasureTextWidth(EmailLbl.Text, EmailLbl.Font) > EmailLbl.Width Then
Do While MP.BXCod.MeasureTextWidth(EmailLbl.Text, EmailLbl.Font) > EmailLbl.Width
EmailLbl.TextSize = (EmailLbl.TextSize - 1)
Loop
End If
#End If
Note - I did not try to print directly. Just create the pdf, I have a seperate button to print and one to share the file externally if the user want to do it some other way - like email it to themselves to print form their home computer.
End of Edit
I need to create a simple phone list for printing. Name, Number, Email on 8 1/2 x 11 paper.
Ideally if I can provide a print button easily as well that would be ideal, but if I can get a pdf/html/rtf file then the user can print it.
I am not familiar with the commands, formatting for any of these things so I will have to figure it out as I go.
I need it to work on B4A and B4i, and ideally eventually B4J as well. I might want to add thumbnail pictures in the future but for now I am looking for simple.
As usual, I find any number of solutions for each platform here, but not for all.
I'm OK writing separate code for each platform if I have to but I thought I would post here first and see if anyone has any suggestions for the best/simplest way to handle this before I head down the rabbit hole of trying everything that;s available..
Thanks in advance for your ideas.
Last edited: