Can someone help me. how to create a filename when I'm downloading a PDf file. What happens on me, its creating a random filename for my PDF. I want to set a specific filename('Sample Name') if I download it.
function toDataURL(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function(){
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
};
//console.log(reader.onloadend);
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
$('#btnPDF').click(function(){
dashboard.fireChange('prmAction', 'Export');
var name = Utils.getQueryParameter('user');
const month = ['January', 'Febuary', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const qtr = ['1st', '2nd', '3rd', '4th'];
// page size A4: [595.28, 841.89]
var rptHeightP1 = 350.28;
var rptHeight = 505.28;
var rptWidth = 791.89;
var pgMargin = [50,20,50,50];
var now = new Date();
var today = month[now.getMonth()] + ' ' + now.getDate() + ', ' + now.getFullYear();
if (now.getMonth() === 0){
var qtrToday = qtr[0];
}
else{
var qtrToday = qtr[(Math.floor((now.getMonth()) / 3))];
}
var logo = '/pentaho/api/repos/%3Ahome%3AEISv4%3APM%3ADQ%20Dashboards%3AECLIP%3Aimg%3Alogo.png/content';
toDataURL(logo, function(dataUrl) {
//console.log('RESULT:', dataUrl);
headerIcon = dataUrl;
});
var breadcrumbs = document.getElementById('breadcrumbs').innerHTML;
breadcrumbs = breadcrumbs.replace(/\n|<.*?>/g,'');
var row1 = '';
var row2 = '';
chartsToCanvas(document.querySelector('#row1')).then(function(row){row1 = row;
chartsToCanvas(document.querySelector('#row2')).then(function(row){row2 = row;
chartsToCanvas(document.querySelector('.container')).then(function(dashboard){
//Used to format the output of the pdf document
var docDefinition = {
pageSize: 'A4',
pageOrientation: 'landscape',
pageMargins: [50,20,50,50],
content: [
{image: headerIcon, fit: [50,50], width: 110, alignment: 'center', margin: [0,10,0,0]},
{text: 'Republic of the Philippines', fontSize: 9, alignment: 'center'},
{text: 'Sample',bold: 'true', fontSize: 12, alignment: 'center'},
{text: 'Sample Address', fontSize: 9, alignment: 'center'},
{text: 'https://www.dilg.gov.ph', fontSize: 9, alignment: 'center'},
{
text: 'Data Quality Dashboard',
fontSize: 12,
alignment: 'center',
bold: true,
margin: [0,10,0,0]
},
{
text: '(as of ' + qtrToday + ' Quarter of FY ' + now.getFullYear() + ')',
alignment: 'center',
fontSize: 8,
margin: [0,0,0,10]
},
{
image: row2,
alignment: 'center',
width: rptWidth,
maxHeight: rptHeight
}
],
footer: function(currentPage, pageCount) {
return {
margin: [100,2,100,2],
alignment: 'center',
fontSize: 9,
columns: [
{
text: 'Printed by: ' + name + ' | ' + today,
alignment: 'left'
},
{
text: ' SYSTEM | ' + currentPage.toString() + ' of ' + pageCount,
alignment: 'right'
}
]
};
}
};
//create the pdf file
pdfMake.createPdf(docDefinition).open();
});
});
});
});
Can someone help me. how to create a filename when I'm downloading a PDf file. What happens on me, its creating a random filename for my PDF. I want to set a specific filename('Sample Name') if I download it.
Please Check my script where can I possible put the filename. Thank you so much
Related
I am using PDFmake in my django project to generate pdf files. I want to download multiple files using one button clicked. That's why I planned to use jsZIP to download all the file in a zip format.
function downloadAllPayslip(){
var employeeIdLst = getSelectedPayslipEmployeeIds();
$.ajax({
type: 'GET',
url: '{% url "salary:ajax-download-all-payslip" %}',
data: {
'month': dateVar.getMonth()+1, // number
'year': dateVar.getFullYear(),
'employee_id_lst': JSON.stringify(employeeIdLst),
},
dataType: 'json',
success: function (data) {
var lastDay = new Date(dateVar.getFullYear(), dateVar.getMonth() + 1, 0);
var lastDayStr = lastDay.toString("MM/dd/yyyy");
var lastDayStrSplit = lastDayStr.split("/");
var monthName = months[parseInt(lastDayStrSplit[0]) - 1];
var monthNameS = monthName.slice(0, 3);
var year = lastDayStrSplit[2];
var day = lastDayStrSplit[1];
var zip = new JSZip();
var bufferPDFList = [];
var docDefinitionArr = [];
var docDefinitionBufferArr = [];
var content;
var dataPDF;
var nameArr = [];
for (var i = 0; i < data.length; i++) {
// Employee info
var dailyStartTime = moment(data[i].daily_start_time, 'HH:mm:ss').format('h:mm A');
var dailyExitTime = moment(data[i].daily_exit_time, 'HH:mm:ss').format('h:mm A');
var employeeId = data[i].e_id;
var employeeName = data[i].name;
nameArr.push(employeeName);
var employeeType = data[i].type;
var employeeDesignation = data[i].designation;
var employeeDepartment = data[i].department;
var employeeJoinDate = data[i].join_date;
var weekends = data[i].weekends;
var shift = dailyStartTime + ' - ' + dailyExitTime;
var breakDuration = data[i].break_duration;
var leaveBalanceDict = data[i].leave_balance_dict;
var leaveDataDict = []
for (var leaveType in leaveBalanceDict) {
var leaveDict = leaveBalanceDict[leaveType];
var total = leaveDict.total;
var taken = leaveDict.taken;
var accrued = leaveDict.accrued;
var remained = accrued - taken;
leaveDataDict.push({
'Leave Types': leaveType,
'Leave Entitled(days)': total,
'Leave Taken(days)': taken,
'Leave Accrued(days)': accrued,
'Leave Remained(days)': remained
})
}
// Salary details
if (data[i].is_overtime) {
var overtimeAddition = data[i].overtime_addition + ' (+' + formatHHMM(data[i].overtime_hour) + ')';
}
else {
var overtimeAddition = 'N/A';
}
var basicPay = data[i].basic_salary;
var overtimePay = overtimeAddition;
var lessWorkDeduction = data[i].less_work_deduction + "(" + formatHHMM(data[i].work_hour_deficit) + ")"
var unpaidLeaveDeduction = data[i].unpaid_leave_deduction + "(" + data[i].unpaid_leave_count + "days)"
var additionalPay = data[i].salary_addition;
var totalPay = data[i].total_salary;
var taxDeduction = data[i].tax_deduction+ "(" + data[i].percent_tax + "%)";
var netSalary = data[i].net_salary;
var comment = data[i].comment;
var companyName = '{{ company_name }}'
// Generate pdf
var docDefinition = {
footer: function(currentPage, pageCount) {
return {
columns: [
{
text: currentPage.toString() + ' of ' + pageCount, alignment: 'center'
}
]
};
},
pageSize: 'A4',
pageMargins: [40, 80, 40, 60],
content: [
{ text: companyName, style: 'header', alignment: 'center' },
{ lineHeight: 2, text: 'Pay Slip', fontSize: 15, alignment: 'center' },
{ lineHeight: 2, text: 'Pay Period: 01 ' + monthNameS + ' ' + year + ' - ' + day + ' ' + monthNameS + ' ' + year , fontSize: 12, alignment: 'center', bold: true },
{ text: 'Employee Information', style: 'subheader'},
{
columns: [
{
width: 120,
fontSize: 10,
text: 'Employee Name\n' +
'Employee ID\n' +
'Employee Type\n'+
'Designation'
},
{
width: 155,
fontSize: 10,
text: ': ' + employeeName + '\n' +
': ' + employeeId + '\n' +
': ' + employeeType + '\n' +
': ' + employeeDesignation + '\n'
},
{
width: 120,
fontSize: 10,
text: 'Department\n' +
'Join Date\n' +
'Weekends\n' +
'Shift'
},
{
width: 155,
fontSize: 10,
text: ': ' + employeeDepartment + '\n' +
': ' + employeeJoinDate + '\n' +
': ' + weekends + '\n' +
': ' + shift + '\n' +
' (Break: ' + breakDuration + 'min)'
}
]
},
{ text: 'Leave Information', style: 'subheader'},
{
columns: [
{ width: 20, text: '' },
table(leaveDataDict, ['Leave Types', 'Leave Entitled(days)', 'Leave Taken(days)', 'Leave Accrued(days)', 'Leave Remained(days)']),
]
},
{ text: 'Salary Information', style: 'subheader'},
{
style: 'table',
table: {
body: [
['Basic', 'Overtime', 'Additional', 'Unpaid Leave Deduction', 'Less Work Deduction', 'Total Pay', 'Tax Deduction', 'Net pay'],
[basicPay, overtimePay, additionalPay, unpaidLeaveDeduction, lessWorkDeduction, totalPay, taxDeduction, netSalary]
]
}
},
],
styles: {
header: {
fontSize: 18,
bold: true,
margin: [0, 0, 0, 10]
},
subheader: {
fontSize: 15,
bold: true,
margin: [0, 10, 0, 5]
},
tableHeader: {
bold: true,
fontSize: 13,
color: 'black'
},
table: {
fontSize: 9,
margin: [0, 5, 0, 15]
},
},
}
pdfFilename = 'Payslip-' + employeeName + '-' + monthNameS + year + '.pdf'
// pdfMake.createPdf(docDefinition).download('Payslip-' + employeeName + '-' + monthNameS + year, window);
pdfMake.createPdf(docDefinition).getBase64(function(data) {
zip.file(pdfFilename, data);
// var content = zip.generate();
// location.href="data:application/zip;base64,"+content;
});
}
console.log(zip);
var content = zip.generate();
location.href="data:application/zip;base64,"+content;
}
});
}
this is my code. I am looping over all the data to generate multiple pdf. Then passing the pdfs to jsZIP. but all the time zip file is returning empty.
Is this the right way to download multiple pdf in jsZIP?
Hello I'm having a problem with my code in Highcharts I already declared my series but it only shows 1 set of chart. All data were set on var dataStr, on how the data that being put, I use push on every data that is being passed. So I think the problem is the with my push?
var dataStr = [
{name: 'JOB-182', problemReportCount: 0, totalCost: 50000, lostHour: 0, lostValue: 0},
{name: 'JOB-185', problemReportCount: 0, totalCost: 3432.65, lostHour: 0, lostValue: 0},
{name: 'JOB-188', problemReportCount: 4, totalCost: 5000, lostHour: 0, lostValue: 0},
{name: 'JOB-189', problemReportCount: 0, totalCost: 1000, lostHour: 0, lostValue: 0}
];
var jRefs = [];
var prJRefs = [];
var prLostVals = [];
var prLostHours = [];
var totCosts = [];
for (var i = 0; i < dataStr.length; i++) {
var jName = '' + dataStr[i].name;
if (jName != '') {
jRefs.push(jName);
var prCount = dataStr[i].problemReportCount;
if (prCount > 0) {
prJRefs.push(jName);
prLostVals.push(dataStr[i].lostValue);
prLostHours.push(dataStr[i].lostHour);
totCosts.push(dataStr[i].totalCost);
}
}
}
var genGraph = function() {
$("#backButton").hide();
$('#prGraph4').highcharts({
chart: {
type: 'column',
plotBackgroundColor: '#F7F7F7'
},
title: {
text: 'Problem Report'
},
subtitle: {
text: 'Estimated Lost Values'
},
xAxis: {
alternateGridColor: '#fff',
categories: prJRefs
},
yAxis: {
min: 0,
title: {
text: 'Amount'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold'
}
}
},
plotOptions: {
column: {
stacking: 'normal',
}
},
tooltip: {
shared: true,
formatter: function() {
var s = '<b>' + this.x + '</b>';
$.each(this.points, function() {
var lostValue = this.y;
s += '<br/><span style=" + dbl + "color:' + this.series.color + ';" + dbl + ">\u25CF</span> ' + this.series.name + ': <b>£</b> ' + lostValue.toFixed(2);
});
return s;
}
},
series:[{
name: 'Total Costs',
data: totCosts,
color: '#2ecc71',
stack: 'total'
}, {
name: 'Estimated Lost Materials Value',
data: prLostVals,
color: '#e74c3c',
stack: 'lost'
}, {
name: 'Estimated Lost Hours Price',
data: prLostHours,
color: '#e67e22',
stack: 'lost'
}]
});
};
Any help would be so much appreciated. Thanks!
You have only one visible column because only one set of data fulfills this condition:
if (prCount > 0) {
prJRefs.push(jName);
prLostVals.push(dataStr[i].lostValue);
prLostHours.push(dataStr[i].lostHour);
totCosts.push(dataStr[i].totalCost);
}
In addition, all values from series: Estimated Lost Materials Value and Estimated Lost Hours Price are 0.
Live demo: http://jsfiddle.net/BlackLabel/vu9ahfk5/
Using pdfmake.js to generate pdf in javascript. But it generates a blank document if the content is too large. Used the html2canvas to create the canvas and created the pdf using this. How can resolve this issue??
self.exportAsCanvas = function (contentObject, fileName, heading) {
var useWidth = $(contentObject)[0].offsetWidth;
var useHeight = $(contentObject)[0].offsetHeight;
//var graphContent = angular.element(contentObject).find('.graph-content');
html2canvas(contentObject, {
onrendered: function (canvas) {
document.body.appendChild(canvas);
var data = canvas.toDataURL();
var docDefinition = {
header: { text: heading, style: 'header' },
footer: {
columns: [
{ text: 'Copyright © 2015 H&R Block. All Rights Reserved.', alignment: 'center',fontSize: 11 }
]
},
pageOrientation: self.pageOrientation,
content: [{
image: data,
fit: [1000, 1100]
//width: 500,
//height:1100
}],
styles: {
header: {
fontSize: 14,
bold: true,
alignment: 'center',
margin: [0, 10, 0, 10]
}
}
};
pdfMake.createPdf(docDefinition).download(fileName + ".pdf");
},
width: useWidth,
height: useHeight
});
};
You should try implementing a page break:
var docDefinition = {
header: { text: heading, style: 'header' },
footer: {
columns: [
{ text: 'Copyright © 2015 H&R Block. All Rights Reserved.', alignment: 'center',fontSize: 11 }
]
},
pageOrientation: self.pageOrientation,
content: [{
image: data,
fit: [1000, 1100],
pageBreak: 'after', //PAGE BREAK
//width: 500,
//height:1100
}],
styles: {
header: {
fontSize: 14,
bold: true,
alignment: 'center',
margin: [0, 10, 0, 10]
}
}
};
https://developers.google.com/chart/interactive/docs/gallery/linechart
Hello, guys, I would like to know that is there a way to change the color of the line when it is moving down. I have googled but I was not able to find anything.
like e.g the line graph is moving upwards it's ok as soon as the graph line tilts downward than that downward should only be red. If after that it moves upward then the upward line should not be red.
Here is a screenshot of what I'm trying to obtain:
http://imgur.com/a/GuWDx
If anybody knows this please help me
Here is my code of what am I doing right now:
function draw_chart(chart_data, id, action)
{
var url = base_url + "controller/function/" + id ;
statData = getAjax(url, '', false, 'json');
minimum = '';
maximum = '';
upside = '';
if (statData.min) {
minimum = statData.min;
}
if (statData.max) {
maximum = statData.max;
}
if (statData.upside == '1') {
upside = -1;
}
value = $("#value_" + id).val();
var name = $('#name_' + id).val();
var names = [];
if (value == 2) {
var names = name.split('/');
} else {
names[0] = name;
}
title = $("#name_" + id).val();
google.load('visualization', '1.1', {packages: ['line', 'corechart']});
format = $("#format-select_" + id + " option:selected").val();
if (statData.row[0].type == 'currency') {
format = '$#';
}
var options = {
title: title,
width: 820,
height: 500,
titlePosition: 'none',
legend: 'none',
lineWidth: 3,
annotation: {
0: { style: "line"},
1: { style: "line"}
},
series: {0: { style: "area"} , 1: {type: "area"}},
animation: {duration: 1000, easing: 'in'},
strictFirstColumnType: true,
fontColor: "#333333",
fontSize: "12px",
colors: ["#5AA023", "#3F5F9F" , ""],
pointSize: 6,
fontSize: 11,
enableEvents: true,
forceIFrame: false,
tooltip: {showColorCode: false, },
vAxis: {
gridlines:{color: "#E6E6E6"},
textStyle:{color: "#666666"},
baselineColor: "#CACACA",
format: format,
viewWindow:{
min: minimum,
max: maximum
},
direction: upside,
},
hAxis: {gridlines:{color: "#E6E6E6" , count:chart_data.length},
baselineColor: "#CACACA",
textStyle:{color: "#666666"},
format: "MMM dd yyyy",
textPosition: "out",
slantedText: true,
},
chartArea: {height: 420, width: 750, top: 14, left: 45, right: 0}
};
if (action && action == "update") {
//alert(action);
}
else {
var chart_div = document.getElementById('chart'+id);
var chart_div1 = document.getElementById('chart1'+id);
var chart = new google.visualization.LineChart(chart_div);
google.visualization.events.addListener(chart, 'select', clickHandler);
data = new google.visualization.DataTable();
data.addColumn('string', 'Season Start Date');
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn('number', names[0].trim());
if (value == 2) {
data.addColumn('number', names[1].trim());
for (i = 0; i < chart_data.length; i++)
data.insertRows(0, [[new Date(chart_data[i].date), parseInt(chart_data[i].val), parseInt(chart_data[i].val1)]]);
}
else {
for (i = 0; i < chart_data.length; i++) {
if (!chart_data[i].quarter) {
date = chart_data[i].date.split('-');
month = getMonthName(date[1]);
day = date[2];
year = date[0];
data.insertRows(0, [[month+' '+day+' '+year , '.' , parseInt(chart_data[i].val) ]]);
} else {
data.insertRows(0, [[chart_data[i].quarter , '.' , parseInt(chart_data[i].val) ]]);
}
}
}
}
}
if (statData.row[0].type == 'currency') {
var formatter = new google.visualization.NumberFormat({prefix: '$'});
formatter.format(data, 1);
}
var dataView = new google.visualization.DataView(data);
dataView.setColumns([
// reference existing columns by index
0, 1,
// add function for line color
{
calc: function(data, row) {
console.log("ok world!");
var colorDown = '#0000FF';
var colorUp = 'green';
if ((row === 0) && (data.getValue(row, 1) < data.getValue(row + 1, 1))) {
return colorDown;
} else if ((row > 0) && (data.getValue(row - 1, 1) < data.getValue(row, 1))) {
return colorDown;
}
return colorUp;
},
type: 'string',
role: 'style'
}
]);
chart.draw(dataView, options);
use a DataView and setColumns to provide a function that determines line direction
and returns the appropriate line color
see following working snippet...
google.charts.load('current', {
callback: drawLineColors,
packages: ['corechart']
});
function drawLineColors() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Y');
data.addRows([
[0, 2000],
[3, 1700],
[6, 1400],
[9, 2500],
[12, 3000],
[15, 4700],
[18, 2200],
[21, 1500],
[24, 1200],
[27, 1800],
[30, 2600],
[33, 2800],
[36, 3000],
[39, 2300],
[42, 2000],
[45, 4000]
]);
var options = {
curveType: 'function',
height: 200,
legend: {
position: 'top'
}
};
var dataView = new google.visualization.DataView(data);
dataView.setColumns([
// reference existing columns by index
0, 1,
// add function for line color
{
calc: function(data, row) {
var colorDown = '#0000FF';
var colorUp = '#FF0000';
if ((row === 0) && (data.getValue(row, 1) < data.getValue(row + 1, 1))) {
return colorDown;
} else if ((row > 0) && (data.getValue(row - 1, 1) < data.getValue(row, 1))) {
return colorDown;
}
return colorUp;
},
type: 'string',
role: 'style'
}
]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(dataView, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
Is it possible, in Javascript, to run a function in background ?
I am generating a pdf with pdfmake tool in an angularJS app, but the pdf generation is quite long (3-4 seconds) and during this time, the ui freeze completely.
I would like to run a background task and force the pdf download without freezing the user ui, is it possible ?
Here how I am running pdfmake (pdfmake and _ are custom factories):
'use strict';
angular.module('App')
.service('CatalogPdfService', ['pdfmake', '_', '$q', '$filter',
function (pdfmake, _, $q, $filter) {
var $translate = $filter('translate');
var listDate = new Date();
return {
download: download
};
function download(data) {
listDate = _.first(data).publishedOn;
console.log('start download');
var deferred = $q.defer();
var filename = $translate('APP.EXPORT.pdf.catalog.title', {date: $filter('amDateFormat')(listDate, 'DDMMYYYY')}) + '.pdf';
create(data).download(filename, function () {
console.log('end download');
deferred.resolve();
});
return deferred.promise;
}
function create(data) {
// group data by category
var dataByCategory = _.groupBy(data, function (d) {
return d.category;
});
// group categories data by subcategory
_.forEach(dataByCategory, function (d, i) {
dataByCategory[i] = _.groupBy(d, function (d) {
return d.subcategory;
});
});
var content = {
table: {
headerRows: 1,
widths: ['*', 20, 10, 20, 20, 20, 20, 40, 20, 30],
body: [
[
{text: $translate('APP.EXPORT.pdf.catalog.header.article') , style: 'headings', alignment: 'left'},
{text: $translate('APP.EXPORT.pdf.catalog.header.mine') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.rank') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.origin') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.transporter') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.culture') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.label') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.unit') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.packing') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.price') , style: 'headings'}
]
]
},
layout: {
hLineWidth: function (i) {
return (i == 0) ? 0 : 1;
},
vLineWidth: function (i) {
return 0;
},
hLineColor: function (i, node) {
return '#ccc';
}
}
};
_.forEach(dataByCategory, function (data, category) {
content.table.body = content.table.body.concat(renderCategory(category, data));
});
var dd = {};
dd.content = renderHeader().concat(content);
dd.header = function (currentPage, pageCount) {
return {
text: $translate('APP.EXPORT.pdf.catalog.pagecount', {start: currentPage.toString(), end: pageCount.toString()}),
alignment: 'right',
color: '#666',
margin: [0, 20, 40, 0]
};
};
dd.styles = {
title: {
fontSize: 15,
bold: true
},
headings: {
italics: true,
alignment: 'center'
},
flag: {
alignment: 'center',
italics: true,
color: '#666'
},
category: {
bold: true,
fontSize: 12,
margin: [0, 10, 0, 0] // Left, Top, Right, Bottom
},
subcategory: {
bold: true,
fontSize: 10,
margin: [0, 7, 0, 5] // Left, Top, Right, Bottom
}
};
dd.defaultStyle = {
fontSize: 8
};
return pdfmake.createPdf(dd);
}
function renderHeader() {
return [
{image: logo(), height:40, width: 86},
{
margin: [0, 10, 0, 20],
table: {
widths: [100, 100, 100, '*'],
body: [
[
{text: $translate('APP.COMMON.address', {char: '\n'})},
{text: '\n' + $translate('APP.COMMON.phone')},
{text: '\n' + $translate('APP.COMMON.fax')},
{text: '\n' + $translate('APP.EXPORT.pdf.catalog.listno', {date: $filter('amDateFormat')(listDate, 'DD/MM/YYYY')}) , alignment: 'right'}
]
]
},
layout: {
hLineWidth: function (i) {
return (i == 0) ? 0 : 1;
},
vLineWidth: function (i) {
return 0;
}
}
}];
}
function renderCategory(name, data) {
var category = [
[
{text: name, style: 'category', colspan: 10},
'', '', '', '', '', '', '', '', ''
]
];
_.forEach(data, function (data, name) {
category = category.concat(renderSubcategory(name, data));
});
return category;
}
function renderSubcategory(name, data) {
var subcategory = [
[
{text: name, style: 'subcategory', colspan: 10},
'', '', '', '', '', '', '', '', ''
]
];
_.forEach(data, function (product) {
subcategory.push(renderProduct(product));
});
return subcategory;
}
function renderProduct(product) {
return [
product.name,
{
text: (product.isInPrivateList ? 'Oui' : ''),
style: 'flag'
},
{
text: (null === product.rank ? '' : String(product.rank)),
style: 'flag'
},
{
text: (product.origin || ''),
style: 'flag'
},
{
text: (product.transporter || ''),
style: 'flag'
},
{
text: (product.label || ''),
style: 'flag'
},
{
text: (product.culture || ''),
style: 'flag'
},
{
text: product.unit,
margin: [0, 0, 5, 0],
italics: true,
alignment: 'right'
},
{
text: (product.quantity || '1'),
italics: true,
fillColor: '#eee',
alignment: 'center'
},
{
text: product.unitPrice,
margin: [0, 0, 5, 0],
italics: true,
fillColor: '#eee',
alignment: 'right'
}
];
}
function logo() {
return 'data:image/jpeg;base64,blabla bigbase64 string'
}
}]);
You could use a Web Worker to generate the PDF. But you should be aware of some restrictions when using them. Here is a good reference.
I created a factory in Angular for doing work on a worker thread. Something like this:
/*
Here's an example on how to get this sack of moldering spuds to do something:
var myWorker = new MyWorker({ fn: function() {
this.onmessage = function(args) {
setTimeout(function() {
this.postMessage('Got args: ' + args.data);
}, 20000);
};
} });
myWorker.do('Test').then(function(message) {
alert(message);
});
*/
'use strict';
angular.module('myApp')
.factory('MyWorker', function($q) {
var _worker;
var MyWorker = function(settings) {
_init(settings);
};
MyWorker.prototype.do = function(args) {
var deferred = $q.defer();
_worker.onmessage = function(message) {
deferred.resolve(message.data);
};
//Fire up the blades.
if (args)
_worker.postMessage(args);
else
_worker.postMessage();
return deferred.promise;
};
MyWorker.prototype.destroy = function() {
_worker.terminate();
};
function _init(settings) {
if (settings.script)
_worker = new Worker(settings.script);
//Need to make this IE (10+) friendly.
else if (settings.fn) {
var blobUrl = window.URL.createObjectURL(new Blob(
['(', settings.fn.toString(), ')()'],
{ type: 'application/javascript' }
));
_worker = new Worker(blobUrl);
}
};
return MyWorker;
});
This will give you a rough idea about how it can be implemented in AngularJS, but seriously take it with a grain of salt.