Link to home
Start Free TrialLog in
Avatar of andrew preciado
andrew preciado

asked on

Angular UI Grid - Exporting an image, along a header, to a pdf

I want to add an image to the header of the pdf.

I am trying to add the image, which I converted to base 64, to exporterPdfHeader.

I added in the column with the image inside exporterPdfHeader, but when I do this it does not show the header which is contained in the body. It just shows the image and the table.

$scope.gridOptions.exporterPdfHeader ={
                    //LOGO TEST (causes the header to disappear..
                    columns: [{
                            image: //long data url
                            width: 150
                    }],

                    margin: [30, 5, 30, 15],
                    table: {
                    widths: [ '*', '*', '*' /*, '*'*/ ],

                    body: [

                           [ 'Region: ' + $scope.region, 'Group: ' + $scope.group, 'MC: ' + $scope.mc /*, 'The last one'*/ ],
                           [ 'District #: ' + $scope.district, 'Route #: ' + $scope.route, 'Week Ending Date: ' + $scope.weekEndDate, /*, 'Value 4' */],

                    ]
                  },



    };

How can I export BOTH the header and the image.  Can I do both within exporterPdfHeader?
Any help is much appreciated.  Thanks
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Please explain more about your application, what libraries it uses and more code - all you have given us is a random JavaScript object that means nothing outside the context of your application (which we don't have)
Avatar of andrew preciado
andrew preciado

ASKER

I apologize, here are more details.

My application contains a search filter which filters certain parameters such as Region #, Group, etc, all showcased within the body of the exporterPdfHeader.

For the main page, there are 7 tabs all containing different table data.  On the main page containing all the tabs, there is a 'Printer Friendly' button which exports the data of the selected tab as a pdf in a new tab within the browser.  

main.html contains all tabs and the printer friendly btn
 
               <li style="float: right;">		
	            <button ng-click="printDiv('rollup-tab')">Printer Friendly</button>
	  	</li>

Open in new window


This button then goes to the js, which then is broadcasted to each tab
       
$scope.printDiv = function(divName) {
		//BROADCAST TO EACH TAB
		$rootScope.$broadcast('print');	
		
	}

Open in new window


For this example, we are broadcasting the to Net page by encapsulating the exporterPdfHeader function within the print broadcast.

       
$scope.$on('print', function(event, filter) {
              $scope.gridOptions.exporterPdfHeader = {
              .....
             //code above
             }
       $scope.export();
       });

Open in new window


This then goes to the export function which is causes the pdf to be exported.

      
$scope.export = function() {
      .....
      var content = uiGridExporterService.prepareAsPdf($scope.gridApi.grid, exportColumnHeaders, exportData);
	      
	      //LOGO TEST (needed to show the image) and does not show the header	   
	      content.pageMargins = [40, 80, 40, 60];	

	      pdfMake.createPdf(content).open();
     }

Open in new window


I HAVE to set these pageMargins for the image to show.  As well show the columns within exporterPdfHeader

I am writing my code with AngularJS trying to export a UI-Grid, using the pdfmake library to export the grid as a pdf
pdfmake: http://pdfmake.org/#/gettingstarted
angular-uigrid: https://github.com/angular-ui/ui-grid

For some reason the site cannot be reached for the ui-grid docs, but I am using ui-grid-exporter for gridOptions
http://ui-grid.info/docs/

Here are the columns which are defined within scope.gridOptions

       
$scope.gridOptions = {
		treeRowHeaderAlwaysVisible : true,
		showColumnFooter : true,
		enableHorizontalScrollbar : 0,
		showTreeExpandNoChildren : true,
		enableGridMenu : false,
		enableSorting : false,
		multiSelect : false,
		headerTemplate : 'app/views/common/templates/category_header.html',
		category : [ {
			name : 'column1',
			visible : true,
			showCatName : false
		}, {
			name : 'MONDAY',
			visible : true,
			showCatName : true
		}],
		columnDefs : [ {
			name : 'routeName',
			displayName : $scope.rollup,
			category : "column1",
			width : '12%',
			footerCellTemplate : '<div class="ui-grid-cell-contents text-center">Total:</div>',
			headerCellTemplate: '<div ng-class="{ \'sortable\': sortable }"><div class="ui-grid-vertical-bar">&nbsp;</div><div class="ui-grid-cell-contents" col-index="renderIndex"><span>{{ grid.appScope.rollup}}</span><span ui-grid-visible="col.sort.direction" ng-class="{ \'ui-grid-icon-up-dir\': col.sort.direction == asc, \'ui-grid-icon-down-dir\': col.sort.direction == desc, \'ui-grid-icon-blank\': !col.sort.direction }">&nbsp;</span></div><div class="ui-grid-column-menu-button" ng-if="grid.options.enableColumnMenus && !col.isRowHeader  && col.colDef.enableColumnMenu !== false" class="ui-grid-column-menu-button" ng-click="toggleMenu($event)"><i class="ui-grid-icon-angle-down">&nbsp;</i></div><div ng-if="filterable" class="ui-grid-filter-container" ng-repeat="colFilter in col.filters"><input type="text" class="ui-grid-filter-input" ng-model="colFilter.term" ng-click="$event.stopPropagation()" ng-attr-placeholder="{{colFilter.placeholder || \'\'}}" /><div class="ui-grid-filter-button" ng-click="colFilter.term = null"><i class="ui-grid-icon-cancel" ng-show="!!colFilter.term">&nbsp;</i> <!-- use !! because angular interprets \'f\' as false --></div></div></div>',					
			enableColumnMenu : false	
		}, {
			name : 'mondayNet',
			cellFilter: 'currency',
			displayName : 'Net',
			category : "MONDAY",
			exporterPdfAlign: 'right',
			width : '14%',	
			cellTemplate : 'app/views/common/templates/cell/pos-neg-cell-template.html',
			footerCellTemplate : '<div class="ui-grid-cell-contents text-center" ng-class="{positive : col.getAggregationValue() > 0, negative : col.getAggregationValue() < 1}">{{col.getAggregationValue() | number : 2}}</div>',
			aggregationType : uiGridConstants.aggregationTypes.sum,
			enableColumnMenu : false
		} ],
		
		//PRINT PDF
	     exporterHeaderFilterUseName: true,		
	     exporterPdfDefaultStyle: {fontSize: 9},
	    						//left, top, right,bottom   
	    exporterPdfTableStyle: {margin: [0, 10, 0, 15]},
	    exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red', alignment: 'center'},
	    exporterPdfOrientation: 'portrait',
	    exporterPdfPageSize: 'LETTER',
	    exporterPdfMaxGridWidth: 475,
	    
	    exporterHeaderFilter: function( displayName ) {
    	
	    	if( displayName === 'routeName' ) { 
			      return 'Route'; 
			    }
	    	if( displayName === 'mondayNet' ) { 
			      return 'MONDAY        Net'; 
			    }
   
	        else { 
	          return displayName;
	        } 
	    	 exporterSuppressColumns: ['gender','company'];
	
	      },
		data : data,
		onRegisterApi : function(gridApi) {
			$scope.gridApi = gridApi;
		}
	};

Open in new window

I am just showing one column, but i have columns for the rest of the week.  The code for monday applies to the rest of the week.

Is there anything else you need so I can solve my problem?  If so please let me know, I am struggling with this issue.  Thank you
Thank you - that was very useful and provides the context needed for going forward.

So to summarise you are using pdfMake that does Client side (JavaScript) rendering of a PDF document and you need to add a header image.

Is that correct?

The fact that you are using Angular should not be an issue have you read this forum which discusses this?

https://github.com/bpampuch/pdfmake/issues/28
Yes, I want to export a logo header, a separate header, and the ui-grid with all the table data.  

I have seen this article.  Two of the tabs are NOT exporting a ui-grid, so for those tables I was able to export the logo header, header, table, and footer, but since I am exporting a ui-grid I cannot.

When I try something like:

var dd = { 
	header: function() { 
		return { 
			table: { 
				widths: [ '50%','*'],
				body: [ 
					[ { image: 'image1.png', fillColor: '#99D6E3', width:100 }, 							{ image: 'image2.png', fillColor: '#99D6E3', width:100, 							alignment:'right' } 
					] 
				] 
			},
					layout: 'noBorders' } 
			}, 

			content: [ 'First paragraph', 'Another paragraph, this time a little bit 						longer to make sure, this line will be divided into at least two 						lines',
					{ text: 'This isdi osdf iosdf', pageBreak: 'after', } 
			] }
....

Open in new window


This structure does not seem to work within the $scope.gridOptions.exporterPdfHeader function.  

Here is an example of another tab where I created what I need:
$scope.$on('print', function(event, filter) {
			var docDefinition = {
					info: {
					    title: 'LCP'
					    
					  },
					content: [
					          
							{
							    margin: [0, -40, 0, 30],	 	
								image: //long image base64 url
								width: 200,
								height: 58,
								style: 'centerImage',

							  },					  
					         
					         {
						        	  fontSize: 9,
								       margin: [0,-30, 0, 10],
								       
									  table: {
										  headerRows: 1,
										  widths: [ '*', '*', '*'],
			
									       body: [  
									        [ 'Region: ' + $scope.region, 'Group: ' + $scope.group, 'MC: ' + $scope.mc],
									        [ 'District #: ' + $scope.district, 'Route #: ' + $scope.route, 'Week Ending Date: ' + $scope.weekEndDate],  
								       ]
								  },
						        	  
						     }, 

							 {
								margin: [-30,0,-30,-30],

								fontSize: 6,
								
							      table: {
							       
							        headerRows: 1,
							        widths: [ 25, 50, 45, 50, 50, 50, 50, 50, 50, 30, 30], 

						            dontBreakRows: true,
						            
							        body: [
							          [ //table data],
							        ]
							      }
											
							  },


						        {
						        	  fontSize: 9,			        	
								       margin: [0,40,0,0],
								       
									  table: {
										  headerRows: 1,
										  widths: [ '*', '*', '*', '*', '*', '*'],
											 
									       body: [  											              
									        [//footer data],																																									     
									       ]
									  },
						        	  
						        }, 					
		     
					        ],

							  styles: {
								  tableData: {
								  alignment: 'right',
							  	  },
							  	  
							  	  centerImage: {
								  alignment: 'center'
							      },
							  	  
							  }
			
					};
				pdfMake.createPdf(docDefinition).open();
			
		});

Open in new window


For this tab I had to recreate the table and insert the data by row, but since I am exporting a ui-grid this process does not work the same.
I see - not sure how to assist here - do you have a link that demonstrates the issue?

Not promising this can help the question is quite narrowly focused (pdfMake + Angular UI-Grid) so not sure you are going to find someone who knows how to do this but we can maybe give suggestions.
For some reason my plunker is not exporting correctly all of a sudden:
http://plnkr.co/edit/1rL7ZBPu9mPym8SEjMxe?p=preview

I can show the code when the image is exported but then replaces the header contained in the table.

When I put the image url within the exporterPdfHeader function, it seems to not go inside the table for some reason.
I have tried to put the image within a variable above the exporterPdfHeader, but still does not work.  I have also tried to play with the page margins, but still no luck.  

//PRINT PDF TEST
$scope.$on('print', function(event, filter) {
	
		$scope.gridOptions.exporterPdfHeader ={
		   			 	columns: [{
		   			 	        margin: [176, -5, 30, 15],
		   			 	       
					            image: //long base64 url
					        	width: 200,
					        	height: 58,  			 	
		   			 	}],	
		   			 	margin: [30, 10, 30, 10],
		   			 	table: {		 
			        		
			  		        widths: [ '*', '*', '*' ],
			  		        body: [
			  		               [ 'Region: ' + $scope.region, 'Group: ' + $scope.group, 'MC: ' + $scope.mc ],
			  		               [ 'District #: ' + $scope.district, 'Route #: ' + $scope.route, 'Week Ending Date: ' + $scope.weekEndDate],
				  		  		              
			  		        ]
			  		    },	
				
		};

		$scope.export();

Open in new window


Here is another example where I asked the question:
http://stackoverflow.com/questions/42981314/angular-ui-grid-exporting-an-image-to-a-pdf
ASKER CERTIFIED SOLUTION
Avatar of andrew preciado
andrew preciado

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Solved the issue myself