How to make a PDF file with RPG

page d'accueil
Boite à outils

Cette page a été mise à jour le01 avril2012
Contact

Welcome page
Tools box


FirstPdf.pdf Second.pdf Pdf5  Password is "user" (without the quotes)
These files are demonstrators. They shows what kind of PDF files can be made with RPG from scratch, only by calling typical PDF procedures. The RPG is based on the PDF 1.4 reference book (9Mo) (2001-11-29)

Versionning 

Chart sample (needs version 2010-05-22) :
PdfChart Sample

last version :
How to upload to my 400  
COPY used in my tools (JP4* and more)

 


ADDMSGD  MSGID(PDF0011) MSGF(JPLTOOLS)
MSG('Text font not set')

ADDMSGD MSGID(PDF0012) MSGF(JPLTOOLS)
MSG('Can not encrypt streams greater than 64K')
SECLVL('This image is too big for current version of PDF server')

ADDMSGD MSGID(PDF0013) MSGF(JPLTOOLS)
MSG('The picture is not preloaded, can not export it')

CHGPFM FILE(JPLTOOLS) MBR(JP4PDFSC) SRCTYPE(RPGLE) TEXT('PDF service program C specs- procedures') EXPDATE(*NONE) SHARE(*NO)
CHGPFM FILE(JPLTOOLS) MBR(JP4PDFSD) SRCTYPE(RPGLE) TEXT('PDF service program D specs- private PR & fields') EXPDATE(*NONE) SHARE(*NO)
CHGPFM FILE(JPLTOOLS) MBR(JP4PDFSP) SRCTYPE(SQLRPGLE) TEXT('PDF service program Public PR & fields') EXPDATE(*NONE) SHARE(*NO)

CHGPFM FILE(JPLTOOLS) MBR(JP4PDFS_M) SRCTYPE(RPGLE) TEXT('PDF service program, the blender') EXPDATE(*NONE) SHARE(*NO)
CRTRPGMOD MODULE(JP4PDFS_M) SRCFILE(JPLTOOLS) OPTION(*NODEBUGIO *SRCSTMT *SHOWCPY *SECLVL *EXPDDS) DBGVIEW(*ALL) REPLACE(*YES) TGTRLS(V5R3M0) ENBPFRCOL(*FULL)

CHGPFM FILE(JPLTOOLS) MBR(JP4PDFS) SRCTYPE(RPGLE) TEXT('PDF service program') EXPDATE(*NONE) SHARE(*NO)
CRTSRVPGM SRVPGM(JP4PDFS) MODULE(JP4PDFS*) EXPORT(*SRCFILE) SRCFILE(JPLTOOLS) ACTGRP(JPLTOOLS)
here, something strange : i've forgot to add the bnddir(qc2le), but srvpgm do it's job !

Before compiling JP4PDFD, update the target PDF file names. They are currently located to /home/lamontre: change these 7 lines:
Jpl =pdfpreloadjpeg ('/Home/Lamontre/jpl.jpg');
Logo =pdfpreloadjpeg ('/Home/Lamontre/logo.jpg');
bmp = pdfpreloadbmp24('/Home/Lamontre/rgb.bmp' );
IfsName='/Home/Lamontre/Pdf5a.pdf';
IfsName='/Home/Lamontre/Pdf5b.pdf';
IfsName='/Home/Lamontre/Pdf5c.pdf';
IfsName='/Home/Lamontre/Pdf5d.pdf';
the thee pictures are here:
jpl.jpg
logo.jpg
rgb.bmp
CHGPFM FILE(JPLTOOLS) MBR(JP4PDFD) SRCTYPE(RPGLE) TEXT('Demonstrator for PDF server') EXPDATE(*NONE) SHARE(*NO)
CRTRPGMOD MODULE(JP4PDFD) SRCFILE(JPLTOOLS) OPTION(*NODEBUGIO *SRCSTMT *SHOWCPY *SECLVL *EXPDDS) DBGVIEW(*ALL) REPLACE(*YES) TGTRLS(V5R3M0) ENBPFRCOL(*FULL)
CRTPGM PGM(JP4PDFD) BNDSRVPGM(JP4PDFS) BNDDIR(QC2LE JPLTOOLS) ACTGRP(JPLTOOLS) OPTION(*DUPPROC) TGTRLS(V5R3M0)

These rpg progs are demonstrators. They shows how to make PDF files in RPG from scratch, only by calling typical PDF procedures. These tools have been made based on the PDF 1.4 reference book (9Mo) (2001-11-29) Compressed version available at Adobe site

Nota : read the chapter 1.4 Intellectual Property. As I have understoud, (i'm not fluent in english) anyone can build a PDF file with general Adobe permission. Anyone who uses the copyrighted list of data structures and operators, as stated above [in the Intellectual property chapter], must include an appropriate copyright notice.

Produced file : 

Pdf5 is made by JP4PDFD. Password is "user" (without the quotes). This PDF uses most of the directives proposed by JP4PDFS.

The demonstrator shows most tools to work with text and transformation, and also show mixing pictures and text.



Questions I have received

Rotation

Question received 2009-03-27
This question comes from the SystemINetwork forum : http://forums.systeminetwork.com/isnetforums/showthread.php?t=53991

Hi
I've been writing PDFs from within RPG for some time now using the excellent examples from JPL as a basis. I've just tried to introduce the rotation function and I'd really appreciate a bit of help as to why I cannot get it to work properly. The code below is an extract from my code which successfully prints Rotate 1 correctly at an angle, but totally ignores the instruction to print Rotate 2. It then goes on to happily print further text without rotation.
Any help would be greatly appreciated, as always.
Regards
Paul

myDraw='';                                                
myText='';                                                
myText = myText + PdfTextOpen();                          
// test                                                   
MyText+=PdfStrmSaveGraphicState();                        
myText+=PdfStrmRotate(330);                               
MyText+=PdfTextGoTo(020:400);                             
MyText+=PdfTextFont(PdfCourier:60);                       
MyText+=PdfTextadd('Rotate 1');                   
myText+=PdfStrmRotate(180);                       
MyText+=PdfTextGoTo(022:420);                     
MyText+=PdfTextFont(PdfCourier:60);               
MyText+=PdfTextadd('Rotate 2');                   
MyText+=PdfStrmRestoreGraphicState();

Answer
There are many things to say to comment the PdfReader's issues.
Note : FoxitReader is less sensitive to errors than AdobeReader
You should test your programs with these two readers.

So, what happens ?

There is a physical error

If this PDF has a page after this test page, when you try to read this next page, Adobe send a message saying that there is an error on the page.
What does that means ?
This means Adobe is completely lost, so it has ignored some dirty code.
Why is it lost ?
Because there are page instruction into text instruction.
Page instructions are generated by PdfStrm* functions
Text instruction  are generated by PdfText* functions
In the resulting stream
(MyStream=mydraw+mytext;)
Text instruction always starts with a PdfTextOpen() and are closed by a PdfTextClose().

Opposite, Draw instructions are more tolerant.
You can mix PdfStrm* with PdfDraw* instructions with far less issues.
But issues are not excluded.
When you start using PdfDrawAdd* instructions, take care of using a PdfDrawClose*

There is also a logical error

The origin of each page is, just after PdfNewPage(), at bottom left.
You can PdfDrawGoto or PdfTextGoto as much as you want, this does not change the coordinates of the point of origin

Rotate is in the PdfStrm instruction group.
Rotate is applied on the whole page.
This means that, in your test,
the things you do are
* NewPage
- stick a tack at (0,0)  IE at the bottom left of the page
- set your pencil at (0,0)
* Rotate 300
- set your pencil up
- rotate the page, depending on the tack, to the left of 30 degrees
- set your pencil down
* goto 20 : 400
* add "Rotate 1"
- write "Rotate 1"
  As you can see in your PDF, the text is visible but probably not at the place you was waiting it.
* Rotate 180
- set your pencil at (0,0)
- set your pencil up
- rotate the page, depending on the tack, to the right of 180 degrees
  Try it youself with a true paper sheet : you have your pencil out of the paper
- set your pencil down
* add "Rotate 2"
- write "Rotate 2"
  You write out of the paper



Try this

myDraw='';                                                
myText='';                                                
// avoid mixing PdfText* and PdfDraw* in the same stream, 
// this too much times results in a dirty PDF file        
MyText+=PdfStrmTranslate(200:500);                        
MyText+=PdfDrawAddrectangle(000:000:400:100);             
MyText+=PdfDrawClosePath(pdf_stroke);                     
myText+=PdfTextOpen();                                    
MyText+=PdfTextGoTo(020:040);                             
MyText+=PdfTextFont(PdfCourier:12);                       
MyText+=PdfTextadd('123');                                
MyText+=PdfTextClose();                                   
myText+=PdfStrmRotate(330);                               
MyText+=PdfDrawAddrectangle(000:000:400:100);             
MyText+=PdfDrawClosePath(pdf_stroke);                     
myText+=PdfTextOpen();                                    
MyText+=PdfTextGoTo(020:040);                 
MyText+=PdfTextFont(PdfCourier:12);           
MyText+=PdfTextadd('456');                    
MyText+=PdfTextClose();                       
myText+=PdfStrmRotate(180);                   
MyText+=PdfDrawAddrectangle(000:000:400:100); 
MyText+=PdfDrawClosePath(pdf_stroke);         
myText+=PdfTextOpen();                        
MyText+=PdfTextGoTo(020:040);                 
MyText+=PdfTextFont(PdfCourier:12);           
MyText+=PdfTextadd('789');                    
MyText+=PdfTextClose();                       
MyStream=PdfStrmSaveGraphicState()            
   + mydraw+mytext                            
   + PdfStrmRestoreGraphicState();            

More details :

 

Blank text

I've set the text with PdfTextAdd, I can select it under Adobe reader, but it shows blank text.

I can see the text correctly with Foxit

There is a missing PdfTextClose after the PdfTextAdd.


The source code is provided as an open source tool under the GNU General Public License, version 2.  In summary, this license specifies:

By clicking the download link you acknowledge and agree to the terms of the license.

Download the (zipped) SAVF containing the JPLTOOLS : the source file, the message file, the bnddir

THIS TOOLBOX IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROVIDER OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS TOOLBOX, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.