You can use SinglePageTemplate instead of DocumentBuilder for single page document generation. The SinglePageTemplate class provides a specialized api that simplifies the generation of single page documents.

You can read more about FO elements at datypic.

1 Lambda template functions

The SinglePageTemplate defines 7 FOP area blocks. From those,

  • Five are specifically related to FOP regions (start, end, before, after, body).
  • One is specifically designed to setup document (root).
  • and one is designed for last page body flow content (bodyfootnote).

You can setup a javascript lambda function to provide configuration and content for each of those area blocks. This method simplifies the process of document generation as you will only need to focus on each concrete area.

Section Argument Description
Root FOPRoot Provides a way to setup document layout. This function is called first and it's not specifically related to any FOP area but a way to configure the document.
Start FOPStaticContent Defines the content of start region, repeated on each page.
End FOPStaticContent Defines the content of end region, repeated on each page.
Before FOPStaticContent Defines the content of before region, repeated on each page.
After FOPStaticContent Defines the content of after region, repeated on each page.
Body FOPFlow Defines the content of body flow.
BodyFootNote FOPFootNote Defines the content of body footnote section. This is a block displayed at the end of the body flow.

2 Basic page layout

Let's start generating a simple page layout. We will setup debug("*") with indicates we want to highlight (mark) all FOP components.

For better understanding you should use debug during layout prototyping and even look on FOP xml content.

Copy
<script>

    var template = new Ax.fop.SinglePageTemplate("A4");
    
    // =======================================================================
    // CONFIGURE FOP ROOT LAYOUT
    // =======================================================================
    
    template.setRoot(root => {
        // setup debug on all components
    	root.setDebug("*");
    	root.getSimplePageMaster().getRegionBefore().setExtent(8.5);
    	root.getSimplePageMaster().getRegionAfter().setExtent(1.5);
    	root.getSimplePageMaster().getRegionStart().setExtent(1.0);
    	root.getSimplePageMaster().getRegionEnd().setExtent(1.0);
    	root.getSimplePageMaster().setMargins(0, 0, 0, 0);
    });
    
    // ====================================================================
    // GENERATE PDF
    // ====================================================================
    
    var fop = template.toFOP();
    let pdf = new Ax.fop.Processor().transform(fop);
    let doc = new Ax.io.File("/tmp/Layout.pdf");
    doc.write(pdf);
    return pdf;
</script>

3 Template model

A complete template model will look like the code below. Each region may provide it's content by adding content to the provided container.

Copy
<script>

    var template = new Ax.fop.SinglePageTemplate("A4");
    
    // =======================================================================
    // CONFIGURE FOP ROOT LAYOUT
    // =======================================================================
    
    template.setRoot(root => {
        //root.setDebug("*");
        root.getSimplePageMaster().getRegionBefore().setExtent(8.5);
        root.getSimplePageMaster().getRegionAfter().setExtent(1.5);
        root.getSimplePageMaster().getRegionStart().setExtent(1.0);
        root.getSimplePageMaster().getRegionEnd().setExtent(1.0);
        root.getSimplePageMaster().setMargins(0, 0, 0, 0);
    });

    // =======================================================================
    // SET START REGION CONTENT
    // =======================================================================
    template.setStart(start => {
        // TODO
    });
    
    // =======================================================================
    // SET END REGION CONTENT
    // =======================================================================
    template.setEnd(end => {
        // TODO
    });
    
    // =======================================================================
    // SET BEFORE REGION CONTENT
    // =======================================================================
    template.setBefore(before => {
        // TODO
    });
    
    // =======================================================================
    // SET AFTER REGION CONTENT
    // =======================================================================
    template.setAfter(after => {
        // TODO
    });
    
    // =======================================================================
    // SET BODY FLOW CONTENT
    // =======================================================================
    template.setBody(body => {
        // TODO
    });
    
    // =======================================================================
    // SET BODY FOOT NOTE CONTENT
    // =======================================================================
    template.setBodyFootNote(footnote => {
        // TODO
    });
    
    // ====================================================================
    // GENERATE PDF
    // ====================================================================
    
    var fop = template.toFOP();
    //console.log(fop);
    let pdf = new Ax.fop.Processor().transform(fop);
    
    // Either write to file
    let doc = new Ax.io.File("/tmp/sample-debug.pdf");
    // or return to caller
    doc.write(pdf);

</script>

4 Adding content before

Let's see how to add content on before region. To do that we simply need to add a lambda function for the before region.

Copy
<script>
    var FILE_PATH = "https://bitbucket.org/deister/axional-docs-resources/raw/master/FOP/Invoices/Style1";
    
    var SVG_WATERMARK =
        "<svg:svg width='600' height='300' xmlns:svg='http://www.w3.org/2000/svg'>\n"+
        "  <svg:g transform='rotate(-30)'>\n"+
        "    <svg:text x='0' y='300' style='font-family:Courier;font-size:140;font-weight:normal;stroke-width:0.5;fill:#EDEDED;stroke:lightgray;stroke-opacity:0.75;'>\n"+
        "        COPY\n"+
        "    </svg:text>\n"+
        "  </svg:g>\n"+
        "</svg:svg>\n";
	    
    var template = new Ax.fop.SinglePageTemplate("A4");
    
    
    // =======================================================================
    // COLORS
    // =======================================================================
    var COLOR_LIGHT_GRAY = "#6d6d6d";
    var COLOR_TABLE_HEADER_GREEN = "#8BB260";
    var COLOR_TABLE_FOOTER_BLUE  = "#1d6480";
    var COLOR_LINE = "#eeeeee";
    
    // =======================================================================
    // FONTS
    // =======================================================================
    var FONT_NAME = "Noto Sans";
    var	FONT_SIZE_TITLES = 14;
    var	FONT_SIZE_TABLE_HEAD = 9;
    var	FONT_SIZE_TABLE_BODY = 8;
    
    // =======================================================================
    // CONFIGURE FOP ROOT LAYOUT
    // =======================================================================
    
    template.setRoot(root => {
        //root.setDebug("*");
        root.getSimplePageMaster().getRegionBefore().setExtent(8.5);
        root.getSimplePageMaster().getRegionAfter().setExtent(1.5);
        root.getSimplePageMaster().getRegionStart().setExtent(1.0);
        root.getSimplePageMaster().getRegionEnd().setExtent(1.0);
        root.getSimplePageMaster().setMargins(0, 0, 0, 0);
    });

    // =======================================================================
    // SET START REGION CONTENT
    // =======================================================================
    template.setStart(start => {
        // TODO
    });
    
    // =======================================================================
    // SET END REGION CONTENT
    // =======================================================================
    template.setEnd(end => {
        // TODO
    });
	
    // =======================================================================
	// SET BEFORE REGION CONTENT
    // =======================================================================
    template.setBefore(before => {
    
        before.addBlockContainer()
            //.setBorderColor("red").setBorderStyle("solid")
            .setPosition("absolute")
            .setTop("12.5cm")
            .setLeft("0.0cm")
            .addBlock()
            .addInstreamForeignObject(SVG_WATERMARK);

        var table = before.addTable();
        table.setFontFamily(FONT_NAME);
        table.setFontSize(FONT_SIZE_TABLE_HEAD);
        table.addColumn();
        table.addColumn();
        
        var row1 = table.getBody().addRow();
        var c11 = row1.addCell();
        var c12 = row1.addCell();
        c11.addBlock().addExternalGraphic(FILE_PATH + "/logo-left.png").setContentWidth(6.0);
        c12.addBlock().setTextAlign("center").addExternalGraphic(FILE_PATH + "/logo-right.png").setContentWidth(8.0);
        
        var row2 = table.getBody().addRow();
        var c21 = row2.addCell();
        var c22 = row2.addCell();
        
        c21.setDisplayAlign("center");
        c21.setPaddingLeft("36pt");
        c21.addBlock("Customer").setFontWeight("bold").setFontSize(FONT_SIZE_TITLES).setColor(COLOR_TABLE_HEADER_GREEN);
        
        c22.setPadding("20pt");
        c22.setDisplayAlign("center");
        c22.setBorderTopStyle("solid");
        c22.setBorderTopColor(COLOR_LIGHT_GRAY);
        c22.setBorderBottomStyle("solid");
        c22.setBorderBottomColor(COLOR_LIGHT_GRAY);
        c22.addBlock("Balace Due").setFontWeight("bold").setFontSize(FONT_SIZE_TITLES).setColor(COLOR_TABLE_HEADER_GREEN);;
    
    });

    // =======================================================================
    // SET AFTER REGION CONTENT
    // =======================================================================
    template.setAfter(after => {
        // TODO
    });
    
    // =======================================================================
    // SET BODY FLOW CONTENT
    // =======================================================================
    template.setBody(body => {
        // TODO
    });
    
    // =======================================================================
    // SET BODY FOOT NOTE CONTENT
    // =======================================================================
    template.setBodyFootNote(footnote => {
        // TODO
    });
    
    // ====================================================================
    // GENERATE PDF
    // ====================================================================
    
    var fop = template.toFOP();
    console.log(fop);
    let pdf = new Ax.fop.Processor().transform(fop);
    let doc = new Ax.io.File("/tmp/Invoice1.pdf");
    doc.write(pdf);

</script>

5 Invoice Examples

Now we are ready to complete a full invoice example using the knowlege from previous section.

5.1 Invoice 1 example

The following example provides full set of SinglePageTemplate features to generate a complete Invoice.

Copy

Example

<script>

var FILE_PATH   = "https://bitbucket.org/deister/axional-docs-resources/raw/master/FOP/Invoices/Style1";

// =======================================================================
// COLORS
// =======================================================================
var COLOR_LIGHT_GRAY = "#6d6d6d";
var COLOR_TABLE_HEADER_GREEN = "#8BB260";
var COLOR_TABLE_FOOTER_BLUE  = "#1d6480";
var COLOR_LINE = "#eeeeee";

// =======================================================================
// FONTS
// =======================================================================
var FONT_NAME = "Noto Sans";
var	FONT_SIZE_TITLES = 14;
var	FONT_SIZE_TABLE_HEAD = 9;
var	FONT_SIZE_TABLE_BODY = 8;

// =======================================================================
// FORMATS
// =======================================================================
var	NUMBER_FORMAT = "%,.2f";
var	DATE_FORMAT = "MMM, dd, yyyy";

// =======================================================================
// DATA
// =======================================================================
var m_locale = "us";
var m_data =  {

	"SVG_WATERMARK" :
		"<svg:svg width='600' height='300' xmlns:svg='http://www.w3.org/2000/svg'>\n"+
	    "  <svg:g transform='rotate(-30)'>\n"+
	    "    <svg:text x='0' y='300' style='font-family:Courier;font-size:140;font-weight:normal;stroke-width:0.5;fill:#EDEDED;stroke:lightgray;stroke-opacity:0.75;'>\n"+
	    "        COPY\n"+
	    "    </svg:text>\n"+
	    "  </svg:g>\n"+
	    "</svg:svg>\n",
	    
	 "m_from" : {
	 
		"m_company" 	: "Cameset Print Solutions",
		"m_address1" 	: "4141 Hacienda Dr",
		"m_address2"	: "Pleasanton California 94588",
		"m_address3"	: "U.S.A",
		"m_phone"		: "+563 1200 4569\n(33) 785 9865 4789",
		"m_email"		: "cameset@gmail.com\nwww.cameset.com",
	 },

	 "m_to" : {
		"m_company"		: "Fantasy Comics",
		"m_person"		: "Jhon Doe",
		"m_address1"	: "1301 K Street NW",
		"m_address2"	: "Washington D.C.",
		"m_address3"	: "U.S.A",
	 },


	 "m_invoice" : {
		"m_order"		: "#R337284",
		"m_number"		: "INV-2020/17",
		"m_balance_due"	: 2700.0,		// must be floating point to be handled by %f
		"m_date_invoice": new Ax.sql.Date(),
		"m_date_due"	: new Ax.sql.Date(),
		"m_terms"		: "Due On Receipt",
	 },
}

	var LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
    var m_resultset = new Ax.rs.Reader().build(
    	[
			[ "Web Design", 15, 10, "Hour", 150, LOREM ],
			[ "Graphic Design", 29, 50, "Pcs", 1450, LOREM],
			[ "Brand Identity", 35, 10, "Pcs", 350, LOREM],
			[ "Magazie Design", 11, 50, "Pcs", 550, LOREM],
			[ "Flyer Design", 10, 20, "Pcs", 200, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
			[ "Empty", 0, 0, "Pcs", 0, LOREM],
    	], 
    	options => {
	        options.setColumnNames(
	        	[
					"DESCRIPTION",
					"QTY",
					"RATE",
					"UNIT",
					"SUBTOTAL",
					"TEXT"
		 		]
		    );
    	}
    );

var template = new Ax.fop.SinglePageTemplate("A4");


// =======================================================================
// CONFIGURE FOP ROOT LAYOUT
// =======================================================================

template.setRoot(root => {
	//root.setDebug("*");
	root.getSimplePageMaster().getRegionBefore().setExtent(8.5);
	root.getSimplePageMaster().getRegionAfter().setExtent(1.5);
	root.getSimplePageMaster().getRegionStart().setExtent(1.0);
	root.getSimplePageMaster().getRegionEnd().setExtent(1.0);
	root.getSimplePageMaster().setMargins(0, 0, 0, 0);

});

// =======================================================================
// CONFIGURE START
// =======================================================================

template.setStart(start => {
	start.addBlock().setPaddingTop("10pt").setFontFamily(FONT_NAME).setFontSize(8).setTextAlign("center")
		.addTextLiteral("&#x00A9; 2020 deister software");

});

// =======================================================================
// CONFIGURE END
// =======================================================================
template.setEnd(end => {
	end.addBlock().setPaddingTop("10pt").setFontFamily(FONT_NAME).setFontSize(8).setTextAlign("center")
		.addTextLiteral("&#x00A9; 2020 deister software");

});

// =======================================================================
// CONFIGURE BEFORE
// =======================================================================
template.setBefore(before => {

	before.addBlockContainer()
		//.setBorderColor("red").setBorderStyle("solid")
		.setPosition("absolute")
		.setTop("12.5cm")
		.setLeft("0.0cm")
		.addBlock()
		.addInstreamForeignObject(m_data.SVG_WATERMARK);
	
	var table = before.addTable();
	table.setFontFamily(FONT_NAME);
	table.setFontSize(FONT_SIZE_TABLE_HEAD);
	table.addColumn();
	table.addColumn();
	table.addColumn();
	
	var row1 = table.getBody().addRow();
	var c11 = row1.addCell();
	var c12 = row1.addCell();
	var c13 = row1.addCell();
	c11.addBlock().addExternalGraphic(FILE_PATH + "/logo-left.png").setContentWidth(6.0);
	c13.addBlock().setTextAlign("center").addExternalGraphic(FILE_PATH + "/logo-right.png").setContentWidth(8.0);
	
	var row2 = table.getBody().addRow();
	var c21 = row2.addCell();
	var c22 = row2.addCell();
	var c23 = row2.addCell();
	
	// -------------------------------------------------------------------
	// Left: TO
	// -------------------------------------------------------------------

	c21.setDisplayAlign("center");
	c21.setPaddingLeft("36pt");
	c21.addBlock("Customer").setFontWeight("bold").setFontSize(FONT_SIZE_TITLES).setColor(COLOR_TABLE_HEADER_GREEN);
	c21.addBlock(m_data.m_to.m_company).setFontWeight("bold").setFontSize(FONT_SIZE_TITLES).setSpaceAfter("5pt");
	c21.addBlock(m_data.m_to.m_person);
	c21.addBlock(m_data.m_to.m_address1);
	c21.addBlock(m_data.m_to.m_address2);
	c21.addBlock(m_data.m_to.m_address3);
	
	// -------------------------------------------------------------------
	// Add a SVG barcode
	// -------------------------------------------------------------------
	c22.addBlock().addInstreamForeignObject(new Ax.barcode.SVG("A0383930000").setPrintText(true).setHeight(1.25).toCode128());
	
	// -------------------------------------------------------------------
	// Right: Balance due
	// -------------------------------------------------------------------
	c23.setPadding("20pt");
	c23.setDisplayAlign("center");
	c23.setBorderTopStyle("solid");
	c23.setBorderTopColor(COLOR_LIGHT_GRAY);
	c23.setBorderBottomStyle("solid");
	c23.setBorderBottomColor(COLOR_LIGHT_GRAY);
	c23.addBlock("Balace Due").setFontWeight("bold").setFontSize(FONT_SIZE_TITLES).setColor(COLOR_TABLE_HEADER_GREEN);;
	c23.addBlock(c23.format(m_data.m_invoice.m_balance_due, m_locale, NUMBER_FORMAT)).setFontWeight("bold").setFontSize(FONT_SIZE_TITLES).setSpaceAfter("5pt");
	c23.addBlock(m_data.m_invoice.m_order);
	c23.addBlock(m_data.m_invoice.m_number);
	c23.addBlock(m_data.m_invoice.m_terms);
	c23.addBlock(c23.format(m_data.m_invoice.m_date_invoice, m_locale, "MMM, dd yyyy"));
	// Align all text added to cell (do at end)
	c23.setTextAlign("right");

});

// =======================================================================
// CONFIGURE AFTER
// =======================================================================
template.setAfter(after => {
	var totalPageNumbeId = after.getRoot().getPageSequence().getTotalPageNumberCitation();
	var pagenumber = after
			.addBlock()
			.setFontFamily(FONT_NAME)
			.setFontSize(FONT_SIZE_TABLE_BODY)
			.setTextAlign("end")
			.setPaddingTop(6)
			.setBorderTopColor(COLOR_LINE)
			.setBorderTopStyle("solid");

	pagenumber.addInline()
		.addText("Page ")
		.putPageNumber()
		.addText(" - ")
		.putPageNumberCitation(totalPageNumbeId)
	;
});

// =======================================================================
// CONFIGURE BODY
// =======================================================================
template.setBody(body => {

	var table = body.addTable();
	table.setFontFamily(FONT_NAME);
	table.setFontSize(FONT_SIZE_TABLE_BODY);
	table.setSpaceBefore("20pt");
	table.addColumn("").setColumnWidth(1).setAlign("center");
	table.addColumn("Item & Description").setColumnWidth(8);
	table.addColumn("Qty").setColumnWidth(2.0).setAlign("right");
	table.addColumn("Rate").setColumnWidth(2.0).setAlign("right");
	table.addColumn("Discount").setColumnWidth(2.5).setAlign("right");
	table.addColumn("Ammount").setColumnWidth(3.5).setAlign("right");
	
	// Header row black background
	table.getHeader().getRows().forEach(row => {
		row.setBackgroundColor(COLOR_TABLE_HEADER_GREEN);
	});

	// Header cols white text + padding
	table.getHeader().getColumns().forEach(col => {
		col.getCell().setFontSize(FONT_SIZE_TABLE_HEAD);
		col.getCell().setColor("#FFFFFF");
		col.getCell().setFontWeight("bold");
		col.getCell().setBackgroundColor(COLOR_TABLE_HEADER_GREEN);
		col.getCell().setPaddingLeft(8);
		col.getCell().setPaddingRight(8);
		col.getCell().setPaddingTop(6);
		col.getCell().setPaddingBottom(6);
	});

	for (var tuple of m_resultset) {
		var row = table.getBody().addRow(
			null,
			tuple.get("DESCRIPTION"),
			table.format(tuple.get("QTY"), m_locale, NUMBER_FORMAT),
			table.format(tuple.get("RATE"), m_locale, NUMBER_FORMAT),
			tuple.get("UNIT"),
			table.format(tuple.get("SUBTOTAL"), m_locale, NUMBER_FORMAT)
		);
		row.getCell(1).getBlock().setFontWeight("bold");
		row.getCell(1).addBlock(tuple.get("TEXT")).setColor(COLOR_LIGHT_GRAY).setKeepWithPrevious("always");
		row.forEach(cell => {
			cell.setDisplayAlign("center");
			cell.setPaddingLeft(8);
			cell.setPaddingRight(8);
			cell.setPaddingTop(8);
			cell.setPaddingBottom(8);
			if (cell.getColumnIndex() < 2) {
				cell.setBorderBottomStyle("solid");
				cell.setBorderBottomColor("black");
			}
		});
		row.setBorderBottomStyle("solid");
		row.setBorderBottomColor(COLOR_LINE);
	}

	table.getBody().getLastRow().forEach(cell => {
		cell.setBorderBottomStyle("solid");
		cell.setBorderBottomColor("black");
	});
	var row = table.getBody().addRow();
	//row.setKeepWithPreviousWithinPage("always");
	row.setBackgroundColor(COLOR_TABLE_FOOTER_BLUE);
	row.addCell();
	row.addCell().setPaddingLeft(8).addBlock("DUE by " + row.format(m_data.m_invoice.m_date_due, m_locale, DATE_FORMAT)).setFontSize(12);
	row.addCell().setColspan(4).addBlock("$ " + row.format(m_data.m_invoice.m_balance_due, m_locale, NUMBER_FORMAT)).setFontSize(16);
	row.forEach(cell => {
		cell.setColor("#FFFFFF");
		cell.setBackgroundColor(COLOR_TABLE_FOOTER_BLUE);
		cell.setDisplayAlign("center");
		cell.setPaddingLeft(8);
		cell.setPaddingRight(8);
		cell.setPaddingTop(8);
		cell.setPaddingBottom(8);
	});

});

// =======================================================================
// CONFIGURE BODY FOOTNOTE
// =======================================================================
template.setBodyFootNote(footnote => {
	var table = footnote.getFootNoteBody().addTable();
	table.addColumn().setColumnWidth(8.0);
	table.addColumn();
	var row = table.getBody().addRow();

	__addLeftFootNote(row.addCell());
	__addRightFootNote(row.addCell());

});

function __addLeftFootNote(cell)
{
	var left = cell.addTable();
	left.setFontFamily(FONT_NAME);
	left.setFontSize(FONT_SIZE_TABLE_BODY);
	left.addColumn().setColumnWidth(1.5).setAlign("center");
	left.addColumn();
	
	var data = [
		[ "icon-phone.png", m_data.m_from.m_phone ],
		[ "icon-mail.png", m_data.m_from.m_email ],
		[ "icon-location.png", m_data.m_from.m_address1 + "\n" + m_data.m_from.m_address2 + "\n" + m_data.m_from.m_address3 ],
	];
	
	for (var temp of data) {
		var row = left.getBody().addRow();
		row.addCell().addBlock().addExternalGraphic(FILE_PATH + "/" + temp[0]).setContentWidth(1.0);
		row.addCell().setDisplayAlign("center").addBlock(temp[1]).setLinefeedTreatment("preserve");
	}	
}

function __addRightFootNote(cell)
{
	var right = cell.addTable();
	right.setFontFamily(FONT_NAME);
	right.setFontSize(FONT_SIZE_TABLE_HEAD);
	right.addColumn().setColumnWidth(1.8);
	right.addColumn();
	right.addColumn().setColumnWidth(1.2);
	right.addColumn();
	
	var row1 = right.getBody().addRow();
	row1.setHeight("20pt");
	row1.addCell().setNumberOfColumnsSpanned(4).addBlock("PAYMENT METHOD").setFontSize(12).setFontWeight("bold");

	var row2 = right.getBody().addRow();
	row2.setHeight("14pt");
	row2.addCell().addBlock("Account No");
	row2.addCell().addBlock(": 123 456 890");
	row2.addCell().addBlock("PayPal");
	row2.addCell().addBlock(": payments@fantasy.com");

	var row3 = right.getBody().addRow();
	row3.setHeight("14pt");
	row3.addCell().addBlock("BANK");
	row3.addCell().addBlock(": BANK0000123456789");
	row3.addCell().addBlock("SWIFT");
	row3.addCell().addBlock(": 12345678");

	var row4 = right.getBody().addRow();
	row4.setHeight("20pt");
	row4.addCell().setNumberOfColumnsSpanned(4)
		.addBlock()
		.addExternalGraphic(FILE_PATH + "/logo-signature.png")
		.setContentWidth(6.0);
}


// ====================================================================
// GENERATE PDF
// ====================================================================

var fop = template.toFOP();
let pdf = new Ax.fop.Processor().transform(fop);
//new Ax.io.File("/tmp/InvoiceStyle1Script.fop").write(fop);
//new Ax.io.File("/tmp/InvoiceStyle1Script.pdf").write(pdf);
return pdf;

</script>
Click here to download the PDF example

5.2 Invoice 2 example

Same as before with style variations

Copy

Example

<script>
    function print_invoice(obj_invoice,obj_lines) {
    var FILE_PATH = "https://bitbucket.org/deister/axional-docs-resources/raw/master/FOP/Invoices/Style1";
    
    var SVG_WATERMARK =
        "<svg:svg width='600' height='300' xmlns:svg='http://www.w3.org/2000/svg'>\n"+
        "  <svg:g transform='rotate(-30)'>\n"+
        "    <svg:text x='0' y='300' style='font-family:Courier;font-size:140;font-weight:normal;stroke-width:0.5;fill:#EDEDED;stroke:lightgray;stroke-opacity:0.75;'>\n"+
        "        COPY\n"+
        "    </svg:text>\n"+
        "  </svg:g>\n"+
        "</svg:svg>\n";
    var template = new Ax.fop.SinglePageTemplate("A4");
    
    
    // =======================================================================
    // COLORS
    // =======================================================================
    var COLOR_LIGHT_GRAY = "#757575";
    var COLOR_LIGHT_BLUE = "#03A9F4";
    var COLOR_BLUE  = "#0288D1";
    var COLOR_LINE = "#a2a0a7";
    var COLOR_WHITE = "#fff";
    var COLOR_BLACK = "#000";

    // =======================================================================
    // FORMATS
    // =======================================================================

    var m_locale = "us";
    var NUMBER_FORMAT = "%,.2f";
    var DATE_FORMAT = "MMM, dd, yyyy";
    
    // =======================================================================
    // FONTS
    // =======================================================================
    var FONT_NAME = "Noto Sans";
    var	FONT_SIZE_TITLE = 25;
    var FONT_SIZE_NAME = 15;
    var	FONT_SIZE_PRIMARY = 10;
    var	FONT_SIZE_SECUNDARY = 8;
    
    // =======================================================================
    // CONFIGURE FOP ROOT LAYOUT
    // =======================================================================
    
    template.setRoot(root => {
        //root.setDebug("*"); // Used to see how much each space occupies on the PDF
        root.getSimplePageMaster().getRegionBefore().setExtent(8.5);
        root.getSimplePageMaster().getRegionAfter().setExtent(9.0);
        root.getSimplePageMaster().getRegionStart().setExtent(1.0);
        root.getSimplePageMaster().getRegionEnd().setExtent(1.0);
        root.getSimplePageMaster().setMargins(0, 0, 0, 0);
    });

    // =======================================================================
	// CONFIGURE START
	// =======================================================================

	template.setStart(start => {
		start.addBlock().setPaddingTop("10pt").setFontFamily(FONT_NAME).setFontSize(8).setTextAlign("center")
			.addTextLiteral("&#x00A9; 2020 deister software");

	});

	// =======================================================================
	// CONFIGURE END
	// =======================================================================
	template.setEnd(end => {
		end.addBlock().setPaddingTop("10pt").setFontFamily(FONT_NAME).setFontSize(8).setTextAlign("center")
			.addTextLiteral("&#x00A9; 2020 deister software");

	});
	
    // =======================================================================
	// CONFIGURE BEFORE
	// =======================================================================
	template.setBefore(before => {
	      
	  	before.addBlockContainer()
	  		.setPosition("absolute")
	  		.setTop("12.5cm")
	  		.setLeft("0.0cm")
	  		.addBlock()

	  	var table = before.addTable();
	  	table.setFontFamily(FONT_NAME);
	  	table.setFontSize(FONT_SIZE_SECUNDARY);
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();

	  	var row1 = table.getBody().addRow();
	  	row1.setPadding("5pt")
	  	var c11 = row1.addCell().setColspan(3);
	  	var c12 = row1.addCell().setLineHeight(12.0).setColspan(3);

	  	c11.addBlock().addExternalGraphic(FILE_PATH + "/logo-right.png").setContentWidth(6.0);//Add the company logo
	  	c11.setPaddingTop("40pt");
	  	c11.setPaddingLeft("36pt");
	  	c12.setPaddingLeft("20pt");
	  	c12.addBlock("INVOICE").setFontSize(FONT_SIZE_TITLE).setColor(COLOR_LIGHT_BLUE).setLineHeight(35.0);//details of the invoice
	  	c12.addBlock("Invoice No.#"+obj_invoice.id).setFontSize(FONT_SIZE_PRIMARY).setSpaceAfter("5pt");
	  	c12.addBlock("Invoice date"	+"	"+":"+c12.format(obj_invoice.date,m_locale,DATE_FORMAT));
	  	c12.addBlock("Issue date"	+"		"+":"+c12.format(obj_invoice.issue_date,m_locale,DATE_FORMAT));
	  	c12.addBlock("Account No."	+"	"+":"+obj_invoice.account_num);
	  	c12.setPaddingTop("40pt");

	  	var row2 = table.getBody().addRow();
	  	var c21 = row2.addCell().setLineHeight(12.0).setColspan(3);//the separation between lines can be adjusted by setlineheight
	  	var c22 = row2.addCell().setLineHeight(12.0).setColspan(3);

	  	c21.setDisplayAlign("center");
	  	c21.setPaddingLeft("36pt");
	  	c21.addBlock("To");
	  	c21.addBlock(obj_invoice.client_name).setFontSize(FONT_SIZE_NAME).setSpaceBefore("5pt").setSpaceAfter("5pt");//Details of the client
	  	c21.addBlock("Director").setSpaceAfter("5pt");
	  	c21.addBlock("Address: "+obj_invoice.client_address);
	  	c21.addBlock("E-mail: "+obj_invoice.client_mail);
	  	c21.addBlock("Phone number: "+obj_invoice.client_phone);

	  	c22.setPadding("20pt");
	  	c22.setDisplayAlign("center");
	  	c22.addBlock("Payment Method: ").setFontWeight("bold").setSpaceAfter("5pt");
	  	c22.addBlock("Paypal: "+obj_invoice.paypal).setColor(COLOR_LIGHT_GRAY);
	  	c22.addBlock("Card payment we accept: "+obj_invoice.accepted_cards).setColor(COLOR_LIGHT_GRAY);
	  	// Align all text added to the cell 
	  	c22.setTextAlign("left");

	  	var row3 = table.getBody().addRow();

	  	row3.setBackgroundColor(COLOR_BLUE);
	  	row3.setPadding("15pt")
	  	var c31 =row3.addCell().setLineHeight(12.0);
	  	var c32 =row3.addCell().setColspan(2).setLineHeight(12.0);
	  	var c33 =row3.addCell().setLineHeight(12.0);
	  	var c34 =row3.addCell().setLineHeight(12.0);
	  	var c35 =row3.addCell().setLineHeight(12.0);
	  	//The first row contains the column descriptions, and must be inserted into the before region
	  	c31.addBlock("SL").setColor(COLOR_WHITE).setTextAlign("center").setPaddingTop("5pt").setPaddingBottom("5pt");
	  	c32.addBlock("ITEM DESCRIPTIONS").setColor(COLOR_WHITE).setTextAlign("center").setPaddingTop("5pt").setPaddingBottom("5pt");
	  	c33.addBlock("RATE").setColor(COLOR_WHITE).setTextAlign("center").setBackgroundColor(COLOR_BLACK).setPaddingTop("5pt").setPaddingBottom("5pt");
	  	c34.addBlock("QTY").setColor(COLOR_WHITE).setTextAlign("center").setBackgroundColor(COLOR_BLACK).setPaddingTop("5pt").setPaddingBottom("5pt");
	  	c35.addBlock("PRICE").setColor(COLOR_WHITE).setTextAlign("center").setBackgroundColor(COLOR_BLACK).setPaddingTop("5pt").setPaddingBottom("5pt");

	  });

    // =======================================================================
    // SET AFTER REGION CONTENT
    // =======================================================================
    template.setAfter(after => {
		var table = after.addTable();
        table.addColumn();

	  	var row1 = table.getBody().addRow();
	  	var row2 = table.getBody().addRow();

	  	var cell1 = row1.addCell();
        //We add table inside cells to have better control of the elements position
	  	var table1 = cell1.addTable().setPageBreakInside("avoid");//In order to prevent a block appearing between 2 pages, we add .setPageBreakInside()
        table1.setFontSize(FONT_SIZE_PRIMARY);
        table1.addColumn();
        table1.addColumn().setColumnWidth(8.0);

        var row1 = table1.getBody().addRow();

        var c11 = row1.addCell().setLineHeight(12.0);
        var c12 = row1.addCell().setLineHeight(12.0);

        var t2 = c12.addTable();
        t2.addColumn();
        t2.addColumn();

        rowt1 = t2.getBody().addRow().setHeight(0.5);
        rowt2 = t2.getBody().addRow().setHeight(0.5);
        rowt3 = t2.getBody().addRow();
        rowt4 = t2.getBody().addRow();

        ct11 = rowt1.addCell().setLineHeight(12.0);
        ct12 = rowt1.addCell().setLineHeight(12.0);
        ct21 = rowt2.addCell().setDisplayAlign("center").setLineHeight(12.0);
        ct22 = rowt2.addCell().setDisplayAlign("center").setLineHeight(12.0);
        ct3  = rowt3.addCell().setColspan(2).setRowspan(1).setLineHeight(12.0);

        c11.addBlock("Terms & Conditions:").setPageBreakInside("avoid");
        c11.addBlock(LOREM).setFontSize(FONT_SIZE_SECUNDARY).setColor(COLOR_LIGHT_GRAY).setTextAlign("justified");
        c11.setPaddingTop("50pt");


        ct11.setPadding("20pt");
		ct11.addBlock("Sub-Total").setColor(COLOR_LIGHT_GRAY).setPaddingLeft("14pt");
		ct11.addBlock("Tax: Vat ("+obj_invoice.taxvalue+"%)").setColor(COLOR_LIGHT_GRAY).setPaddingLeft("14pt");
		
		ct12.setPadding("20pt");
		ct12.addBlock(ct12.format(obj_invoice.subtotal,m_locale,NUMBER_FORMAT)+" €").setColor(COLOR_LIGHT_GRAY).setTextAlign("right").setPaddingLeft("5pt");
		ct12.addBlock(ct12.format(obj_invoice.tax,m_locale,NUMBER_FORMAT)+" €").setColor(COLOR_LIGHT_GRAY).setTextAlign("right").setPaddingLeft("5pt");

		//We can define blocks as variables to separate its properties among multiple lines
		cbt21 = ct21.addBlock("Grand Total:").setColor(COLOR_WHITE).setFontWeight("bold").setBackgroundColor(COLOR_BLUE)
		cbt21.setPaddingTop("5pt").setPaddingBottom("5pt").setPaddingLeft("20pt").setStartIndent("15pt");
		ct21.setPadding("5pt")

		ct22.setPadding("5pt")
		cbt22 = ct22.addBlock(ct22.format(obj_invoice.total,m_locale,NUMBER_FORMAT)+" €").setColor(COLOR_WHITE).setFontWeight("bold").setBackgroundColor(COLOR_LIGHT_BLUE)
		cbt22.setTextAlign("right").setPaddingTop("5pt").setPaddingBottom("5pt").setEndIndent("15pt")
		cbt22.setPaddingRight("20pt");

		ct3.addBlock("Robert Smith").setTextAlign("center")
		ct3.addBlock("Web Designer").setTextAlign("center").setFontSize(FONT_SIZE_SECUNDARY).setColor(COLOR_LIGHT_GRAY)

		cell2 = row2.addCell();
		var table2 = cell2.addTable().setPageBreakInside("avoid");
		table2.addColumn();
		table2.addColumn();
		table2.addColumn();
		var row21 = table2.getBody().addRow();
		var row22 = table2.getBody().addRow();

		var c211 = row21.addCell().setPadding("15pt").setLineHeight(12.0);
		var c212 = row21.addCell().setPadding("15pt").setLineHeight(12.0);
		var c213 = row21.addCell().setPadding("15pt").setLineHeight(12.0);
		var c22  = row22.addCell().setColspan(3).setLineHeight(12.0);

		var t21 = c211.addTable();
		t21.addColumn().setColumnWidth(1.8);
		t21.addColumn();
		t21.setFontSize(FONT_SIZE_SECUNDARY).setColor(COLOR_LIGHT_GRAY);
		t21.setBorderStyle("solid").setBorderColor(COLOR_LIGHT_BLUE)
		var row211 = t21.getBody().addRow();
		var row212 = t21.getBody().addRow();

		var ct2111 = row211.addCell().setRowspan(2);
		var ct2112 = row211.addCell();
		var ct2122 = row212.addCell();

		cbt2111 = ct2111.addBlock().setStartIndent("15pt");
		cbt2111.addExternalGraphic(FILE_PATH + '/'+"icon-phone.png").setContentWidth(1.0);
		cbt2111.setSpaceBefore("5pt").setSpaceAfter("5pt").setPaddingBottom("5pt");
		cbt2112 = ct2112.addBlock(obj_invoice.company_phone).setLinefeedTreatment("preserve").setSpaceBefore("10pt");
		cbt2122 = ct2122.addBlock(obj_invoice.company_phone).setLinefeedTreatment("preserve");
		c211.setTextAlign("center");

		var t22 = c212.addTable();
		t22.addColumn().setColumnWidth(1.8);
		t22.addColumn();
		t22.setFontSize(FONT_SIZE_SECUNDARY).setColor(COLOR_LIGHT_GRAY);
		t22.setBorderStyle("solid").setBorderColor(COLOR_LIGHT_BLUE)
		var row221 = t22.getBody().addRow();
		var row222 = t22.getBody().addRow();

		var ct2211 = row221.addCell().setRowspan(2);
		var ct2212 = row221.addCell();
		var ct2222 = row222.addCell();

		cbt2211 = ct2211.addBlock().setStartIndent("15pt");
		cbt2211.addExternalGraphic(FILE_PATH + '/'+"icon-mail.png").setContentWidth(1.0);
		cbt2211.setSpaceBefore("5pt").setSpaceAfter("5pt").setPaddingBottom("5pt");
		cbt2212 = ct2212.addBlock(obj_invoice.company_mail).setLinefeedTreatment("preserve").setSpaceBefore("10pt");
		cbt2222 = ct2222.addBlock(obj_invoice.company_web).setLinefeedTreatment("preserve");
		c212.setTextAlign("center");
		
		var t23 = c213.addTable();
		t23.addColumn().setColumnWidth(1.8);
		t23.addColumn();
		t23.setFontSize(FONT_SIZE_SECUNDARY).setColor(COLOR_LIGHT_GRAY);
		t23.setBorderStyle("solid").setBorderColor(COLOR_LIGHT_BLUE)
		var row231 = t23.getBody().addRow();
		var row232 = t23.getBody().addRow();

		var ct2311 = row231.addCell().setRowspan(2);
		var ct2312 = row231.addCell();
		var ct2322 = row232.addCell();

		cbt2311 = ct2311.addBlock().setStartIndent("15pt");
		cbt2311.addExternalGraphic(FILE_PATH + '/'+"icon-location.png").setContentWidth(1.0);
		cbt2311.setSpaceBefore("5pt").setSpaceAfter("5pt").setPaddingBottom("5pt").setPageBreakInside("avoid");
		cbt2312 = ct2312.addBlock(obj_invoice.company_address).setLinefeedTreatment("preserve").setSpaceBefore("10pt");
		cbt2322 = ct2322.addBlock("").setLinefeedTreatment("preserve");
		c213.setTextAlign("center");

		c22.addBlock(LOREM).setColor(COLOR_LIGHT_GRAY).setSpaceBefore("10pt");


	});
    
    // =======================================================================
    // SET BODY FLOW CONTENT
    // =======================================================================
    template.setBody(body => {
    	
        var table = body.addTable();
    	table.setFontFamily(FONT_NAME);
        table.setFontSize(FONT_SIZE_PRIMARY);
        table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();

	  	var row1 = table.getBody().addRow();
	  	

	  	var counter = 1;//counter is used to obtain the row number
	  	for (var i of obj_lines) {
	  		var row = table.getBody().addRow();
	  		var c1 = row.addCell().setLineHeight(12.0);
	  		var c2 = row.addCell().setColspan(2).setLineHeight(12.0);
	  		var c3 = row.addCell().setLineHeight(12.0);
	  		var c4 = row.addCell().setLineHeight(12.0);
	  		var c5 = row.addCell().setLineHeight(12.0);
	  		c1.addBlock(counter).setTextAlign("center").setSpaceBefore("14pt");
	  		c1.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c1.setBorderRightStyle("solid").setBorderRightColor(COLOR_LINE);
	  		c1.setPadding("10pt").setDisplayAlign("after");
	  		c2.addBlock(i.ITEM_NAME).setFontWeight("bold");
	  		c2.addBlock(i.DESCRIPTION).setPageBreakInside("avoid").setFontSize(FONT_SIZE_SECUNDARY);
	  		c2.setTextAlign("justified").setPadding("10pt");
	  		c2.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c2.setBorderRightStyle("solid").setBorderRightColor(COLOR_LINE);
	  		c3.addBlock(c3.format(i.RATE,m_locale,NUMBER_FORMAT)+" €").setTextAlign("center").setSpaceBefore("14pt");
	  		c3.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c3.setBorderRightStyle("solid").setBorderRightColor(COLOR_LINE);
	  		c3.setPadding("10pt").setDisplayAlign("after");
	  		c4.addBlock(i.QTY).setTextAlign("center").setSpaceBefore("14pt");
	  		c4.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c4.setBorderRightStyle("solid").setBorderRightColor(COLOR_LINE);
	  		c4.setPadding("10pt").setDisplayAlign("after");
	  		var PRICE = i.RATE*i.QTY;//The price is calculated as the product between the rate and the quantity
	  		c5.addBlock(c5.format(PRICE,m_locale,NUMBER_FORMAT)+" €").setTextAlign("center").setSpaceBefore("14pt").setPageBreakInside("avoid");
	  		c5.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c5.setPadding("10pt").setDisplayAlign("after");
	  		counter = counter+1;
	  		}
	  	
		
    });

	// =======================================================================
	// CONFIGURE BODY FOOTNOTE
	// =======================================================================
	template.setBodyFootNote(footnote => {
		

	});


  // ====================================================================
  // GENERATE PDF
  // ====================================================================

  var fop = template.toFOP();
  let pdf = new Ax.fop.Processor().transform(fop);
  return pdf;
}
    </script>
// *****************************************************************************
// * DATA
// *****************************************************************************
// Needed data
var temp_invoice = {
	"id"				: 2342343,
	"date"				: new Ax.sql.Date("2020-02-19"),
	"issue_date"		: new Ax.sql.Date("2020-02-19"),
	"account_num"		: 2342323423,
	"client_name"		: "John Smith",
	"client_address"	: "Avenida Europa Edificio Alcor Plaza 2-2",
	"client_mail"		: "JohnSmith@email.com",
	"client_phone"		: "918386100",
	"paypal"			: "paypaladdress@paypal.es",
	"accepted_cards"	: "Visa",
	"company_phone"		: "345345343",
	"company_mail"		: "company@mail.com",
	"company_web"		: "www.company.com",
	"company_address"	: "old street 123",
    "taxvalue"          : 15,
    "subtotal"          : 3300,
    "tax"               : 495,
    "total"             : 3795
}

var LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
//Needed data for the invoice lines, note we use a resultset
var m_resultset = new Ax.rs.Reader().build(
    	[
			[ "Web Design", LOREM, 15, 10],
			[ "Graphic Design", LOREM, 29, 50],
			[ "Brand Identity", LOREM, 35, 10],
			[ "Magazine Design", LOREM, 11, 50],
			[ "Flyer Design", LOREM, 10, 20],
			[ "Flyer Design", LOREM, 10, 20],
			[ "Flyer Design", LOREM, 10, 20],
			[ "Flyer Design", LOREM, 10, 20],
    	], 
    	options => {
	        options.setColumnNames(
	        	[
					"ITEM_NAME",
					"DESCRIPTION",
					"RATE",
					"QTY"
		 		]
		    );
    	}
    );

// ------------------------------------------------------------------------
// OBTAIN PDF
// ------------------------------------------------------------------------

return print_invoice(temp_invoice,m_resultset);
Click here to download the PDF example

5.3 Invoice 3 example

Same as before with style variations

Copy

Example

<script>
function print_invoice(obj_invoice,obj_lines) {
    var FILE_PATH = "https://bitbucket.org/deister/axional-docs-resources/raw/master/FOP/Invoices/Style1";
    
    var SVG_WATERMARK =
        "<svg:svg width='600' height='300' xmlns:svg='http://www.w3.org/2000/svg'>\n"+
        "  <svg:g transform='rotate(-30)'>\n"+
        "    <svg:text x='0' y='300' style='font-family:Courier;font-size:140;font-weight:normal;stroke-width:0.5;fill:#EDEDED;stroke:lightgray;stroke-opacity:0.75;'>\n"+
        "        COPY\n"+
        "    </svg:text>\n"+
        "  </svg:g>\n"+
        "</svg:svg>\n";
    var template = new Ax.fop.SinglePageTemplate("A4");
    
    
    // =======================================================================
    // COLORS
    // =======================================================================
    var COLOR_LIGHT_GRAY = "#e1e1e1";
    var COLOR_LIGHT_BLUE = "#03A9F4";
    var COLOR_DARK_BLUE  = "#252c3b";
    var COLOR_GOLD = "#b5a789";
    var COLOR_LINE = "#a2a0a7";
    var COLOR_WHITE = "#fff";
    var COLOR_BLACK = "#000";
    var COLOR_RED_WINE = "#ac354b";
    var COLOR_GRAY = "#939294";

    // =======================================================================
    // FORMATS
    // =======================================================================

    var m_locale = "us";
    var NUMBER_FORMAT = "%,.2f";
    var DATE_FORMAT = "MMM, dd, yyyy";
    
    // =======================================================================
    // FONTS
    // =======================================================================
    var FONT_NAME = "Noto Sans";
    var	FONT_SIZE_TITLE = 25;
    var FONT_SIZE_NAME = 12;
    var	FONT_SIZE_PRIMARY = 10;
    var	FONT_SIZE_SECUNDARY = 8;
    
    // =======================================================================
    // CONFIGURE FOP ROOT LAYOUT
    // =======================================================================
    
    template.setRoot(root => {
        //root.setDebug("*"); // Used to see how much each space occupies on the PDF
        root.getSimplePageMaster().getRegionBefore().setExtent(10.0);
        root.getSimplePageMaster().getRegionAfter().setExtent(8.25);
        root.getSimplePageMaster().getRegionStart().setExtent(2.0);
        root.getSimplePageMaster().getRegionEnd().setExtent(1.0);
        root.getSimplePageMaster().setMargins(0, 0, 0, 0);
    });

    // =======================================================================
	// CONFIGURE START
	// =======================================================================

	template.setStart(start => {
		var table = start.addTable();//Using a table, we can modify the color of the margins of the page
		table.addColumn();
		table.addColumn().setColumnWidth(4.6);

		var row1 = table.getBody().addRow();
		var row2 = table.getBody().addRow();

		c1 = row1.addCell().setBackgroundColor(COLOR_LIGHT_GRAY);
		c2 = row1.addCell().setBackgroundColor(COLOR_GOLD);
		c3 = row2.addCell();
		c4 = row2.addCell().setBackgroundColor(COLOR_DARK_BLUE);

		c1.addBlock("a").setPaddingBottom("15pt").setColor(COLOR_LIGHT_GRAY);
		c2.addBlock("a").setPaddingBottom("15pt").setColor(COLOR_GOLD);
		c3.addBlock("a").setColor(COLOR_WHITE);
		c4.addBlock("a").setPaddingBottom("15pt").setColor(COLOR_DARK_BLUE);
	});
	
	// =======================================================================
	// CONFIGURE END
	// =======================================================================

	template.setEnd(end => {
		var table = end.addTable();
		table.addColumn().setBackgroundColor(COLOR_DARK_BLUE).setColumnWidth(4.6);
		table.addColumn();

		var row1 = table.getBody().addRow();

		c1 = row1.addCell();
		c2 = row1.addCell();

		c1.addBlock().addTextLiteral("a").setPaddingBottom("15pt").setColor(COLOR_DARK_BLUE);
		c2.addBlock().addTextLiteral("a").setPaddingBottom("15pt").setColor(COLOR_WHITE);
	});
	
    // =======================================================================
	// CONFIGURE BEFORE
	// =======================================================================
	template.setBefore(before => {
	      
	  	before.addBlockContainer()
	  		.setPosition("absolute")
	  		.setTop("12.5cm")
	  		.setLeft("0.0cm")
	  		.addBlock()

	  	var table = before.addTable();
	  	table.setFontFamily(FONT_NAME);
	  	table.setFontSize(FONT_SIZE_SECUNDARY);
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();

	  	var row1 = table.getBody().addRow();
	  	row1.setPadding("5pt").setBackgroundColor(COLOR_DARK_BLUE);
	  	var c11 = row1.addCell().setColspan(3);
	  	var c12 = row1.addCell().setLineHeight(12.0).setColspan(3);
		c12.setTextAlign("center");

	  	var t2 = c12.addTable().setBorderLeftStyle("solid").setBorderLeftColor(COLOR_GOLD)
	  	t2.addColumn().setColumnWidth(1.5);
	  	t2.addColumn();

	  	var rowt21 = t2.getBody().addRow();
	  	var rowt22 = t2.getBody().addRow();
	  	var rowt23 = t2.getBody().addRow();

	  	var ct21 = rowt21.addCell().setColspan(2);
	  	var ct221 = rowt22.addCell();
	  	var ct222 = rowt22.addCell();
	  	var ct231 = rowt23.addCell();
	  	var ct232 = rowt23.addCell();

	  	ct21.addBlock(obj_invoice.company_address).setColor(COLOR_WHITE).setFontWeight("bold").setSpaceBefore("20pt").setStartIndent("20pt");
	  	cbt221 = ct221.addBlock().setStartIndent("15pt").setEndIndent("40pt");
		cbt221.addExternalGraphic(FILE_PATH + '/'+"icon-phone.png").setContentWidth(0.5);
		cbt221.setSpaceBefore("5pt").setSpaceAfter("5pt").setPaddingBottom("5pt");
		cbt222 = ct222.addBlock(obj_invoice.company_phone).setLinefeedTreatment("preserve").setSpaceBefore("9pt").setColor(COLOR_WHITE);
		cbt231 = ct231.addBlock().setStartIndent("15pt").setEndIndent("40pt");
		cbt231.addExternalGraphic(FILE_PATH + '/'+"icon-mail.png").setContentWidth(0.5);
		cbt231.setSpaceBefore("5pt").setSpaceAfter("5pt").setPaddingBottom("5pt");
		cbt232 = ct232.addBlock(obj_invoice.company_mail).setLinefeedTreatment("preserve").setSpaceBefore("3pt").setColor(COLOR_WHITE);
		cbt232 = ct232.addBlock(obj_invoice.company_web).setLinefeedTreatment("preserve").setColor(COLOR_WHITE);

	  	c11.addBlock().addExternalGraphic(FILE_PATH + "/logo-right.png").setContentWidth(6.0);//Add the company logo
	  	c11.setPaddingTop("20pt").setPaddingBottom("20pt");
	  	

	  	var row2 = table.getBody().addRow();
	  	var c21 = row2.addCell().setLineHeight(12.0).setColspan(3);//the separation between lines can be adjusted by setlineheight
	  	var c22 = row2.addCell().setLineHeight(12.0).setColspan(3);

	  	cb21 = c21.addBlock().setSpaceAfter("5pt").setSpaceBefore("20pt").addInline().addText("Bill To: ").setFontWeight("bold").setColor(COLOR_GOLD).setFontSize(FONT_SIZE_PRIMARY).addInline().addText(obj_invoice.client_name).setFontWeight("normal").setColor(COLOR_BLACK)
	  	cb21.setFontSize(FONT_SIZE_PRIMARY);//With addInline(), we can apply different format to different parts of the text
        c21.addBlock("Account manager").setSpaceAfter("5pt");
	  	c21.addBlock().addInline().addText("A: ").setFontWeight("bold").addInline().addText(obj_invoice.client_address).setFontWeight("normal");
	  	c21.addBlock().addInline().addText("W: ").setFontWeight("bold").addInline().addText(obj_invoice.client_mail).setFontWeight("normal");
	  	c21.addBlock().addInline().addText("P: ").setFontWeight("bold").addInline().addText(obj_invoice.client_phone).setFontWeight("normal");

	  	var t4 = c22.addTable()
	  	t4.addColumn();
	  	t4.addColumn();
	  	t4.addColumn();

	  	var rowt41 = t4.getBody().addRow();
	  	var rowt42 = t4.getBody().addRow();

	  	var ct41 = rowt41.addCell().setColspan(3);
	  	var ct421 = rowt42.addCell().setPaddingTop("10pt").setPaddingBottom("10pt");
	  	var ct422 = rowt42.addCell().setPaddingTop("10pt").setPaddingBottom("10pt");
	  	var ct423 = rowt42.addCell().setPaddingTop("10pt").setPaddingBottom("10pt");

	  	c22.setPaddingLeft("20pt");
	  	ct41.addBlock("INVOICE").setFontSize(FONT_SIZE_TITLE).setLineHeight(35.0).setBorderBottomStyle("solid").setSpaceAfter("20pt");//details of the invoice
	  	ct421.addBlock("A/C No:").setBorderRightStyle("solid");
	  	ct421.addBlock(`#${obj_invoice.account_num}`).setBorderRightStyle("solid");
	  	ct422.addBlock("Invoice date:").setBorderRightStyle("solid").setStartIndent("15pt");
	  	ct422.addBlock(ct422.format(obj_invoice.date,m_locale,DATE_FORMAT)).setBorderRightStyle("solid").setStartIndent("15pt");
	  	ct423.addBlock("Issue date").setStartIndent("15pt");
	  	ct423.addBlock(ct423.format(obj_invoice.issue_date,m_locale,DATE_FORMAT)).setStartIndent("15pt");
	  	c22.setPaddingTop("40pt");

	  	var row3 = table.getBody().addRow();

	  	row3.setPadding("15pt")
	  	row3.setBorderTopStyle("solid").setBorderBottomStyle("solid");
	  	var c31 =row3.addCell().setLineHeight(12.0);
	  	var c32 =row3.addCell().setColspan(2).setLineHeight(12.0);
	  	var c33 =row3.addCell().setLineHeight(12.0);
	  	var c34 =row3.addCell().setLineHeight(12.0);
	  	var c35 =row3.addCell().setLineHeight(12.0);
	  	//The first row contains the column descriptions, and we must insert it into the before region
	  	c31.addBlock("D. DATE").setTextAlign("center").setPaddingTop("10pt").setPaddingBottom("10pt").setFontSize(FONT_SIZE_NAME);
	  	c32.addBlock("ITEM DESCRIPTION").setTextAlign("center").setPaddingTop("10pt").setPaddingBottom("10pt").setFontSize(FONT_SIZE_NAME);
	  	c33.addBlock("UNITY PRICE").setTextAlign("center").setPaddingTop("10pt").setPaddingBottom("10pt").setFontSize(FONT_SIZE_NAME);
	  	c34.addBlock("QTY").setTextAlign("center").setPaddingTop("10pt").setPaddingBottom("10pt").setFontSize(FONT_SIZE_NAME);
	  	c35.addBlock("TOTAL").setTextAlign("center").setPaddingTop("10pt").setPaddingBottom("10pt").setFontSize(FONT_SIZE_NAME);

	  });

    // =======================================================================
    // SET AFTER REGION CONTENT
    // =======================================================================
    template.setAfter(after => {
		var table = after.addTable();
		table.addColumn();

		var row1 = table.getBody().addRow();
		var row2 = table.getBody().addRow();

		var cell1 = row1.addCell();
		var cell2 = row2.addCell();
	  	
		var table1 = cell1.addTable().setPageBreakInside("avoid");//In order to prevent a block appearing between 2 pages, we add .setPageBreakInside()
        table1.setFontSize(FONT_SIZE_PRIMARY);
        table1.addColumn();
        table1.addColumn().setColumnWidth(8.0);
        table1.setBorderTopStyle("solid");

        var row11 = table1.getBody().addRow();

        var c111 = row11.addCell().setLineHeight(12.0);
        var c112 = row11.addCell().setLineHeight(12.0);

        var t12 = c112.addTable();
        t12.addColumn();
        t12.addColumn();

        rowt11 = t12.getBody().addRow().setHeight(0.5);
        rowt12 = t12.getBody().addRow().setHeight(0.5);
        rowt13 = t12.getBody().addRow();

        ct111 = rowt11.addCell().setLineHeight(15.0);
        ct112 = rowt11.addCell().setLineHeight(15.0);
        ct121 = rowt12.addCell().setDisplayAlign("center").setLineHeight(12.0);
        ct122 = rowt12.addCell().setDisplayAlign("center").setLineHeight(12.0);

        c111.addBlock("PAYMENT METHOD").setPageBreakInside("avoid").setColor(COLOR_GOLD).setBorderBottomStyle("solid").setBorderBottomColor(COLOR_GRAY).setEndIndent("120pt").setSpaceAfter("5pt");
        cb111 = c111.addBlock().setTextAlign("justified").addInline().addText("Paypal: ").setFontWeight("bold").setFontSize(FONT_SIZE_SECUNDARY).setSpaceAfter("5pt")
        cb111.addInline().addText(obj_invoice.paypal).setColor(COLOR_GRAY).setFontWeight("normal");
        cc111 = c111.addBlock().setTextAlign("justified").addInline().addText("Cards we accept: ").setFontWeight("bold").setFontSize(FONT_SIZE_SECUNDARY).setSpaceAfter("5pt")
        cc111.addInline().addText(obj_invoice.accepted_cards).setColor(COLOR_GRAY).setFontWeight("normal").setPaddingBottom("10pt");
        c111.setPaddingTop("40pt");


        ct111.setPadding("20pt");
		ct111.addBlock("Sub-Total").setPaddingLeft("14pt");
		ct111.addBlock(`Discount (${obj_invoice.discountvalue}%)`).setColor(COLOR_RED_WINE).setPaddingLeft("14pt");
		ct111.addBlock(`Tax: Vat (${obj_invoice.taxvalue}%)`).setColor(COLOR_GRAY).setPaddingLeft("14pt");
		
		ct112.setPadding("20pt");
		ct112.addBlock(ct112.format(obj_invoice.subtotal,m_locale,NUMBER_FORMAT)+" €").setTextAlign("right").setPaddingLeft("5pt");
		ct112.addBlock(ct112.format(obj_invoice.discount,m_locale,NUMBER_FORMAT)+" €").setColor(COLOR_RED_WINE).setTextAlign("right").setPaddingLeft("5pt");
		ct112.addBlock(ct112.format(obj_invoice.tax,m_locale,NUMBER_FORMAT)+" €").setColor(COLOR_GRAY).setTextAlign("right").setPaddingLeft("5pt");

		
		cbt121 = ct121.addBlock("GRAND TOTAL:").setColor(COLOR_WHITE).setFontWeight("bold").setBackgroundColor(COLOR_GOLD).setFontSize(FONT_SIZE_NAME)
		cbt121.setPaddingTop("5pt").setPaddingBottom("5pt").setPaddingLeft("20pt").setStartIndent("20pt");

		cbt122 = ct122.addBlock(ct122.format(obj_invoice.total,m_locale,NUMBER_FORMAT)+" €").setColor(COLOR_WHITE).setFontWeight("bold").setBackgroundColor(COLOR_GOLD).setFontSize(FONT_SIZE_NAME)
		cbt122.setTextAlign("right").setPaddingTop("5pt").setPaddingBottom("5pt").setEndIndent("20pt").setPaddingRight("20pt")

		var table2 = cell2.addTable().setPageBreakInside("avoid");
		table2.addColumn();
		table2.addColumn();
		var row21 = table2.getBody().addRow();

		var c21 = row21.addCell().setLineHeight(15.0);
		var c22 = row21.addCell().setDisplayAlign("center");

		c21.addBlock("Thank You For Your Business!").setColor(COLOR_GOLD).setFontSize(FONT_SIZE_NAME).setSpaceAfter("10pt")
		c21.addBlock("Terms & Conditions:").setFontSize(FONT_SIZE_SECUNDARY)
		c21.addBlock().setColor(COLOR_GRAY).addTextLiteral("&#x00B7; "+LOREM).setFontSize(FONT_SIZE_SECUNDARY)
		c21.setTextAlign("justified");

		c22.addBlock("Thomas B. Speicher").setTextAlign("center")
		c22.addBlock("Account manager").setTextAlign("center").setColor(COLOR_GRAY).setFontSize(FONT_SIZE_SECUNDARY);


	});
    
    // =======================================================================
    // SET BODY FLOW CONTENT
    // =======================================================================
    template.setBody(body => {
    	
        var table = body.addTable();
    	table.setFontFamily(FONT_NAME);
        table.setFontSize(FONT_SIZE_PRIMARY);
        table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
	  	table.addColumn();
        // For each row, we obtain the values of each column and add it to the blocks 
	  	for (var i of obj_lines) {
	  		var row = table.getBody().addRow();
	  		var c1 = row.addCell().setLineHeight(12.0);
	  		var c2 = row.addCell().setColspan(2).setLineHeight(12.0);
	  		var c3 = row.addCell().setLineHeight(12.0);
	  		var c4 = row.addCell().setLineHeight(12.0);
	  		var c5 = row.addCell().setLineHeight(12.0);
	  		c1.addBlock(c1.format(i.DATE,m_locale,DATE_FORMAT)).setTextAlign("center");
	  		c1.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c1.setPadding("10pt").setDisplayAlign("center");
	  		c2.addBlock(i.ITEM_NAME).setFontWeight("bold");
	  		c2.addBlock(i.DESCRIPTION).setPageBreakInside("avoid").setFontSize(FONT_SIZE_SECUNDARY);
	  		c2.setTextAlign("justified").setPadding("10pt");
	  		c2.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c3.addBlock(c3.format(i.RATE,m_locale,NUMBER_FORMAT)+" €").setTextAlign("center");
	  		c3.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c3.setPadding("10pt").setDisplayAlign("center");
	  		c4.addBlock(i.QTY).setTextAlign("center");
	  		c4.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c4.setPadding("10pt").setDisplayAlign("center");
	  		var PRICE = i.RATE*i.QTY;//The price is calculated as the product between the rate and the quantity
	  		c5.addBlock(c5.format(PRICE,m_locale,NUMBER_FORMAT)+" €").setTextAlign("center").setPageBreakInside("avoid");
	  		c5.setBorderBottomStyle("solid").setBorderBottomColor(COLOR_LINE);
	  		c5.setPadding("10pt").setDisplayAlign("center");
	  	}
    });

	// =======================================================================
	// CONFIGURE BODY FOOTNOTE
	// =======================================================================
	template.setBodyFootNote(footnote => {
	});


  	// ====================================================================
  	// GENERATE PDF
  	// ====================================================================

  	var fop = template.toFOP();
  	let pdf = new Ax.fop.Processor().transform(fop);
  	return pdf;
}
</script>
// *****************************************************************************
// * DATA
// *****************************************************************************
// Needed data
var temp_invoice = {
	"id"				: 2342343,
	"date"				: new Ax.sql.Date("2020-02-19"),
	"issue_date"		: new Ax.sql.Date("2020-02-19"),
	"account_num"		: 2342323423,
	"client_name"		: "John Smith",
	"client_address"	: "Avenida Europa Edificio Alcor Plaza 2-2",
	"client_mail"		: "JohnSmith@email.com",
	"client_phone"		: "918386100",
	"paypal"			: "paypaladdress@paypal.es",
	"accepted_cards"	: "Visa",
	"company_phone"		: "345345343",
	"company_mail"		: "company@mail.com",
	"company_web"		: "www.company.com",
	"company_address"	: "old street 123",
    "taxvalue"          : 15,
    "discountvalue"     : 20,
    "tax"               : 396,
    "subtotal"          : 3300,
    "discount"          : 660,
    "total"             : 3036
}

var LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
//Needed data for the invoice lines, note we use a resultset
var m_resultset = new Ax.rs.Reader().build(
    	[
			[ new Ax.sql.Date("2020-02-19"),"Web Design", LOREM, 15, 10],
			[ new Ax.sql.Date("2020-02-19"),"Graphic Design", LOREM, 29, 50],
			[ new Ax.sql.Date("2020-02-19"),"Brand Identity", LOREM, 35, 10],
			[ new Ax.sql.Date("2020-02-19"),"Magazine Design", LOREM, 11, 50],
			[ new Ax.sql.Date("2020-02-19"),"Flyer Design", LOREM, 10, 20],
			[ new Ax.sql.Date("2020-02-19"),"Flyer Design", LOREM, 10, 20],
			[ new Ax.sql.Date("2020-02-19"),"Flyer Design", LOREM, 10, 20],
			[ new Ax.sql.Date("2020-02-19"),"Flyer Design", LOREM, 10, 20],
    	], 
    	options => {
	        options.setColumnNames(
	        	[
					"DATE",
					"ITEM_NAME",
					"DESCRIPTION",
					"RATE",
					"QTY"
		 		]
		    );
    	}
    );


// ------------------------------------------------------------------------
// OBTAIN PDF
// ------------------------------------------------------------------------

return print_invoice(temp_invoice,m_resultset);
Click here to download the PDF example

5.4 Delivery Note

Copy

Delivery Example

var logo_albaran = "base64:,/9j/4QbfRXhpZgAATU0AKgAAAAgADAEAAAMAAAABAZgAAAEBAAMAAAABAHgAAAECAAMAAAADAAAAngEGAAMAAAABAAIAAAESAAMAAAABAAEAAAEVAAMAAAABAAMAAAEaAAUAAAABAAAApAEbAAUAAAABAAAArAEoAAMAAAABAAIAAAExAAIAAAAkAAAAtAEyAAIAAAAUAAAA2IdpAAQAAAABAAAA7AAAASQACAAIAAgALcbAAAAnEAAtxsAAACcQQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkAMjAxODowNzoxMyAxMzoyOTowNAAABJAAAAcAAAAEMDIyMaABAAMAAAAB//8AAKACAAQAAAABAAABmKADAAQAAAABAAAAeAAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAFyARsABQAAAAEAAAF6ASgAAwAAAAEAAgAAAgEABAAAAAEAAAGCAgIABAAAAAEAAAVVAAAAAAAAAEgAAAABAAAASAAAAAH/2P/tAAxBZG9iZV9DTQAB/+4ADkFkb2JlAGSAAAAAAf/bAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgAHQBiAwEiAAIRAQMRAf/dAAQAB//EAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5/cRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8A55IkASTA8Skug+quPhY9Wb9YOp45ysPB2Y9VAZ6m+60s9axtMO3/AGah7Pzf8Lf/AKNFTz5IaCXGAOSdAm3NkNkSRIE6x4rp8fpDOl/4wsXA2B2K6834oOrTTZVfZUBM/wBHuY+ln/EV2KwzC6ZZ9XuvHMtbg0Vdctm9lXqWBrH1CrHxqme7fZv+z1f6P1XpKeRSWxndCxMXK6a6rPdf0nq4LsfMZQ6y4Fo3Gk4VI9W2125mzZX7P0vq0fq/6QvVPqwzFwqM/CyL7KLcmvEuZmY78a2t1rm1subXayh1tPvb/g/+u/TSU4SYOaSWggkchdB1f6udK6Z1Sjpj+q2WX3WRYyvGdc+ql1b7KnmrGD3W5Vt9fpekz/A2/afQ9Or9JY6/0m49O6U/Hvs/Z1N1XTmY9+K/Esqfc5jHZr67xXbkPvd77/37P5r/AA6SnmEl0+R9T8Bl3UsLG6qb+p9Oq+0fZnVbW+ntbY1l1v0XWu3fzlL/ANH6tX6Bcu1wc0OHDgCPmkpdJJJJSkkkklP/0OeW1V9auo4XS8Hp3SHO6eMZrzl2AV2G+2x2/wBQetXb6bN3qP8A7fp/zdPvxUkVPQf87bLsro2dn0Oyc/pL7TdktLGG6q1rq2s9NjWMbazdW/8A0f6L2f0j9HDH+seCMDqPT8/pzsrH6nn2Zzw2303VtsLbGtqsbD/tFFtVex36Ouz+QsJJJT0df1upx+p9Ovw+nirpvSqbKMfEL5sItDRbf6p3M9f9EzZ/Of8Aaj1L/wBY/RhyvrHjv6UOmY2PlOa3MqzG35uSb7Hem9l7q3l270tzq/TYyv1K/wDD/wA8sJJBTvM+tLa/rbb9Ym4pdXc30zjOcN4Ya6qd7LB7PW/V/wDtt/ppsn6x47umVdOxsfKc2jOqzRfm5JvseKnNuNb3O3ejvcz02sq31f4f+e9RYSSSne/50tHXeq9WGK4t6njHGZSXDcw7KqmWWO+j/gffs/6awGN2Ma3naAJ+CdJFSkznNY0veYa0EuPgAnW/9VmfVZvVcf8Aatt1txe37N6lba8Vts/om27Lsi2y3f8AzLrvSxt//DekkpX/ADO6x/3Hf/yX9t4P9J/8rv8Aj0l6ukgp/9n/7Q6MUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAccAgAAAgAAADhCSU0EJQAAAAAAEOjxXPMvwRihontnrcVk1bo4QklNBDoAAAAAAO8AAAAQAAAAAQAAAAAAC3ByaW50T3V0cHV0AAAABQAAAABQc3RTYm9vbAEAAAAASW50ZWVudW0AAAAASW50ZQAAAABJbWcgAAAAD3ByaW50U2l4dGVlbkJpdGJvb2wAAAAAC3ByaW50ZXJOYW1lVEVYVAAAAAEAAAAAAA9wcmludFByb29mU2V0dXBPYmpjAAAAEQBBAGoAdQBzAHQAZQAgAGQAZQAgAHAAcgB1AGUAYgBhAAAAAAAKcHJvb2ZTZXR1cAAAAAEAAAAAQmx0bmVudW0AAAAMYnVpbHRpblByb29mAAAACXByb29mQ01ZSwA4QklNBDsAAAAAAi0AAAAQAAAAAQAAAAAAEnByaW50T3V0cHV0T3B0aW9ucwAAABcAAAAAQ3B0bmJvb2wAAAAAAENsYnJib29sAAAAAABSZ3NNYm9vbAAAAAAAQ3JuQ2Jvb2wAAAAAAENudENib29sAAAAAABMYmxzYm9vbAAAAAAATmd0dmJvb2wAAAAAAEVtbERib29sAAAAAABJbnRyYm9vbAAAAAAAQmNrZ09iamMAAAABAAAAAAAAUkdCQwAAAAMAAAAAUmQgIGRvdWJAb+AAAAAAAAAAAABHcm4gZG91YkBv4AAAAAAAAAAAAEJsICBkb3ViQG/gAAAAAAAAAAAAQnJkVFVudEYjUmx0AAAAAAAAAAAAAAAAQmxkIFVudEYjUmx0AAAAAAAAAAAAAAAAUnNsdFVudEYjUHhsQHLAAAAAAAAAAAAKdmVjdG9yRGF0YWJvb2wBAAAAAFBnUHNlbnVtAAAAAFBnUHMAAAAAUGdQQwAAAABMZWZ0VW50RiNSbHQAAAAAAAAAAAAAAABUb3AgVW50RiNSbHQAAAAAAAAAAAAAAABTY2wgVW50RiNQcmNAWQAAAAAAAAAAABBjcm9wV2hlblByaW50aW5nYm9vbAAAAAAOY3JvcFJlY3RCb3R0b21sb25nAAAAAAAAAAxjcm9wUmVjdExlZnRsb25nAAAAAAAAAA1jcm9wUmVjdFJpZ2h0bG9uZwAAAAAAAAALY3JvcFJlY3RUb3Bsb25nAAAAAAA4QklNA+0AAAAAABABLAAAAAEAAgEsAAAAAQACOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD+AAAA4QklNA/IAAAAAAAoAAP///////wAAOEJJTQQNAAAAAAAEAAAAHjhCSU0EGQAAAAAABAAAAB44QklNA/MAAAAAAAkAAAAAAAAAAAEAOEJJTScQAAAAAAAKAAEAAAAAAAAAAjhCSU0D9QAAAAAASAAvZmYAAQBsZmYABgAAAAAAAQAvZmYAAQChmZoABgAAAAAAAQAyAAAAAQBaAAAABgAAAAAAAQA1AAAAAQAtAAAABgAAAAAAAThCSU0D+AAAAAAAcAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAA4QklNBAgAAAAAABAAAAABAAACQAAAAkAAAAAAOEJJTQQeAAAAAAAEAAAAADhCSU0EGgAAAAADUQAAAAYAAAAAAAAAAAAAAHgAAAGYAAAADgBhAGwAYgBhAHIAYQBuAF8AaABlAGEAZABlAHIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAZgAAAB4AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAAAAABudWxsAAAAAgAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAB4AAAAAFJnaHRsb25nAAABmAAAAAZzbGljZXNWbExzAAAAAU9iamMAAAABAAAAAAAFc2xpY2UAAAASAAAAB3NsaWNlSURsb25nAAAAAAAAAAdncm91cElEbG9uZwAAAAAAAAAGb3JpZ2luZW51bQAAAAxFU2xpY2VPcmlnaW4AAAANYXV0b0dlbmVyYXRlZAAAAABUeXBlZW51bQAAAApFU2xpY2VUeXBlAAAAAEltZyAAAAAGYm91bmRzT2JqYwAAAAEAAAAAAABSY3QxAAAABAAAAABUb3AgbG9uZwAAAAAAAAAATGVmdGxvbmcAAAAAAAAAAEJ0b21sb25nAAAAeAAAAABSZ2h0bG9uZwAAAZgAAAADdXJsVEVYVAAAAAEAAAAAAABudWxsVEVYVAAAAAEA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AG8AdABvAHMAaABvAHAAAAAXAEEAZABvAGIAZQAgAFAAaABvAHQAbwBzAGgAbwBwACAAQwBDACAAMgAwADEAOAAAAAEAOEJJTQQGAAAAAAAHAAgAAAABAQD/4RJ6aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0MCA3OS4xNjA0NTEsIDIwMTcvMDUvMDYtMDE6MDg6MjEgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06RG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjE2NDZhYzdhLWFkMDYtMjY0ZS05NTU4LWZiM2Y4MzRiM2VjNCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2YTJkOWFmMS04YWEyLTQ1ZWUtYjhjMy0wMDk2ZDc3MGMwMGYiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0iQjc1NzMyQzNBNDZCQkZERUQzRjlDMkI3QTJFMkI5ODAiIGRjOmZvcm1hdD0iaW1hZ2UvanBlZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9IkFwcGxlIFJHQiIgeG1wOkNyZWF0ZURhdGU9IjIwMTgtMDctMTNUMTE6NDY6MzUrMDI6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDE4LTA3LTEzVDEzOjI5OjA0KzAyOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDE4LTA3LTEzVDEzOjI5OjA0KzAyOjAwIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChNYWNpbnRvc2gpIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NWMxMjZiMGQtZDA3YS00YWRjLWE2NjctODQ4ZTc4ZTBmZDYxIiBzdEV2dDp3aGVuPSIyMDE4LTA3LTEzVDExOjUzOjQ0KzAyOjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoTWFjaW50b3NoKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY29udmVydGVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJmcm9tIGltYWdlL2pwZWcgdG8gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iZGVyaXZlZCIgc3RFdnQ6cGFyYW1ldGVycz0iY29udmVydGVkIGZyb20gaW1hZ2UvanBlZyB0byBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo4ZmY5OTJlMy01MzZiLTQzYWItYmZmZC00MDUyNWFkZTkzMmIiIHN0RXZ0OndoZW49IjIwMTgtMDctMTNUMTE6NTM6NDQrMDI6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChNYWNpbnRvc2gpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpkODlmZWQ2NS0xMWNkLTQ4Y2YtYjc3Ni05MmU1Y2I4NzA3NmUiIHN0RXZ0OndoZW49IjIwMTgtMDctMTNUMTM6Mjk6MDQrMDI6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChNYWNpbnRvc2gpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjb252ZXJ0ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9qcGVnIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJkZXJpdmVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJjb252ZXJ0ZWQgZnJvbSBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wIHRvIGltYWdlL2pwZWciLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjZhMmQ5YWYxLThhYTItNDVlZS1iOGMzLTAwOTZkNzcwYzAwZiIgc3RFdnQ6d2hlbj0iMjAxOC0wNy0xM1QxMzoyOTowNCswMjowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOmQ4OWZlZDY1LTExY2QtNDhjZi1iNzc2LTkyZTVjYjg3MDc2ZSIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjJmMzI1Y2JiLTYzOTYtMTU0Yy05OGM5LTc5ZmFkNDQyZmUxYiIgc3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPSJCNzU3MzJDM0E0NkJCRkRFRDNGOUMyQjdBMkUyQjk4MCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSJ3Ij8+/+ICOElDQ19QUk9GSUxFAAEBAAACKEFEQkUCEAAAbW50clJHQiBYWVogB88ABgADAAAAAAAAYWNzcEFQUEwAAAAAbm9uZQAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1BREJFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKY3BydAAAAPwAAAAyZGVzYwAAATAAAABkd3RwdAAAAZQAAAAUYmtwdAAAAagAAAAUclRSQwAAAbwAAAAOZ1RSQwAAAcwAAAAOYlRSQwAAAdwAAAAOclhZWgAAAewAAAAUZ1hZWgAAAgAAAAAUYlhZWgAAAhQAAAAUdGV4dAAAAABDb3B5cmlnaHQgMTk5OSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAAAAGRlc2MAAAAAAAAACkFwcGxlIFJHQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAAAAAAAAAAAAAAAAAAY3VydgAAAAAAAAABAc0AAGN1cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAWFlaIAAAAAAAAHm9AABBUgAABLlYWVogAAAAAAAAVvgAAKwvAAAdA1hZWiAAAAAAAAAmIgAAEn8AALFw/+4ADkFkb2JlAGRAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQEBAQEBAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAeAGYAwERAAIRAQMRAf/dAAQAM//EAaIAAAAGAgMBAAAAAAAAAAAAAAcIBgUECQMKAgEACwEAAAYDAQEBAAAAAAAAAAAABgUEAwcCCAEJAAoLEAACAQMEAQMDAgMDAwIGCXUBAgMEEQUSBiEHEyIACDEUQTIjFQlRQhZhJDMXUnGBGGKRJUOhsfAmNHIKGcHRNSfhUzaC8ZKiRFRzRUY3R2MoVVZXGrLC0uLyZIN0k4Rlo7PD0+MpOGbzdSo5OkhJSlhZWmdoaWp2d3h5eoWGh4iJipSVlpeYmZqkpaanqKmqtLW2t7i5usTFxsfIycrU1dbX2Nna5OXm5+jp6vT19vf4+foRAAIBAwIEBAMFBAQEBgYFbQECAxEEIRIFMQYAIhNBUQcyYRRxCEKBI5EVUqFiFjMJsSTB0UNy8BfhgjQlklMYY0TxorImNRlUNkVkJwpzg5NGdMLS4vJVZXVWN4SFo7PD0+PzKRqUpLTE1OT0laW1xdXl9ShHV2Y4doaWprbG1ub2Z3eHl6e3x9fn90hYaHiImKi4yNjo+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A16/b/V+ve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r/0Nev2/1fr3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de6/9HXr9v9X697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuv/S16/b/V+ve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r/09ev2/1fr3v3Xuve/de697917r3v3Xuve/de67AvwOSeAB+ffuvdbCnxP/4Tn/LH5GdTbd7d3pvvYnRGL3niabO7R2vu6hzuZ3lW4TI08VXicvmcXioI6bb9Nk6aVZYoZp2qxGys8SXANCwHWq9VufPb+XZ8gf5ePYmI2T3RR4jKYTdtJWZDYfYu0p6qs2hvClxssMOThpJaymo67HZfFvURGpoqqKOaNJo3GqN1Y2BB690Q33vrfXvfuvdH8/lrfBnNfzBvlBt7oii3INmbbp8Jld7dgbtWlFfWYbZmAlooK0Yihd44azN5OvyVNSUqyMsaPMZXukbA6JoK9a62E/n1/wAJyekeqPjRvntz4u9gdoy786n2pkt45vbHZGV2/uLFb5wmApDX52LG1GG23tuo29m4sdBNPBf7mnmZBEVjv5PdAxrQ9aB608PbnVutwb+Xv/wnR6T7g+Mmwe5/lJv3s+LeXb+0cVvjbW1utcvgNu43Zu2NzUKZPbT5Sry+3Nyz53N12IqYKqRQKaCn8viKyMpf22WNcdVr1QD/ADM/ghmf5efydy/R9TuR95bVye3sXvvrrddRSJQV+Z2Zm6rI0FOMtQxPJDT5bF5bEVdHUGM+KV6fyIFVwouDUV631Xv731vr3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917pe9XdZ727m7G2V1R1xgqrcu++wdyYram1sHRqWmr8vl6qOlpkZ7FaeliLmSeZ7RwQI8jkIrEa6919F34r/wAmH4NdEdBbW6z7F+P3UHde/mwNK/ZHZvYWysPurPZzdVTTB83Pt3LZ2jqMltTBUtVI0VDDQPSMlPGjyapi8jNlifPqtetIX+a31/8AETq/5ndi7J+F2SNd1VhI6GmzFLRZabP7XwO/1843Tt7Zmdqp6qrym3sROI4g0k04jqRNEkrxop9uCtM9bHVb/vfW+ve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuv/9TXr9v9X697917r3v3Xuve/de697917r3v3XurMf5R3w/l+aHzh6o66yeOet662hXDtLtlzHI1KNi7Lq6OrlxNS6qVQbrzk1FiRcggVrOL6CPeiaDrR6+mxHHHFGkUSJHFGixxxxqEjjjQBUREUBURFFgBwB7Z6r1U9/Ok+Ho+YfwW7HweCxYyHZvU6Ht/rAwwiWunzO1KOqbO7fpSLOx3RtWaspFTUENS0Dtfxj3ZTQ9bHXzWCLcHgjgg/j271brr37r3WyB/wmI/7Lr7I/wDFdt0/+9lsf3R+HWj1ug/L7/slH5K/+II7Y/8AeGznug4jqvXyfvb3V+vq4fCf/sjb4nf+K29H/wDvtNs+2Oqdacn/AAqJ/wCy4umP/FW9s/8Av0+2fbicOrDrXdwPXPYO6qZqzbGxd4bipEJD1WC21mctTKQuohp6CiniBCm55+nu3W+k7k8RlcJVyUGZxmQxFdCxWaiydFU0FXEwtdZKeqjimQi/5A976903e/de697917rJHFLM4jhjeWQ/RI0Z3P8ArKoJPv3XulLFsbe08AqoNn7pmpiuoVEW38tJAV+uoTJSGPTb839+690nJ6eopZDDUwTU8q/qinieGRbEg3SRVYcj+nv3XusPv3Xuve/de6c6nCZmioqXJVmIydJjq6/2VfU0FVBRVmn9X2tVLEkFRp/Ohjb3rr3WPHYrJ5ipWixGOr8pWMrOtJjqOorqlkQFnZYKaOWUqii5NrAe99e6izQzU0skFRFLBPC5jlhmjeKWJ1NmSSNwro6n6ggEe/de6xgX4HJPAA/Pv3XurRf5UHynwHwd+T0Xf2+Pj9u7urG02yNxbXwi7YpHXObOzWdlxwbdOENZQVGOqK04emqqB1Z4HFPXSFZByr1YVFK9a49WNfzHf+FBXcvyH6/ynSfQPWe6/jZs/c1JJjt87tz+WeXs3cGJqVljqdv4magocfS7QxORgbRVPDJUVk8d0WaKNnV9BQOPXqdaz/u/W+ve/de6cqXDZiupaquocVkqyhoQGrayloaqopaNWvpNVUQxPDThrG2si/v3Xum337r3S8x/VvZuWxozGK673zksQVLjKUG089WY9kAJLrWU9BJTsoA+oa3vXXukRNBNTSyQVEMtPPExSWGaN4pY3H1WSOQK6MP6EA+99e6xe/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r/1dev2/1fr3v3Xuve/de697917r3v3Xuve/de632v+E33w+/0J/EvM/IzdGM+3338mspBkcO9RAUq8f1PtWSrotpxIXJKx7jyk9dkyyWWamlpSblB7ac5p1U9DX/Od/mXZH4EUvxkw2yMgBvLe3b+C3dvXGQxwVNTU9H7MrYk3xizTTqVV91PkUpKeS6skkLsD6T78orXrwHV0W09z7f3/tHbu8dt1tLmtr7y2/i9xYTIQNHUUeTwmex8GQoKmNhqjlgqqKqVvyCD7r1rr5sn84v4gS/Dn5y9obTxOMeg647GrJO1+r3SJko125u6rqanIYalbxxxW23uJaujCJxHDHH/AF9uqajqw6qz92631sgf8JiP+y7OyP8AxXfdP/vZbH90fh1o9boPy/8A+yUfkr/4gjtf/wB4bOe6DiOq9fJ+9vdX6+rf8J/+yNvid/4rZ0f/AO+z2z7Y6oePRSfkZ/Ky6g+XPzf2d8o/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WNAetHh1/9LXr9v9X697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917reG/4TP8AwzyHWXSu/fl9vGhqaHPd7aNndeUtVDJA69YbZyYqa/NCOpx8Uph3RuqlHheKd4ZYMejFblSG3Pl1U9f/09ev2/1fr3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917qzD+V1/Lu3p/MG+QmD2cIq7B9N7Yq48v21vsUla9NRYWiQVbbaxU1MgV9xbhASnjLSQx0qzCSSRXaBJqk060T19K7YOxts9ZbJ2p17szF0uG2rsvAYvbeAxlHTUlHBS4zE0kVHTKKegp6SjSWRItchjiRXkZmsL+2uq9f//U16/b/V+ve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917q2r+XF/KF+RXz83PhM2cTlurPjwtcx3J3Pn8PULS19FRGkkr8b19QVQp13VnZ4qtEidWWhidmaSU+KRPdSwH29ar19Ar4n/ABM6Z+GnUOE6d6V2zSYPB45EqMxkxFfMbpzbIBVZvOV0jz1dXUzMT4xJLJ4kNtTMWdmya9V6Mx7117r/1dev2/1fr3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de697917r3v3Xuve/de6X2y+quz+yJxS9e9c7731UEsPDs/aWf3LINJ0uWXDUFYUVCfUTYL+be9de6tk+Pf8hD+Yx3pW0z53qqn6J221RjRWZ3uXIpt6thoa+eSKarpNp0S5Hc1XNQRwvJLBJT08gAUcF01aLAdar1sg/C/wD4TmfFToaoxe8vkPk6v5K7/otE0eHykD4PqnG1kZroxPDtiCT+I5/XFNBKq5Gpkihmi4jccmhY+XWq9bC2GwuG27jKPCbfxOMwWGx8ZhoMRhqClxeMoYmkeVoqOgoooKWmjaWRmKoigsxP1PuvWunP37r3Xvfuvdf/2Q==";
var logo_mimaos = "base64:,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//2Q==";


function addDirection(header_left)
{
	header_left.addBlock(
		"SUPERCONSUM SL\n"+
		"CL PINTOR SOROLLA 5\n"+
		"03610 PETRER\n"+
		"NIF: 9929293293\n"+
		"Tel: 9838383838 - Fax: 3333345555"
		)
		.setSpaceBefore("3.0cm")
		.setFontSize(8)
		.setFontWeight("bold")
		.setFontFamily("Helvetica")
		.setLinefeedTreatment("preserve");
}

function addIndentedDataTable(wrapper, rs)
{
	var container = wrapper.addBlockContainer().setWidth("11.0cm").setStartIndent("6.0cm");
	var table = container.addTable()
		.setFontSize(8)
		// Table automatically detects start-indent from parent container and resets to 0 if present
		//.setStartIndent("0cm")
		.setBorderStyle("solid")
		.setBorderWidth("0.25pt")
		.setSpaceBefore("10pt")
		.addResultSet(rs);
	
	table.getHeader().getRows().forEach(row => {
		row.forEach(cell => {
			cell.setTextAlign("center");
		});
		row.setBackgroundColor("#EAEAEA");
		}
	);
	
	table.getBody().getRows().forEach(row => {
		row.forEach(cell => {
			cell.setMargin("1pt");
			if (row.isLast()) {
				cell.setBorderTopStyle("solid");
				cell.setBorderTopWidth("1.0pt");
				cell.setFontWeight("bold");
			}
		});
		}
	);
	table.setFontSize(9);
}

function addLeftTable(fopBlockContainer)
{
	var t1 = fopBlockContainer.addTable();

	t1.setFontSize(9);

	t1.addColumns(
	   [
		"Farmacia",
		"Fecha Pedido",
		"Hora",
		"<center>Referencia</center>",
		"Albarán",
		"Fecha albarán",
		"Vencimiento"
	   ]
	).forEach(c => {
		c.getCell().setBackgroundColor("#EEEEEE");
		c.getCell().setFontWeight("bold");
		c.getCell().setPaddingTop(4);
		c.getCell().setPaddingLeft(5);
		c.getCell().setPaddingRight(5);
		c.getCell().setBorderStyle("solid");
		c.getCell().setBorderWidth(2);
		c.getCell().setBorderColor("white");
	});

	var r = t1.getBody().addRow([
				"MM-100353-C298182",
				"19-10-2017",
				"15:04",
				"42924",
				"1710-0416668",
				"19-10-2017",
				"20-11-17"
				]);
	r.forEach(c => {
		c.setPaddingBottom(4);
		c.setPaddingLeft(5);
		c.setPaddingRight(5);
		if (c.getColumnIndex() > 0) {
			c.setTextAlign("center");
			c.setBorderLeftStyle("solid");
			c.setBorderLeftWidth(4);
			c.setBorderLeftColor("red");
		}
	});

	// TODO: compute widths on non sized columns
	t1.pack();
}

function addRightTable(fopBlockContainer)
{
	var t1 = fopBlockContainer.addTable();
	
	t1.setFontSize(9);
	
	t1.addColumns([
		"Farmacia",
		"Fecha Pedido",
		"Hora",
		"Albarán"
	]).forEach(c => {
		c.getCell().setTextAlign("center");
		c.getCell().setBackgroundColor("#EEEEEE");
		c.getCell().setFontWeight("bold");
		c.getCell().setPaddingTop(4);
		c.getCell().setPaddingLeft(5);
		c.getCell().setPaddingRight(5);
		c.getCell().setBorderStyle("solid");
		c.getCell().setBorderWidth(2);
		c.getCell().setBorderColor("white");
		/*
		if (c.getColumnIndex() > 0) {
		c.getCell().setBorderLeftStyle("solid");
		c.getCell().setBorderLeftWidth(4);
		c.getCell().setBorderLeftColor("red");
		}
		*/
	});
	
	t1.getBody().addRow([
		"MM-100353-C298182",
		"19-10-2017",
		"15:04",
		"1710-0416668",
	]).forEach(c => {
		c.setPaddingBottom(4);
		c.setTextAlign("center");
		/*
		if (c.getColumnIndex() > 0) {
		c.setBorderLeftStyle("solid");
		c.setBorderLeftWidth(4);
		c.setBorderLeftColor("red");
		}
		*/
	});
	
	// TODO: compute widths on non sized columns
	t1.pack();
}

function addBodyTable(fopWrapper, width)
{
	var rs = getHeaderResultSet();
	
	// ==========================================================================
	// AUTOMATIC TABLE USING ResultSet table generator
	// ==========================================================================
	
	if (false) {
		var body = new ResultSet2FOP(rs, c => {
			c.setTableHeadAlign("left");
		}).getTableBody(width);
		fopWrapper.addFOPContent(body);
	}

	// ==========================================================================
	// MANUALLY SIZED TABLE
	// ==========================================================================
	var widths = [
		1.4, // codigo nacional
		5.4, // descripcion
		1.0, // caja
		1.9, // Ubicacion
		0.6, // CP
		0.6, // CS
		1.3, // CBonif
		1.2, // PVD
		1.3, // Importe Neto
		1.0, // IVA
		1.0, // PVP
		0.5, // CAB
		0.2, // - CENTER separator
		1.4, // Codigo nacional
		4.8, // Descripcion
		0.4, // O
		0.6, // CP
		0.6, // CS
		2.0, // CBonif
		0.5, // CAB
		0.5 // MAB
	];

	rs.beforeFirst();
	console.log("+++++ cell align should be as data!!");
	var table = fopWrapper.addBlock().addTable().addResultSet(rs);
	table.setBorderStyle("solid");
	table.setBorderWidth("0.5pt");
	table.setFontSize(7.5);
	table.forEach(column => {
		column.setColumnWidth(widths[column.getColumnIndex()]);
		switch (column.getColumnIndex()) {
			case 11:
			case 19:
			case 20:
				column.setAlign("center");
				break;
		}
	});
	table.getHeader().getRows().forEach(row => {
		row.setBackgroundColor("#EAEAEA");
		row.forEach(cell => {
			if (cell.getColumnIndex() == 12) {
				cell.setBackgroundColor("red");
			}
			cell.setFontWeight("bold");
			cell.setPadding("1pt");
			cell.setBorderStyle("solid");
		});
	});
	table.getBody().getRows().forEach(row => {
		row.forEach(cell => {
			if (cell.getColumnIndex() != 12) {
				cell.setPadding("1pt");
				cell.setBorderStyle("solid");
			}
		});
	});
}

function addOfertaDeLaSemana(fopWrapper)
{
	var rs = getOfertaDeLaSemana();
	var table = fopWrapper.addBlock().addTable()
	.setFontSize(8)
	.setBorderStyle("solid")
	.setBorderWidth("0.25pt")
	.setSpaceBefore("10pt")
	.addResultSet(rs);
	
	table.setCaption("OFERTA DE LA SEMANA").setMargin("1pt").setPadding("1pt").setBackgroundColor("#999999");
	
	table.forEach(column => {
		column.getCell().setMargin("1pt");
		column.getCell().setFontWeight("bold");
		switch (column.getColumnIndex()) {
			case 0: column.setColumnWidth(2.5); break;
			case 1: column.setColumnWidth(9.0); break;
			case 2: column.setColumnWidth(5.5); break;
		}
	});
	table.getHeader().getRows().forEach(row => {
		row.setBackgroundColor("#EAEAEA");
	});
	table.getBody().getRows().forEach(row => {
		row.forEach(cell => {
			cell.setMargin("1pt");
		});
	});
	table.setFontSize(9);
}

/**
*
*/
function createWaterMarkPDF()
{
	console.log("createWaterMarkPDF");
	var svg =
	"<svg:svg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 1000'>                                              " +
	/*
	"<svg:rect x='0' y='0' width='1000' height='1000' fill='none' stroke='red' />                                                    " +
	"<svg:circle cx='100' cy='100' r='50' fill='none' stroke='black'/>                                                               " +
	"<svg:circle cx='220' cy='100' r='35' fill='red' stroke='black'/>                                                                " +
	"<svg:circle cx='340' cy='100' r='20' fill='black' stroke='lime' stroke-width='4'/>                                              " +
	"<svg:circle cx='100' cy='260' r='20' stroke='lime' fill='yellow' stroke-width='4'/>                                             " +
	"<svg:circle cx='220' cy='260' r='35' stroke='none' fill='blue'/>                                                                " +
	"<svg:circle cx='340' cy='260' r='50' stroke='red' fill='none' stroke-width='10'/>                                               " +
	*/
	"<svg:line x1='1' x2='1' y1='0' y2='1000' stroke='#000000' stroke-width='2' stroke-linecap='round' stroke-dasharray='1, 4'/>     " +
	"</svg:svg>";
	var root = new Ax.fop.FOPDocumentBuilder().createA4Document();
	root.rotate();
	root.getPageMaster().getRegionBody().setMargins(17.5, 0.0, 0.0, 0.0);
	root.getBodyFlow().addBlock().addInstreamForeignObject(svg).setContentHeight("20.0cm").setContentWidth("20.0cm");
	
		/* TODO
	fop2File(root, "watermark", true);
	*/
}

function getHeaderResultSet()
{
	var rows = [];
	rows.push([
		"0157170",
		"ANTISEPTICO DESINFECTOL 500 ML CON MUESTRA GRATIS",
		"644159",
		"037012051",
		1,
		1,
		null,
		4.88,
		4.88,
		21,
		null,
		null,
		// SEPARATOR
		null,
		// SECOND PART
		"0157170",
		"ANTISEPTICO DESINFECTOL 500 ML",
		"F",
		1,
		1,
		null,
		null,
		null,
		]
	);
rows.push([
		"067045",
		"SULFITO DE AMONIO BARRIL",
		"467321",
		"736278112",
		1,
		1,
		null,
		53.12,
		53.12,
		21,
		null,
		null,
		// SEPARATOR
		null,
		// SECOND PART
		"067045",
		"SULFITO DE AMONIO BARRIL",
		"",
		1,
		1,
		null,
		null,
		null,
		]
	);
	
	var rs = new Ax.rs.Reader().build(rows, options => {
		options.setColumnNames(
			[
			"Código\nNacional",
			"Descripción",
			"Caja",
			"Ubicac.",
			"CP",
			"CS",
			"CBonif\n/%DTO",
			"P.V.D",
			"Importe\nNeto",
			"%IVA",
			"P.V.P",
			"C\nAB",
			// SEPARATOR
			"-",
			// SECOND PART
			"Código\nNacional",
			"Descripción",
			"O",
			"CP",
			"CS",
			"CBonif/\n%Dto.",
			"C\nAB",
			"M\nAB"
			]
		);
		options.setColumnTypes(
			[
			Ax.sql.Types.CHAR,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.INTEGER,
			Ax.sql.Types.INTEGER,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.DOUBLE,
			Ax.sql.Types.DOUBLE,
			Ax.sql.Types.DOUBLE,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.CHAR,
			// SEPARATOR
			Ax.sql.Types.CHAR,
			// SECOND PART
			Ax.sql.Types.CHAR,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.INTEGER,
			Ax.sql.Types.INTEGER,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.CHAR,
			Ax.sql.Types.CHAR
			]
		);
	});
	return rs;
}

function getOfertaDeLaSemana()
{
	var rows = [
	[ "0179558", "GUANTE LATEX POLVO T/L      ", "DESDE 1 UNITS: -20% DT." ],
	[ "0179557", "GUANTE LATEX POLVO T/M      ", "DESDE 1 UNITS: -20% DT." ],
	[ "0179555", "GUANTE LATEX POLVO T/S      ", "DESDE 1 UNITS: -20% DT." ],
	[ "0183963", "GUANTE NITRILO SIN POLVO T L", "DESDE 1 UNITS: -20% DT." ],
	[ "0183961", "GUANTE NITRILO SIN POLVO T M", "DESDE 1 UNITS: -20% DT." ],
	[ "0183960", "GUANTE NITRILO SIN POLVO T S", "DESDE 1 UNITS: -20% DT." ],
	]
	var rs = new Ax.rs.Reader().build(rows, options => {
	options.setColumnNames(
	[
	"Código\nNacional",
	"Descripción",
	"Oferta"
	]);
	options.setColumnTypes(
	[
	Ax.sql.Types.CHAR,
	Ax.sql.Types.CHAR,
	Ax.sql.Types.CHAR
	]);
	});
	return rs;
}

function getTipologia()
{
	var rows = [
	[ "MINORISTA", 0, 0, 0 ],
	[ "GRAN VOLUMEN", 0, 0, 0 ],
	[ "PROD.QUIMICO", 4.59, -0.29, 4.88 ],
	[ "TOTAL", 4.59, -0.29, 4.88 ]
	];
	var rs = new Ax.rs.Reader().build(rows, options => {
	options.setColumnNames(
	[
	"TIPOLOGIA",
	"P.V.D",
	"DTO",
	"NETO"
	]);
	options.setColumnTypes(
	[
	Ax.sql.Types.CHAR,
	Ax.sql.Types.DECIMAL,
	Ax.sql.Types.DECIMAL,
	Ax.sql.Types.DECIMAL
	]);
	});
	return rs;
}

function getBasesImponibles()
{
	var rows = [
	["BASES\nIMPONIBLES", null, null, 4.88]
	];
	var rs = new Ax.rs.Reader().build(rows, options => {
	options.setColumnNames(
	[
	"",
	"I.V.A 4%",
	"I.V.A 10%",
	"I.V.A 21%"
	]);
	options.setColumnTypes(
	[
	Ax.sql.Types.CHAR,
	Ax.sql.Types.DECIMAL,
	Ax.sql.Types.DECIMAL,
	Ax.sql.Types.DECIMAL
	]);
	});
	return rs;
}

function getBarcode128(msg)
{
	//var svg = new Ax.barcode.SVG(msg).setPrintText(true).setHeight(1.25).toCode128();
	//var svg = new Ax.barcode.QrCode(msg).toSVG().replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "").replace("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">", "").replace(/[\r\n]+/g, "");
	var svg = new Ax.barcode.QrCode(msg).toSVG().replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "").replace("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">", "");
	console.log(svg);
	return svg;
}

//createWaterMarkPDF();

    var template = new Ax.fop.SinglePageTemplate("A4");

    // =======================================================================
    // CONFIGURE FOP ROOT LAYOUT
    // =======================================================================

    template.setRoot(root => {
        //root.setDebug("*");
        root.rotate();
        root.getSimplePageMaster().getRegionBefore().setExtent(6.5);
        root.getSimplePageMaster().getRegionAfter().setExtent(1.5);
        root.getSimplePageMaster().getRegionStart().setExtent(0);
        root.getSimplePageMaster().getRegionEnd().setExtent(0);
		root.getSimplePageMaster().setMargins(0.5, 0.5, 0.5, 0.5);
    });


    // =======================================================================
    // SET START & END VOID REGION CONTENT
    // =======================================================================
    template.setStart(start => {
        // VOID
    });
    template.setEnd(end => {
        // VOID
    });

    // =======================================================================
    // SET BEFORE REGION CONTENT
    // =======================================================================
    template.setBefore(before => {
// ===========================================================================
// Header
//
// [ALBARAN                             mimaos.png| |ALBRAN        mimaos.png]
// [
// [ Superfarma
// [ CL/PINTOR
// [ 020202 PETRER
// [ NIF: 339393
// [ Tel...
// [
// [ Farmacia Fecha pedido Hora Refencia..        | |Farmacia Fecha pedidos  ]
// [ MM-23333  19-10-2017
// ===========================================================================

var blockHeader   = before.addBlock();

var header_left   = blockHeader.addInlineContainer().setWidth("17.2cm");
var header_center = blockHeader.addInlineContainer().setWidth("0.8cm"); //.setBackgroundColor("#BBBBBB");
var header_right  = blockHeader.addInlineContainer().setWidth("10.8cm");

// ====================================================================
// Header LEFT
// ====================================================================
header_left.addBlockContainer()
			.setPosition("absolute")
			.setLeft("0.1cm")
			.addBlock()
			.addExternalGraphic(logo_albaran).setContentWidth("3.5cm");

header_left.addBlockContainer()
			.setPosition("absolute")
			.setLeft("13.0cm")
			.setWidth("4.2cm")
			.addBlock()
			.setTextAlign("right")
			.addExternalGraphic(logo_mimaos).setContentWidth("2.0cm");

addDirection(header_left);
header_left.addBlockContainer()
			.setPosition("absolute")
			.setTop("2.5cm")
			.setLeft("8.0cm")
			.addBlock()
			.addInstreamForeignObject(getBarcode128("1710-0416668 19-10-17 4,88 20-11-17")).setContentHeight(2.5);
addLeftTable(header_left.addBlockContainer()
			.setPosition("absolute")
			.setTop("5cm")
			.setLeft("0.0cm"));

// ====================================================================
// Header center
// ====================================================================
header_center.addBlockContainer().addBlock("."); // If not present, header_left and right disapears

header_center.addBlockContainer()
			.setWidth("0.2cm")
			.setHeight("19.0cm")
			.addBlock()
			//.addInstreamForeignObject(`<svg xmlns="http://www.w3.org/2000/svg" version="1.1" stroke="none"><path stroke-dasharray="5,5" d="M 0,0 V 8000" stroke="green" stroke-width="2" /></svg>`).setContentHeight("20.0cm"); //.setContentWidth("0.2cm")
			.addInstreamForeignObject(`<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="12px" height="1000px" viewBox="0 0 12 1000"><path stroke-dasharray="5,5" d="M 5,0 V 1000" stroke="green" stroke-width="1" /></svg>`).setContentHeight("20.0cm");
			//.addBlock(".");

// ====================================================================
// Header right
// ====================================================================
header_right.addBlockContainer()
			.setPosition("absolute")
			.setTop("0cm")
			.setLeft("18cm")
			.addBlock()
			.addExternalGraphic(logo_albaran).setContentWidth("3.5cm");

header_right.addBlockContainer()
			.setPosition("absolute")
			.setLeft("24.4cm")
			.setWidth("4.2cm")
			.addBlock()
			.setTextAlign("right")
			.addExternalGraphic(logo_mimaos).setContentWidth("2.0cm");

addDirection(header_right);
header_right.addBlockContainer()
			.setPosition("absolute")
			.setTop("2.5cm")
			.setLeft("25.0cm")
			.addBlock().addBlock().addInstreamForeignObject(getBarcode128("1710-0416668")).setContentHeight(2.5);
			addRightTable(header_right.addBlockContainer()
			.setPosition("absolute")
			// Don't know why width is need... but if not set, content is lost in thin width
			.setWidth("10.8cm")
			.setTop("5cm")
			.setLeft("17.8cm"));
});

// =======================================================================
// SET AFTER REGION CONTENT
// =======================================================================
template.setAfter(after => {
	var blockFooter   = after.addBlock();
	var footer_left   = blockFooter.addInlineContainer().setWidth("17.2cm");
	var footer_center = blockFooter.addInlineContainer().setWidth("0.4cm").setBackgroundColor("yellow");
	var footer_right  = blockFooter.addInlineContainer().setWidth("10.8cm"); //.setBackgroundColor("cyan");

	var totalPageNumbeId = after.getRoot().getPageSequence().getTotalPageNumberCitation();

	footer_left.addBlock(
	"TODA RECLAMACIÓN DEBERÁ EFECTUARSE DENTRO DE LOS DIEZ DÍAS SIGUIENTES A LA FECHA DEL ALBARÁN\n"+
	"Logística Avanzada de Transportes, S.L.U. - C/ Descubrimiento 7-13 Zona B3 Parque empresarial Pi-III 35120 Segovia C.I.F. Z12345044\n" +
	"Inscrita en el Registro Mercantil Segovia, Tomo 3138, Folio 15, Hoja 7649, Insc. 1"
	)
				.setFontSize(7)
				.setFontWeight("bold")
				.setFontFamily("Helvetica")
				.setLinefeedTreatment("preserve")
				.setTextAlign("center")
				.setBorderBottomWidth(.5)
				.setBorderBottomStyle("solid");
	footer_center.addBlock(" ");

	var table = footer_right.addTable().setFontSize(8);
	table.addColumn();
	table.addColumn();

	var row1 = table.getBody().addRow();
	var cell11 = row1.addCell().addBlock("Motivo Aono").setFontWeight("bold");
	var cell12 = row1.addCell().addBlock("COLUMNA O").setFontWeight("bold");
	var row2 = table.getBody().addRow();
	var cell21 = row2.addCell().addBlock("ME - MAL ESTADO FALTA GÉNERO\nNI - NO INTERESA").setLinefeedTreatment("preserve");
	var cell22 = row2.addCell().addBlock("CF = CLUB  T = OFERTA DIRECTA");

	var pagenumber = footer_right
							.addBlock()
							.setFontFamily("Helvetica")
							.setFontSize(8)
							.setTextAlign("end")
							.setPaddingTop(6);

	pagenumber.addInline()
			.addText("Page ")
			.putPageNumber()
			.addText(" - ")
			.putPageNumberCitation(totalPageNumbeId);

});

// =======================================================================
// SET BODY FLOW CONTENT
// =======================================================================
template.setBody(body => {
	addBodyTable(body.getWrapper(), 28.5);
	addOfertaDeLaSemana(body.getWrapper());
	addIndentedDataTable(body.getWrapper(), getTipologia());
	addIndentedDataTable(body.getWrapper(), getBasesImponibles());
});

// =======================================================================
// SET BODY FOOT NOTE CONTENT
// =======================================================================
template.setBodyFootNote(footnote => {
    // TODO
});

// ====================================================================
// GENERATE PDF
// ====================================================================
var fop = template.toFOP();
console.log(fop);

// ====================================================================
// WaterMark
// ====================================================================
//byte[] temp = fop2byte(root, "companybg", true);

//WaterWark wm = new WaterWark(temp, Overlay.Position.FOREGROUND);
//wm.setOverlay("/tmp/watermark.pdf", Pages.ALL);

var pdf = new Ax.fop.Processor().transform(fop);

return pdf;
Click here to download the PDF example

6 Atomic examples

This section shows some atomic micro-examples showing advanced fop generation functionality.

6.1 Dynamic row styles

This example, uses getCells() method to obtain a list of all cells containe in a FOP Table Row.

Copy
var template = new Ax.fop.SinglePageTemplate("A4");
template.setBody(body => { var table_cond = body.addTable();
    table_cond.setSpaceBefore("20pt"); table_cond.setBorderColor("black").setBorderStyle("solid");
    table_cond.addColumn("Referencia de pedido").setColumnWidth(6).setAlign("center");
    table_cond.addColumn("Fecha de pedido").setColumnWidth(6).setAlign("center");
    table_cond.addColumn("Transportista").setColumnWidth(7).setAlign("center");

    table_cond.getHeader().getRows().forEach(row => {
        row.setBackgroundColor("#CCCCCC");
    });
    table_cond.getHeader().getColumns().forEach(col => {
        col.getCell().setFontWeight("bold");
    });

    var row_cond = table_cond.getBody().addRow("REFTER1", "01-01-2021", "TRANSPORT");
    var row_cond = table_cond.getBody().addRow("REFTER2", "04-01-2021", "ALTERNATE");
    var row_cond = table_cond.getBody().addRow("REFTER3", "06-01-2021", "TRANS_R3");
    var row_cond = table_cond.getBody().addRow("REFTER4", "07-01-2021", "R4 TRANS");
    rpos=0; table_cond.getBody().getRows().forEach(row => {
    if (++rpos % 2 == 0) { row.setBackgroundColor("yellow"); 
        row.getCells().forEach(col => {
            col.setFontWeight("bold");
        });
    }
    });
});
var fop = template.toFOP();let pdf = new Ax.fop.Processor().transform(fop);
return pdf;

6.2 FOP Block Container

fo:block-container is a container of blocks. Into a table cell, setting overflow property to hidden allows to hidde the text overflowing cell size.

Copy
// Implement block-container and allow to set overflow property
// Documentation: https://www.w3.org/2002/08/XSLFOsummary.html#block
// Other docs: http://www.datypic.com/sc/fo11/e-fo_block-container.html

var template = new Ax.fop.SinglePageTemplate("A4");

template.setBody(body => {
    var table = body.addTable();

    table.setSpaceBefore("20pt");
    table.addColumn().setColumnWidth(1);
    table.addColumn().setColumnWidth(1);

    var row1 = table.getBody().addRow();
    var c11 = row1.addCell();
    var c12 = row1.addCell();
 
    c11.addBlockContainer().setOverflow("hidden").addBlock("Iamtoowideforacell");
    c12.addBlockContainer().setOverflow("hidden").addBlock("Iamtoowideforacell");
});

var fop = template.toFOP();
console.log(fop);
let pdf = new Ax.fop.Processor().transform(fop);

return pdf;

6.3 FOP Inline Container

In FO, fo:block is similar to HTML <div> and fo:inline-container is similar to HTML <span>

In this example you define two diferent inline blocks that are rendered in the same line, one beside the other.

Copy
var template = new Ax.fop.SinglePageTemplate("A4");
template.setBody(body => {
    var blk = body.addBlock().setFontSize(0);
    var ic1 = blk.addInlineContainer().setInlineProgressionDimension("80mm");
    var ic2 = blk.addInlineContainer().setInlineProgressionDimension("130mm");

    ic1.addBlock("Text left").setTextAlign("left").setFontSize(10).setBackgroundColor("red");
    ic2.addBlock("Text right").setTextAlign("right").setFontSize(10).setBackgroundColor("yellow");
});

var fop = template.toFOP();
console.log(fop);
let pdf = new Ax.fop.Processor().transform(fop);

return pdf;

7 Dashboard examples

The following example provides some dasboard examples. In the examples we will see how to combine text, charts and reports automatically rendered from a resultset.

To do that we will use a subset of data from foodmart example database.

7.1 Foodmart database tables

7.2 Dashboard example 1

TO DO

This section is incomplete and will be concluded as soon as possible.