This document shows some examples of interesting FOP techniques to create advanced documents using FOP

1 Makers Usage

Markers allows to add dynamic content to static page areas like before, after, start or end

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

var IMAGE = "base64:,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVAQAAAACBbJg7AAAACXBIWXMAABcSAAAXEgFnn9JSAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAFUlEQVR42mJgYGBnoDIGAAAA//8DABffAJTyC7mIAAAAAElFTkSuQmCC";

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

template.setRoot(root => {
    //root.setDebug("*");
    root.getSimplePageMaster().getRegionBefore().setExtent(2.0);
    root.getSimplePageMaster().getRegionAfter().setExtent(2.0);
    root.getSimplePageMaster().getRegionStart().setExtent(2.0);
    root.getSimplePageMaster().getRegionEnd().setExtent(2.0).setReferenceOrientation(0);
    root.getSimplePageMaster().setMargins(0, 0, 0, 0);
    
    var block = root.getStaticContentEnd().addBlock().setTextAlign("right").setFontSize("12").setFontWeight("bold");
    block.addBlockContainer().setAbsolutePosition("absolute").setTop("20mm").addBlock().addRetrieveMarker("index-A").setRetrievePosition("first-including-carryover").setRetrieveBoundary("page");
    block.addBlockContainer().setAbsolutePosition("absolute").setTop("25mm").addBlock().addRetrieveMarker("index-B").setRetrievePosition("first-including-carryover").setRetrieveBoundary("page");
    block.addBlockContainer().setAbsolutePosition("absolute").setTop("30mm").addBlock().addRetrieveMarker("index-C").setRetrievePosition("first-including-carryover").setRetrieveBoundary("page");
    block.addBlockContainer().setAbsolutePosition("absolute").setTop("35mm").addBlock().addRetrieveMarker("index-D").setRetrievePosition("first-including-carryover").setRetrieveBoundary("page");
    block.addBlockContainer().setAbsolutePosition("absolute").setTop("40mm").addBlock().addRetrieveMarker("index-E").setRetrievePosition("first-including-carryover").setRetrieveBoundary("page");
    block.addBlockContainer().setAbsolutePosition("absolute").setTop("45mm").addBlock().addRetrieveMarker("index-F").setRetrievePosition("first-including-carryover").setRetrieveBoundary("page");
    block.addBlockContainer().setAbsolutePosition("absolute").setTop("50mm").addBlock().addRetrieveMarker("index-G").setRetrievePosition("first-including-carryover").setRetrieveBoundary("page");
});

// =======================================================================
// SET AFTER REGION CONTENT
// =======================================================================

template.setAfter(after => {
    let totalPageNumberId = after.getRoot().getPageSequence().getTotalPageNumberCitation();
    
    
    let footer = after.addTable();
    footer.addColumn();
    footer.addColumn();

    let r1 = footer.getBody().addRow();

    r1.addCell()
        .addBlock()
        .setFontSize(8)
        .setPaddingTop(5)
        .setTextAlign("left")
        .addInline()
        .addText("Acme Company LTD") 
    ;
    
    r1.addCell()
        .addBlock()
        .setFontSize(8)
        .setPaddingTop(5)
        .setTextAlign("end")
        .addInline()
        .addText("Pág. ")
        .putPageNumber()
        .addText(" / ")
        .putPageNumberCitation(totalPageNumberId)
    ;
});

// =======================================================================
// SET BODY FLOW CONTENT
// =======================================================================
template.setBody(body => {
    var sectionL1  = body.getRoot().createBlockProperties().setSpaceBefore(10, "pt").setFontSize(16).setFontWeight("bold"); 
    var sectionL2  = body.getRoot().createBlockProperties().setSpaceBefore(10, "pt").setFontSize(12); 
        
   body.addBlock("THUMB INDEX")
	   .setFontFamily("sans-serif")
	   .setFontSize("2em")
	   .setFontWeight("bold")
	   .setPaddingBefore("0.3em")
	   .setPaddingAfter("0.3em")
	   .setSpaceBefore("1em")
	   .setSpaceAfter("1em");     
     
    var root1 = body.addBlock("Prints thumb indexes on the right side of the page. Thumb indexes are generated automatically.");
    var root2 = body.addBlock().setLineHeight("2em");
     
    var letters = ["A", "B", "C", "D", "E", "F", "G"];   
        
    for (var letter of letters) {
	  	var marker = root2.addBlock()
	  		.addBlock()
	  		.addMarker("index-" + letter)
	  		.addText(letter)
	  		.addExternalGraphic(IMAGE)
	  		.setContentWidth(0.4);
			
			
		root2.addBlock()
			.setKeepWithNext("always")
			.setTextAlign("center")
			.setFontSize("1.4em")
			.setFontWeight("bold")
			.setBackgroundColor("#97D8F0")
			.setBorderStyle("solid")
			.setBorderWidth(0.2)
			.addText(letter);
			
		var list = root2.addListBlock()
			.setProvisionalDistanceBetweenStarts("6cm")
			.setProvisionalLabelSeparation("3pt");
		
		for (var idx = 1; idx < 8; idx++) {
			list.addItem((l,b) => {
				l.addBlock(letter + idx).setFontStyle("italic");
				b.addBlock("Sample").setFontWeight("bold");
			})
		}
	}

});

// ====================================================================
// GENERATE PDF
// ====================================================================
let fop = template.toFOP();
//new Ax.io.File("/tmp/test.fop").write(fop);

let pdf = new Ax.fop.Processor().transform(fop);
//new Ax.io.File("/tmp/test.pdf").write(pdf);

return pdf;

Next example shows a simple usage of marker to show the last content of the marker at the footer of the page:

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

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

// =======================================================================
// SET AFTER REGION CONTENT
// =======================================================================
template.setAfter(after => {
    
    after.addBlock().setTextAlign("left").setFontSize("12").setFontWeight("bold")
         .addBlockContainer()
         .addBlock().addText("Section: ")
         .addRetrieveMarker("index");
    
    let totalPageNumberId = after.getRoot().getPageSequence().getTotalPageNumberCitation();

    let footer = after.addTable();
    footer.addColumn();
    footer.addColumn();

    let r1 = footer.getBody().addRow();
    r1.addCell()
        .addBlock()
        .setFontSize(8)
        .setPaddingTop(5)
        .setTextAlign("left")
        .addInline()
        .addText("Acme Company LTD") 
    ;
    r1.addCell()
        .addBlock()
        .setFontSize(8)
        .setPaddingTop(5)
        .setTextAlign("end")
        .addInline()
        .addText("Pág. ")
        .putPageNumber()
        .addText(" / ")
        .putPageNumberCitation(totalPageNumberId)
    ;
});

// =======================================================================
// SET BODY FLOW CONTENT
// =======================================================================
template.setBody(body => {
    var sectionL1  = body.getRoot().createBlockProperties().setSpaceBefore(10, "pt").setFontSize(16).setFontWeight("bold"); 
    var sectionL2  = body.getRoot().createBlockProperties().setSpaceBefore(10, "pt").setFontSize(12); 
        
   body.addBlock("THUMB INDEX")
	   .setFontFamily("sans-serif")
	   .setFontSize("2em")
	   .setFontWeight("bold")
	   .setPaddingBefore("0.3em")
	   .setPaddingAfter("0.3em")
	   .setSpaceBefore("1em")
	   .setSpaceAfter("1em");     
     
    var root1 = body.addBlock("Prints thumb indexes on the right side of the page. Thumb indexes are generated automatically.");
    var root2 = body.addBlock().setLineHeight("2em");
     
    var letters = ["A", "B", "C", "D", "E", "F", "G"];   
        
    for (var letter of letters) {
	  	var marker = root2.addBlock()
	  		.addMarker("index")
	  		.addText(letter);

		root2.addBlock()
			.setKeepWithNext("always")
			.setTextAlign("center")
			.setFontSize("1.4em")
			.setFontWeight("bold")
			.setBackgroundColor("#97D8F0")
			.setBorderStyle("solid")
			.setBorderWidth(0.2)
			.addText(letter);
			
		var list = root2.addListBlock()
			.setProvisionalDistanceBetweenStarts("6cm")
			.setProvisionalLabelSeparation("3pt");
		
		for (var idx = 1; idx < 8; idx++) {
			list.addItem((l,b) => {
				l.addBlock(letter + idx).setFontStyle("italic");
				b.addBlock("Sample").setFontWeight("bold");
			})
		}
	}
});

// ====================================================================
// GENERATE PDF
// ====================================================================
let fop = template.toFOP();
let pdf = new Ax.fop.Processor().transform(fop);

return pdf;