Documentation for PDFColumns
By Stephen Joys Aug 11th 2020PDF Columns is wrapper for jsPDF that is still written as code but has an easier document formating system to produce clean PDF documents with autobuilt columns, styles and images. while jsPDF does not allow for zorder of printing, this app can work around it and print images and background colors behind text
In this first example, let's create a new document, add a background image, add some text and save.
//starting document let pdf = new PDFColumns("filename"); await PDFLoadImage(pdf,'background',"back_image.png"); await PDFLoadImage(pdf,'robocat',"doraemon.png"); pdf.dim.left= 14; //adjust the margins before adding pages //add background before loading first page; // add a page with auto-numbering and background pdf.newPage(); // writes following main page dimensions set in pdf.dim pdf.nline("here is some text"); pdf.nline("and some more"); pdf.cimage("robocat"); pdf.save(); //opens download dialog for user to get the file
Adding columns to document
Next we can add down-flowing columns to the document: this code creates a new PDFColumns document and uses the col() or 'columns' to generate two side-by-side columns for writinglet pdf = new PDFColumns("filename"); pdf.newPage(); //do variable loading as above pdf.col(2); // create two side by side columns of equal size total 100% of print range pdf.nline("write text in first column"); pdf.nline("keep writing next line down on same column"); pdf.next(); //swaps to next col in this group pdf.nline("write text in the second column at its starting point"); pdf.next(); //cycle back to the first column); pdf.end(); pdf.save();
Nested columns
We can also nest columns infinitely. in this example we will create a set of 3 columns in the first large column. Some flags are sent with the text to allign the text in the middlelet pdf = new PDFColumns("filename",{align:"center"}); pdf.newPage(); pdf.nline("document title at top of page"); pdf.col(2); // create two side by side columns of equal size total 100% of print range pdf.nline("below are nested columns"); pdf.col(3,[2,5,5]); // 3 columns spliting parent column space in ratio 2,5,5 pdf.nline("1st small",{align:"center"}); pdf.nline("data 1",{align:"center"}); pdf.next(); pdf.nline("2nd column",{align:"center"}); pdf.nline("data 2",{align:"center"}); pdf.next(); pdf.nline("3rd Column",{align:"center"}); pdf.nline("data 3",{align:"center"}); pdf.end(); pdf.next(); //back to top columns set //lets make a grid using arrays pdf.col(4); for(let i = 0;i<4;i++){ for(let j = 0;j<4;j++){ pdf.nline(""+(i*4+j+1)); pdf.next(); } } pdf.end(); pdf.end(); pdf.save();
Styles
Next the formatting avaliable for jsPDF, like text color, font, size, line color, etc. has been organized into 3 functions that can save collections of styles by name and apply new or saved styles quickly// create a style but dont apply it, simply save it as default to be accessed later // by virtue of being the first one given by the user, this is set as default pdf.addStyle({name:"mytext",font:"verdana",fontsize:10,fontstyle:"bold", color:"#000000"}); pdf.style(); //applies last kept style as single 'previous style' (no full history) pdf.nline("style();"); pdf.style("mytext"); //applies named style saved previously, keeps this style as fallback pdf.nline("mytext"); pdf.style({color:"#0000FF"},1); // applies new style, doesn't save as fallback pdf.nline("red"); pdf.style(); //returns to previous pdf.nline("black like mytext again"); pdf.style({name:"newstyle", {color:"#0000FF"}); //saves, applies, and saves as fallback pdf.style({fontsize:14}); // applies, and saves as fallback // applying styles does nothing to keys not present, so clearing styles means // applying a style with all keys accounted for (user could make a detailed style called "default") // and apply that to clean out the odd spacing or colors pdf.nline("this text is altered by last styles applied");
Border and Fill
Another type of style tag are border and fillcolor, that affects currently active column and unlike jsPDF will be correctly applied behind flowing text and images after everything is writtenpdf.col(2); pdf.style({border:"#00FF00"}); // this style is fixed onto the active column pdf.nline("this column will be bordered by a colored box"); pdf.next(); pdf.style({fillcolor:"#FF0000",color:"0000FF"});//fill and change text color pdf.nline("this column will be filled in with color"); pdf.end();
Page loading
Pages are added when needed and their pagenumber is added (see this.pagenumber.x , y for location)let pdf = new PDFColumns("filename"); var test = await PDFLoadImage(pdf,'background',"back_image.png"); pdf.pagecounter.y-=10; // can fix x and y to appropriate location pdf.dim.left+=5; pdf.dim.bottom+=5; pdf.newPage(); pdf.col(2); for(let c = 0;c<2;c++){ for(let i = 0;i<200;i++) pdf.nline("This is column "+(c+1)+" and line "+i); pdf.next(); } pdf.end(); pdf.save();
Building tables
Here are a few examples where we build tables for objects and object arraysfunction example7generator(pdf, data){ pdf.col(1);//wrapper pdf.style("table");//creates full table border let keys =null; //passed array of objects if (Array.isArray(data)){ //gather all keys from the objects within the data array keys = Object.keys(data[0]); let filter_keys =[]; data.forEach(row => { //find kes that arent in current list then concat them filter_keys = new Set(keys); keys = keys.concat(Object.keys(row).filter(key => !filter_keys.has(key))); }); //passed single object }else{ keys = Object.keys(data); } pdf.col(keys.length);//print header for keys table keys.forEach(head => {pdf.style("tableheader");pdf.nline(head); pdf.next()}); pdf.end();//end header for(let i = 0;i<(Array.isArray(data)?data.length:1);i++){ pdf.col(keys.length);//by starting and ending columns each row we can have row borders,otherwise omit keys.forEach(head => { pdf.style("tableline"+(i%2)); pdf.nline((Array.isArray(data)?data[i][head]:data[head])); pdf.next(); }); pdf.end(); } pdf.end();//wrapper }
// start pdf and add some table styles that show borders and background-color (fillcolor) let pdf = new PDFColumns("filename"); pdf.addStyle({name:"table",border:"#000000",font:"verdana"}); pdf.addStyle({name:"tableheader",fillcolor:"#DDDDDD",fontstyle:"bold"}); pdf.addStyle({name:"tableline0",fillcolor:"#ffffff",fontstyle:"normal"}); pdf.addStyle({name:"tableline1",fillcolor:"#f4f4f4"}); pdf.newPage(); //do variable loading as above // lets put a single object through a column generator let data = {name:"BMW #005", type:"car", cost:"$36,000", color:"black"}; example7generator(pdf,data); pdf.nline(); // Now lets make an array of objects to pass through // a column generator data= [{name:"horse",color:"brown",speed:"fastest",size:"huge"}, {name:"dog",color:"white",speed:"fast",size:"big"}, {name:"cat",color:"orange",speed:"meh",size:"small"}, {name:"mouse",color:"grey",speed:"slight",size:"tiny"}]; example7generator(pdf,data);//same as above pdf.nline(); //simple generator for object arrays let keys =Object.keys(data[0]); pdf.col(1);//wrapper pdf.style("table");//creates full table border pdf.col(keys.length);//animal, size, color etc... //print header keys.forEach(head => {pdf.style("tableheader");pdf.nline(head); pdf.next()}); //write rows for(let i = 0;i{ pdf.style("tableline"+(i%2)); pdf.nline(data[i][head]); pdf.next()}); } pdf.end(); pdf.end();//wrapper*/ pdf.nline(); //Last lets fee some data from the styles we have given the PDFColumns pdf example7generator(pdf,pdf.styles); pdf.save();
Inserting Pictures
pictures loaded in can be placed on page with cimage and cbimage (which appends flag background to flags) Pictures can be back or inline with text, be given own size or "auto" to scale with column sizelet pdf = new PDFColumns("filename"); await PDFLoadImage(pdf,'robocat',"doraemon.png"); // add a page with auto-numbering and background pdf.newPage(); pdf.nline(); pdf.col(3,[3,5,3]); pdf.next(); pdf.style({border:"#FF0000"}); pdf.cbimage('robocat'); pdf.nline("This cat was a robot sent to the past to protect and teach an important scientist before he grows up; sent by the man himself from the future",{wrap:true, align:"center"}); pdf.end(); pdf.col(3); // fill with color and with background image pdf.style({fillcolor:"#FF0000"}); pdf.cbimage('robocat'); pdf.nline("write over",{align:"center"}); pdf.next(); //add border around, and image is inline with text pdf.style({border:"#00FF00"}); pdf.cimage('robocat'); pdf.nline("write under",{align:"center"}); pdf.next(); //image has been centered (point of drawing) with background color pdf.style({fillcolor:"#0000FF"}); pdf.cimage('robocat',{height:40, alignx:"center", aligny:"center"}); pdf.nline("write under"); pdf.save();