Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pdf export not working all data with large table #4757

Closed
tiagomsmagalhaes opened this issue Nov 23, 2015 · 24 comments
Closed

pdf export not working all data with large table #4757

tiagomsmagalhaes opened this issue Nov 23, 2015 · 24 comments

Comments

@tiagomsmagalhaes
Copy link

Hi,

I'm running ui-grid 3.0.7 and the export pdf does nothing on a table that has around 250 results with 17 columns. If I select a few rows i get the pdf... but if I select export visible data or all data it does open a tab but with no action.

@tiagomsmagalhaes
Copy link
Author

i can't provide a plunker, but tutorial 401 doesn't work for me... http://ui-grid.info/docs/#/tutorial/401_AllFeatures

tested in IE11, Chrome 46.0.2490.86 and Firefox 42

@Gonkaro
Copy link

Gonkaro commented Nov 23, 2015

Hello guys, same issue here. When I have too many data the browser simply freaks out when exporting to pdf.

Csv export works fine.

@AgDude
Copy link
Contributor

AgDude commented Nov 23, 2015

This appears to be a duplicate of #2529 (and in turn bpampuch/pdfmake#275). I thought it started working with newer versions of chrome, but apparently it didn't. I am having the same problem now on the 401 tutorial.

pdfMake is a great tool when it works. But we probably need to limit the amount of data we send to it.

@tiagomsmagalhaes
Copy link
Author

@AgDude is it possible to index the pdf generation to a pagination feature? like if we were in the page 3, when exporting it would export only page 3?

i have another grid with 982*3 (rows x columns) and it would export to pdf... but when it's like 250 * 17 it crashes, so it would be related to the columns... but i'm just guessing

@AgDude
Copy link
Contributor

AgDude commented Nov 23, 2015

I was just reading a but more on this, and found this issue and workaround: bpampuch/pdfmake#280 (comment)

@tiagomsmagalhaes would you be able to try that workaround with pdfmake and let us know how that works here?

I think an "export current page" option would be a nice feature, but I wouldn't replace the option to export all. We would welcome a pull request that implemented that.

@tiagomsmagalhaes
Copy link
Author

@AgDude hi... i tried that workaround to my 256*17 grid worked only in IE11... soon after that comment, the OP mentioned a addPageBreaksIfNeccessary but i couldn't find that in the source..

@AgDude
Copy link
Contributor

AgDude commented Nov 23, 2015

@tiagomsmagalhaes You are looking in the pdfMake source, not uiGrid, right?. Have you tried with a new version of pdfMake? I am not sure what version is running on ui-grid.info.

This is something that is on my radar, as I need it in my application as well. I am unlikely to have time in the next few weeks to look into it in detail.

@tiagomsmagalhaes
Copy link
Author

@AgDude Yes, I'm looking at the pdfMake source... I'm not sure if I'm running the most recent because i'm using without package systems.. i could try at home in the MEAN stack

@PaulL1
Copy link
Contributor

PaulL1 commented Nov 23, 2015

I would have thought that export visible data would give the same thing as export current page.

@tiagomsmagalhaes
Copy link
Author

@PaulL1 i confess that i haven't read the default behaviour of that option, but in this situation i'm using the grid with no pagination

@PaulL1
Copy link
Contributor

PaulL1 commented Nov 23, 2015

@tiagomsmagalhaes : I know the pdfMake team don't have very good IE support. Does it work in Chrome?

@tiagomsmagalhaes
Copy link
Author

@PaulL1 i mentioned above that the workaround link provided by @AgDude worked in IE11. i just couldn't figure out one little tweak where the user that created the workaround, because he didn't provide the Line of Code. I think the problem is residing in the columns, because i limited tutorial 401 to 500 rows and it didn't worked. But a colleague was able to generate a pdf with 900 rows and 3 columns, and i have to use one with 17 columns

@cm0n
Copy link

cm0n commented Dec 2, 2015

I have the same issue. I have a table with 13 cols and over 3300 rows, after 20 minute if have kill the tab.
I have also the issue i can not display all 3300 rows with the ui-grid, it is the same behaviour the tab is freezing and use 100% cpu time.

@trentballew1
Copy link

I've had this issue as well. Is there a way with ui-grid to change which pdf library is used for export? That way we could use a library other than pdfMake to create PDF exports instead of being held hostage by the limitations of that particular library. You can do this with ng-grid; it's just not a built-in function.

@AgDude
Copy link
Contributor

AgDude commented Dec 14, 2015

@trentballew1 sure, you can roll your own export. You can start with the grid options from the gridApi, or if you want the docDefinition that gets sent to pdfMake, have a look at (uiGridExportService)[http://ui-grid.info/docs/#/api/ui.grid.exporter.service:uiGridExporterService]. It isn't exposed as part of the public API, but you can still inject it like any other service.

@james-bell
Copy link

@AgDude If there's a way to get the DocDefinition can you give us an example of how to do it? What would I do to fetch and possibly change the DocDefinition?

@PaulL1
Copy link
Contributor

PaulL1 commented Jan 26, 2016

There's a callback that gives you the full doc definition once created and allows you to modify it. Check the exporter gridoptions doco or the complex exporter tutorial.

Sent from my iPhone

On 27 Jan 2016, at 5:09 AM, James Bell <notifications@github.commailto:notifications@github.com> wrote:

@AgDudehttps://github.com/AgDude If there's a way to get the DocDefinition can you give us an example of how to do it? What would I do to fetch and possibly change the DocDefinition?

Reply to this email directly or view it on GitHubhttps://github.com//issues/4757#issuecomment-175094192.

@jaimejosephmxns
Copy link

I implemented the same functionality, when it gets to
uiGridExporterService.csvExport(gridApi);
The property gridApi.rows is = 100, but my total result set is 2307

Is there a way to set the rows to include all the data that came back and not limit to 100?

@farnsy
Copy link

farnsy commented Aug 31, 2016

Not sure if it's any help, but in my experimenting with this I found that chrome defaults to pdfMake.open to just open the pdf in another tab, whereas IE downloads it as a file. If I try to export a large table to pdf in chrome, it breaks. If I try in IE, it downloads fine. I modified the source to always do download instead of open in Chrome, and it worked fine. It would be good if there was a param on ui-grid to specify always download, instead of Opening... Looks like constructing the data url and throwing it to a new tab doesn't perform too well with large tables.

@veica
Copy link

veica commented Sep 9, 2016

@farnsy it seems to me that is the case. How did you modify the source to do download instead of opening in Chrome?

@farnsy
Copy link

farnsy commented Sep 14, 2016

It was a bit hacky at the time as I just wanted to see if it would fix the problem. In ui-grid.js, v3.1.1 at line 18230 is the pdfExport method. That first checks if the browser is IE or Edge, and if so it initiates a download, otherwise it opens (i.e. uses the dataurl method). I just modified this so it always did a download.

@tiagomsmagalhaes
Copy link
Author

@farnsy could you make a PR?

@samaelsimoes
Copy link

Hello, this works for me

app.controller('ExpenseGridCrtl', ['$scope','$http','uiGridExporterConstants', '$log', '$rootScope', 'ExpenseService', '$location', 'toastr',
'UserService', 'GenreService', 'CostCenterService', 'uiGridConstants',

function($scope, $http, uiGridExporterConstants, $log, $rootScope, ExpenseService, $location,  toastr,  
		 UserService, GenreService, CostCenterService,  uiGridConstants) {

$scope.downloadPDFCSV = function(){  
	$scope.gridApi.exporter.pdfExport(uiGridExporterConstants.VISIBLE, $scope.gridOptions.ALL);
	$scope.gridApi.exporter.csvExport(uiGridExporterConstants.VISIBLE, $scope.gridOptions.ALL);
}    

now = new Date;
dayName = new Array("domingo", "segunda", "terça", "quarta", "quinta", "sexta", "sábado");
monName = new Array("janeiro", "fevereiro", "março", "abril", "maio", "junho", "agosto", "outubro", "novembro", "dezembro");
var dia = ("Data: " + now.getDate () + " de " + monName [now.getMonth() ] + " de " + now.getFullYear ());

$scope.expenses = [];
$scope.rows = [];
$scope.users = [];
$scope.costcenters = [];
$scope.typegenres = [];   
$scope.reportexpense = [];
exporterCsvFilename: 'despesas.csv';
enableGridMenu: true;

$scope.loadSelects = function() {	
	UserService.query(function( users ) {
		
		$scope.users = users;	
	}, function( error ) {				
		toastr.error( error );
	});
	
	GenreService.query(function( genres ) {	
		
		$scope.typegenres = genres;	
	}, function( error ) {		
		toastr.error( error );
	});
	
	CostCenterService.query(function( costcenters ) {	
		
		$scope.costcenters = costcenters;
	}, function( error ) {			 
		toastr.error( error );
	});
}

$scope.gridOptions = {
		 
	rowHeight: 35,         
	selectionRowHeaderWidth: 35,
	enableRowSelection: true,
	enableColumnResizing: true,
	multiSelect: true,
	enableSelectAll: true,
	showGridFooter:false,
	paginationPageSize: 10,
	selectedItems: $scope.mySelections,
	enablePaginationControls: false,
    enableFiltering : false,
    enableSelectionBatchEvent: true,
    
	columnDefs: [	
		{ 
			field: 'code',
			displayName: 'Número', 
			enableCellEdit: false, 
			type: "number",
			
			cellTooltip: 
			function( row, col ) {
			  return 'Número: ' + row.entity.code;
			}, headerTooltip: 
			function( col ) {
				return 'Titulo: ' + col.displayName;
			}
		},
		{ 
			field: 'userOid', 
			displayName: 'Usuario', 
			enableCellEdit: false,
			
			cellTooltip: 
			function( row, col ) {
			  return 'Usuario: ' + row.entity.userOid;
			}, headerTooltip: 
			function( col ) {
				return 'Titulo: ' + col.displayName;
			}
		},	
		{ 
			field: 'description', 
			displayName: 'Descrição', 
			enableCellEdit: false,
			
			cellTooltip: 
			function( row, col ) {
		      return 'Descrição: ' + row.entity.description;
		    }, headerTooltip: 
		    function( col ) {
		    	return 'Titulo: ' + col.displayName;
		    }
		},
		{ 
			field: 'value', 
			displayName: 'Valor R$', 
			enableCellEdit: false,
			
			cellTooltip: 
			function( row, col ) {
		      return 'Valor: R$' + row.entity.value;
		    }, headerTooltip: 
		    function( col ) {
		    	return 'Titulo: ' + col.displayName;
		    }
		},
		{ 
			field: 'paidValue', 
			displayName: 'Valor Adiantamento R$', 
			enableCellEdit: false,
			
			cellTooltip: 
			function( row, col ) {
		      return 'Valor de Adiantamento: R$ ' + row.entity.paidValue;
		    }, headerTooltip: 
		    function( col ) {
		    	return 'Titulo: ' + col.displayName;
		    }
		},
		{ 
			field: 'date', 
			displayName: 'Data', 
			enableCellEdit: false,
			
			cellTooltip: 
				function( row, col ) {
			      return 'Data: ' + row.entity.date;
			    }, headerTooltip: 
			    function( col ) {
			    	return 'Titulo: ' + col.displayName;
			    }
		},
		{ 		
			name: 'situation',
			field: 'situation', 
			displayName: 'Situação', 
			
			enableCellEdit: true,
			enableGridMenu: true,
			enableSorting: true,
			multiSelect: true,
			
			cellFilter: 'situationFilter',
			editDropdownValueLabel: 'situation',
			editableCellTemplate: 'ui-grid/dropdownEditor',				
			
			editDropdownOptionsArray: [						
			    { id: 0, situation: 'Aberto' },
			    { id: 1, situation: 'Concluído' },
			    { id: 2, situation: 'Aprovado' },
			    { id: 3, situation: 'Pago' }
			],
			
			cellTooltip: 
				function( row, col ) {						
					
			    	return 'Situação: ' + row.entity.situation;
			    }, headerTooltip: 
			    function( col ) {
			    	return 'Titulo: ' + col.displayName;
			    }
		},		
		{ 
			field: 'costecenterOid', 
			displayName: 'Centro de Custo', 
			enableCellEdit: false,
			
			cellTooltip: 
			function( row, col ) {
		      return 'Centro de custo: ' + row.entity.costecenterOid;
		    }, headerTooltip: 
		    function( col ) {
		    	return 'Titulo: ' + col.displayName;
		    }
		},
		{ 
			field: 'reason', 
			displayName: 'Objetivo da empresa', 
			enableCellEdit: false,	
			
			cellTooltip: 
			function( row, col ) {					
		      return 'Objetivo da empresa: ' + row.entity.reason;
		    }, headerTooltip: 
		    function( col ) {
		    	return 'Titulo: ' + col.displayName;
		    }
		},			
		{ 
			field: 'typeOid', 
			displayName: 'Tipo despesa', 
			enableCellEdit: false,				
			cellTooltip: 
				
			function( row, col ) {
				return 'Tipo de despesa: ' + row.entity.typeOid;
		    }, headerTooltip: 
		    function( col ) {
		    	return 'Titulo: ' + col.displayName;
		    }
		}
	],
	
	enableGridMenu: false,
    enableSelectAll: true,
    
    exporterCsvFilename: 'despesas.csv',
    exporterPdfDefaultStyle: {
    	fontSize: 9
    },
    
    exporterPdfTableStyle: {
    	margin: [0, 30, 30, 30]
    },
    
    exporterPdfTableHeaderStyle: {
    	fontSize: 10, 
    	bold: true, 
    	italics: true, 
    	color: '#000'
    },
    
    exporterPdfHeader: { 
    	text:"Wizfee - relatório de despesas", 
    	style:'headerStyle' 
    },   

    exporterPdfFooter: function ( currentPage, pageCount ) {	    	
    	return { 
    		text: currentPage.toString() + ' de ' + pageCount.toString(), style: 'footerStyle' 
    	};
    },
    
    exporterPdfCustomFormatter: function ( docDefinition ) {	    	
    	docDefinition.styles.headerStyle = {	    			
    		margin: [40, 10, 30, 0],
			fontSize: 22, 
			bold: true 
    	};
    	
        docDefinition.styles.footerStyle = { 
	    	margin: [540, 10, 30, 0],
        	fontSize: 10, 
        	bold: true 
        };
        return docDefinition;
    },
    
    exporterPdfOrientation: 'portrait',
    exporterPdfPageSize: 'LETTER',
    exporterPdfMaxGridWidth: 465,
    exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
};

/* --- Server --- */        // Service
$scope.load = function() { // load all		
	ExpenseService.query(function( expenses ) {
		
		console.log(expenses);
		
		$scope.expenses = expenses;
		$scope.gridOptions.data = expenses;		 		
	}, function( error ) {			 
		toastr.error( error );
	});
};	

//-- end load 
$scope.editExpense = function ( e, t ) {			
	var row = $scope.rows[0].entity;
	$scope.update( row );
};

$scope.update = function ( row ) {
	ExpenseService.update ( row, function (response ) {				
		toastr.success( response.message );
		$scope.load();
	}, function ( err ){
		toastr.error( 'Erro ' + err.data);
	})
};

// ---- ROWS checkeds or unchecked	
$scope.gridOptions.onRegisterApi = function ( gridApi ) {	
	
	$scope.gridApi = gridApi;
	$scope.gridApi.grid.registerRowsProcessor( $scope.singleFilter, 200 );			

	gridApi.selection.on.rowSelectionChanged( $scope, function( row ) {
		
		var msg = row.isSelected; //one selected true or false
	
		if ( msg ) {
			$scope.rows.push( row );
		} else {				
			$scope.rows.splice( $scope.rows.indexOf ( row ) );
		}
	}); // Grid Edit Situation selected
    gridApi.rowEdit.on.saveRow($scope, function(rowEntity){
    	$scope.update( rowEntity );
    });
};	

$scope.filter = function() {
    $scope.gridApi.grid.refresh();
};

$scope.singleFilter = function( renderableRows ) {    	
	var matcher = new RegExp( $scope.filterValue );     	
	renderableRows.forEach( function( row ) {
		
		var match = false;
		
		[ 'code', 'situation', 'date', 'costecenterOid', 'userOid', 'costecenterOid', 'typeOid' ].forEach(function( field ) {    			
			if ( row.entity[field].toString().match(matcher) ) {
				match = true;
			}
		});    		
		if ( !match ) {
			row.visible = false;
		}
    });    	
    return renderableRows;
};    

$scope.aceptdelet = function () {
	
	var rows = $scope.gridApi.selection.getSelectedRows();
	var daterowsid = [];
	
    for (var i=0; i < rows.length; i++) {        	
    	daterowsid.push(rows[i].oid);
    }
    
	$scope.deletrows( daterowsid );
};

// ---=== Delet rowsw
$scope.deletrows = function( ids ) {
	
	var t = ids;
	ExpenseService.remove({ids: t}, function(response) {  
		
		toastr.success("Excluido com sucesso!");
		$scope.load();
	}), function(err) {    		
		toastr.error('Erro ' + err);
	}
};       
$scope.load();

}])

.filter('situationFilter', function() {
var genderHash = {
0: 'Aberto',
1: 'Concluído',
2: 'Aprovado',
3: 'Pago'
};
return function(input) {
if (!input) {
return '';
} else {
return genderHash[input];
}
};
});

@dimit19
Copy link

dimit19 commented Mar 7, 2018

first insert pdf libraries using this command
-> npm install pdfmake

after add pdf file path in your file like.

<script src="node_modules/pdfmake/build/pdfmake.min.js"></script>
    <script src="node_modules/pdfmake/build/vfs_fonts.js"></script>

it is working for me..

Thank you..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests