Page 1 of 1

Printing reports and stuff right away from a SmartBasic program

Posted: Mon Jul 09, 2018 3:54 pm
by Henko
A technique has been developed to print reports, generated in a SB program, straight to a default printer of a PC system. The "technical" part of the method is described in the "Other Topics" section of the forum.

In this post, the technique is used to print adequate reports. The technicallities are hidden in 3 functions. As one picture can tell more than a lot of words, the following picture shows a good looking report (although the content of this one is rubbish).
IMG_1532.JPG
IMG_1532.JPG (2.2 MiB) Viewed 8254 times
Each page of the report carries an identification header, stating the date/time it was printed, the report title, and a page number.
Furthermore the column descriptions are repeated on each page. They may consist of 1 or two lines (or zero, then column descriptions are omitted)
After this the page is filled with the information lines.
If the number of lines generated exceed the maximum on a sheet, the headline info is repeated on the next sheet.
The entire report is packed into one string. When the report is finished, the built report string is sent via WiFi to the PC to be printed on the default printed.

There are 3 functions to accomplish this:

"Iprt" - An initialization function, to be used once for each report, prepares the header strings, starts the report string, and does some initializations voor the line printing function.

"Prt" - adds one line to the report string, and insets the header info into the report string when the end of sheet is detected.

"Eprt" - sends the report string (or any other string supplied by the calling code) to the printer, using the technique, outlined in the "Other Topics" section.

Proper inserts of the heading info on each page depends on the value of the "lpp" (lines per page) value when invoking the "lprt() function. This value, in turn, depends on the settings of the Windows "Notepad" program, with respect to font and font size. The best way is to use the little testprogram in the "Other Topics" section. It prints horizontally and vertically over the sheet boundary. In this way the values of "cpl" (# characters per line) and "lpp" (lines per page) can simply be established for given settings.

Code: Select all

' Demo program, generates a multipage report with rubbish content
' and demonstrates the use of the three print functions to print
' the report on the default printer of a PC system.
' The three function follow the test program, together with some 
' auxiliary functions.
'
dim col_head$(3),lin$(100)
rname$="Spare parts in stock at Newport"  ' title of the report
restore to columns
for i=1 to 1 ! read col_head$(i) ! next i  ' column headings
columns:
data " Code   Description  Quantity   Price"
data "  nr      of item    in pieces  $/pc"
restore to lines
for i=0 to 4 ! read lin$(i) ! next i  ' 5 lines with random content
lines:
data "  xxx    fuhvhijfxd       328   20.45"
data " gyyy       fcjkhjk        42   48.00"
data "  sde      d bmiddg      1523    4.99"
data "  sdu       hfc hhj       469    3.50"
data " umkj     fmoputdsn         5  120.40"
l$ = " cccc     ddddddddd       nnn   nn.nn"
for i=5 to 60 ! lin$(i)=l$ ! next i  ' additional lines to exceed
                                     ' the length of one sheet
' initialization of header info, # lines per sheet, and
' # characters per line (used to centre the title, and 
' cut off the title in case it is too long
'
iprt(rname$,col_head$,58,70)
'
' generate 60 lines, which is enough to exceed one sheet
'
for i=0 to 60 ! prt(lin$(i)) ! next i
'
' print the report on the screen, if desired
'
print prt.t$
'
' print the report on the printer
'
' eprt(prt.t$)
end

' initialisation for printing a report
' rname$ = report title, is printed on each page
' col_head$() = 0, 1 or 2 strings with colomn headers
' lpp = # of lines per page
' cpl = # of characters per line
'
def iprt(rname$,col_head$(),lpp,cpl)
ob=option_base() ! option base 1
set output font size int(1250/cpl)
'                 make report header
prt.rn$=date_time$() ! ld=len(prt.rn$) ! av=cpl-ld-8
lr=len(rname$) 
if lr>av-4 then ! rname$=left$(rname$,av-4)! lr=av-4 ! end if
sp=(av-lr)/2
prt.rn$&=ft$(sp+lr,rname$)&ft$(sp+5,"page ")
'                make columns headers
prt.header$=""
h1$=col_head$(2-ob) ! lh1=len(h1$)
h2$=col_head$(3-ob) ! lh2=len(h2$)
if lh1 then prt.header$ &= h1$ & lf$()
if lh2 then prt.header$ &= h2$ & lf$()
'                underline the column headers
sp$="" ! ns=min(lh1,lh2)
for i=1 to ns
  if asc(mid$(h1$,i,1))+asc(mid$(h2$,i,1))>64 then sp$&="~" else sp$&=" "
  next i
if lh1>ns then
  for i=ns+1 to lh1
    if mid$(h1$,i,1)>" " then sp$&="~" else sp$&=" "
    next i
  end if
if lh2>ns then
  for i=ns+1 to lh2
    if mid$(h2$,i,1)>" " then sp$&="~" else sp$&=" "
    next i
  end if
prt.header$ &= sp$
'         initialize some more values for the prt() function
prt.hfix=3+sgn(lh1)+sgn(lh2)
prt.lc=lpp+1 ! prt.lmax=lpp ! prt.page=0 ! prt.t$=""
option base ob
end def

def prt(a$)
if lc>=lmax then
  page+=1 ! lc=hfix 
  t$ &= rn$ & page & lf$ & lf$ & header$ & lf$
  end if
lc+=1 ! t$ &= a$ & lf$
end def

def eprt(t$)
dim h$(3)
h$(1) = "content-type:text/html"
h$(2) = "content-length:"&len(t$)
HTTP "192.168.2.9" HEADER h$ POST t$  ' IP adress of PC
end def

def date_time$()
dim m$(13)
restore to months
for i=1 to 12 ! read m$(i) ! next i
months:
data "january","february","march","april","may","june","july"
data "augustus","september","october","november","december"
y=current_year() ! mo=current_month() ! d=current_date()
h=current_hour() ! mi=current_minute()
dt$=m$(mo)&" "&d&","&y&" "&h&"."&mi&"h"
return dt$
end def

' print formatting of numbers
' n is total fieldwith, -n puts %-sign at end of number
' field starts and ends with one space
' number is right justified if smaller than fieldwith
' number is truncated if larger than fieldwidth
'
def fn$(n,x)
sp$="                             "
if n<0 then p=1 else p=0 ! n=abs(n)
v$=x ! lv=len(v$) ! dp=n-lv-p-2
if dp<0 then v$=left$(v$,lv+dp)
ret$=" " ! if dp>0 then ret$&=left$(sp$,dp)
ret$&=v$ ! if p=1 then ret$&="%" ! ret$&=" "
return ret$
end def

' print formatting of texts
def ft$(n,v$)
sp$="                             "
lv=len(v$) ! dp=n-lv-2
if dp<0 then v$=left$(v$,lv+dp)
ret$=" " ! if dp>0 then ret$&=left$(sp$,dp)
ret$&=v$&" "
return ret$
end def

def lf$ = chr$(13)&chr$(10)