We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now


Justify text within AS/400 AFPDS printer file

rbedard65 asked
Medium Priority
Last Modified: 2007-12-19
Is it possible to justify (left and right) printed text on an AFPDS printer file?  I have been forced to use MS WORD/MERGE DOC because I cannot find any way to justify printed text on AS/400.
Watch Question

the only way I can think of doing it is by decalring a field that is the full width of the and placing the text in the middle

here is an ILE example

d text            S             60    inz('Put me in the middle')        
d text1           s                   like(text)                        
D lenOfTxt        S              3  0                                    
D SizeOfFls       S              3  0                                    
c                   eval      lenOfTxt  =%LEN(%trim(Text))              
c                   eval      SizeOfFls =%size(Text)                    
c                   clear                   text1                        
c                   eval      %subst(text1:%int(SizeOfFls/2)-            
c                                          %int(lenOfTxt/2))=            
c                             text                                      
C                   EVAL      *INLR=*ON                                  



Thanks Dave for the quick response but I do not want to use CENTER JUSTIFICATION, I want the left and right hand to start and end at the same location.  Example:

Space  me   out  all  the  way  to  right  hand
Even      if       only       a      few         words

I was hoping there was some sort of keyword on the PRTF DDS or on the CRTPRTF.  Or an RPGLE routine that caluclated the length based on the font and gave a result of how much space to place between each word.   Sounds tricky though.  

The Dave's way work if you use Courrier Font (Fixed width font). but it's really not cute.

For others font i've never been able to justify them, I heard that IBM has another Package that work with AFP which give you tool to calculte a String lenght so you can move you text with  the key word POSITION in you DDS.

If you have time you could make a program that calculate lenght of a string, and paste it in the Forum ;) !!

I'm really interrested to know, if someone found a way !!


Thats the trick...how to calculate the length of a string when using a non-fixed font.  Also, whether or not a letter is upper case or lower case makes a big difference in the size.  My guess the answer lies in some Java procedures/code/utilities.  Maybe there are some JAR files/classes out there that convert as/400 data to true "word" document data.  
The other problem we have run into is how to underline and/or bold one word in a sentence.  
I can use OVERLAYS and PAGE SEGMENTS for data that doesnt change, but can't for variable data.

You could always made a ratio like how many "i" goes in a inch
and with

  when @car = 'i'
     @len = @len + .1

but that really a weird methode to get what you want.
Java is a good Idea !! I know ni VB you can know the length of a string (not the number of caracter). So i guess that they have it in Java too.


That sounds like fun.  You would need a size (.1, .2, .3 etc..) for every lower case letter, every upper case letter, every number, every punctation and for each font you use.   I'll stick to using Word/Merge document.  It saved us a lot of programming time.  
This sounds like a good challenge,
 I am very busy at work at the moment (hence not my usual participation level) but if you can wait a few days.
Can you please do the following?
Print a sample document containing:

L then 50 spaces then L
l then 50 spaces then l
R then 50 spaces then R.
r then 50 spaces then r.

Once printed measure (fairly accurately, but to the nth degree, the distance between the start of the first character and the start of the last character).

Let be know the results.
I will try to write an algorithm to work it out.



OK..I can do that along with what font/size I used....just curious..why just those letters?  Are their groups of letters that pretty much have the same size?  What about an upper case 'W'...and dont you need to know the size of one space because not all spaces are the same size, depending on the font used.  

Well if you write algorithm return the Size in Centimeter plz, it's the futur ;)

Does anybody know if ISO(Or something like RFC...) exist for Standard Font like Courrier, Arial, MS Serif....

If yes we could have the lenght of each caracter !!


Here are my results in millimeters.

This is using a TIMES NEW ROMAN, point size 13 (font # 2308 on AS/400).

L to L w/50 spaces     7.1 mm
l to l w/50 spaces       6.9 mm
R to R w/50 spaces    7.1 mm
r to r w/50 spaces      6.95 mm
W to W w/50 spaces   7.2 mm
w to w w/50 spaces    7.05 mm

Not sure what all this means....
I have a basic solution that you may want to look at.
Send me an e-mail to my EE address (see my profile) it is written for V5.2
I will send the source and a file as a save file.
We can then develop a better solution we we have more time.


Hi again

A quick overview on what I have done.
There is a file that holds a font id, based on length and characters with and approximate length. I set it up in about 30 minutes.

I have quickly (alternate name for badly) written a few programs

1) Maintain fonts and character widths, print sample document for estimating character width, and print a justified print. The initial characters are added via DFU. It allows the copy of font ids

2) A service program that does the main business. It currently only deals with single lines but if we decide to go further we can make it sexy I have some good ideas and when I have more time I am going to work on this and a little pet project.

The only reason it needs V5.2 is some of the programming techniques I have used – it should be easy to convert to V5.1

The basic way it works is:

Using the file (I have based the font widths on per 50 but this is configurable) the service program calculates an approximate width of each character.

Some defaults are then set.
Text is passed – the program calculates the spacing required

Finally your programme requests each character, the service program returns the character along with the column where to print. Your application then prints the character in the position required.

It may be a bit CPU intensive for large documents but I have tested and it does work.

I am not that bothered if it is not the solution you require I have really enjoyed working out a solution / work round; it’s nice to get the old grey matter working.



This sounds like it has potential.    If I had a file that had the font id and each char. including a blank, and it's size, I could then calculate the total length of a string.  Subtract that from the total space on a line I have available.  Then divide that result by the number of words...that should give me approx. how much space between each word.  
Unlock this solution and get a sample of our free trial.
(No credit card required)


Thanks Dave...Good stuff!
Just a quick note on the above.
In the file the first element (C001) should be a space ie blank. Then next bank indicates that there are not more values to process.

The sample print prints
H then 50 characters then H.
I measure from the end of the first H to the start of the last H. I think the distance of 50 characters should give a good indication of the font size ie if you are 1mm out in the measurement then when the program comes to calculate the font width it will be 1/50th of a millimeter out that is a small value.

When using a different point for a spacific font you can copy the font id, change the print file for the new font, do a few measurements on some characters if the %age is consistant then simply write a pgmto increase the value.


PS I did enjoy this.
Hi all
here is a new procedure to put intom the service program
Once you have loaded the font and set the defaults you cal call it with a large string and optionally a start position.
It will return how many bytes can be fitted onto a line.

This will enable you to build up a large string in your pgm and then get the justification program to format it.

  ** Returns the nuber of characters that will fit onto 1 line                
  ** Returns -1 if an error occurred                                          
  ** text - Text to format                                                    
  ** Start Position (1 to Len of text) Optional                                
 dfnTextToPrint    PR             5  0                                        
 d Text                       32726    Const Options(*varSize)                
 d StartPos                       5  0 Const Options(*NoPass)                  

 ** Returns Text that will fit onto 1 line                                                
 ** Returns -1 if an error occurred                                                        
 ** text - Text to format                                                                  
 ** Start Position (1 to Len of text)                                                      
pfnTextToPrint    b                   Export                                              
dfnTextToPrint    PI             5  0                                                      
d Text                       32726    Const Options(*varSize)                              
dzStartPos                       5  0 Const Options(*NoPass)                              
 ** work fields                                                                            
d StartPos        S              5  0                                                      
d i               S              5  0                                                      
d i1              S              5  0                                                      
d NbrChars        S              5  0                                                      
D LastSpace       S              5  0                                                      
D Len             S              5  0                                                      
d size            S              7  3                                                      
D Byte            S              1                                                        
 ** Set Start Position                                                                    
c                   If        %parms=2                                          
c                   eval      StartPos = ZstartPos                              
c                   else                                                        
c                   eval      StartPos = 1                                      
c                   Endif                                                      
 ** Start > length ? - then return an error                                    
c                   eval      Len=%len(%trim(Text))                            
c                   if        StartPos > Len                                    
c                   Return    -1                                                
c                   endif                                                      
 ** Calculate the number of characters that will fit onto 1 line                
c                   clear                   size                                
 ** calculate total size of field                                              
 ** we do not need to take into account the first character                    
 ** as this is not justified                                                    
c                   for       i=StartPos to Len                                
c                   eval      Byte= %subst(text:i:1)                            
 **  I am nmot sure if lookup / or scan is fastest (I think scan is)            
c**                 eval      i1=%lookup(Byte:char)                            
c                   eval      i1=%scan(Byte:chards)                            
 ** use average when character not found                      
c                   if        i1=0                            
c                   eval      size = size + average          
 ** use average when character width is zero                  
c                   elseif    Width53(i1)=0                  
c                   eval      size = size + average          
 ** use calculated width                                      
c                   else                                      
c                   eval      size = size + Width53(i1)      
c                   endif                                    
 ** If size >= page width then exit                          
C                   if        Size >= PageWidth              
c                   leave                                    
c                   endif                                    
 ** Accumulate Character Count                                
c                   eval      nbrChars = NbrChars + 1        
 ** store the last space                                      
c                   if        Byte=' '                        
c                   eval      lastspace=i                    
c                   endif                                    
c                   endfor                            
c                   if        lastspace<>0            
c                   Return    LastSpace                
c                   else                              
c                   Return    nbrChars                
c                   endif                              
pfnTextToPrint    e                                    
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept daveslater comment as answer

Please leave any comments here within the next four days.

Page Editor
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.