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]
}
}
};
Related
I am using the pdfmake library in a project, but its execution takes about 2-3 min.
Is the library normally slow or do I need to improve the performance of my code ?
It is also possible that performances are impacted by the code being executed in chunks, but I am not sure I understand the role of chunks and why they are used.
var docDefinition = {
footer: function (currentPage, pageCount) {
return {
margin: [40, 0, 0, 0],
columns: [{
fontSize: 8,
text: [
{
text: 'Page ' + currentPage.toString() + ' / ' + pageCount,
}
],
}]
};
},
content: contentAry,
styles: {
clsHeader: {
fontSize: 12,
bold: true
},
clsSubHeader: {
fontSize: 10
},
clsTblHeader: {
fillColor: '#9e9e9e',
color: '#FFFFFF'
},
clsImage: {
margin: [0, 40, 0, 0]
},
clsTable: {
fontSize: 8
}
},
defaultStyle: {
alignment: 'justify'
}
}
var doc = printer.createPdfKitDocument(docDefinition);
var chunks = [];
doc.on('readable', function () {
var chunk;
while ((chunk = doc.read(9007199254740991)) !== null) {
chunks.push(chunk);
}
});
Is it possible to modify the chunk size?
I need to apply labels on top of chart following the columns just like the image (the numbers aside the text 'Resultado mês'):
Image of the desired result
Some help please?
The page is bellow (the labels need to go before the legends).
I've provided a HTML/CSS solution temporarily in the page bellow , but I'm waiting for the real solution:
http://www.pdagencia.com.br/porto/pages/10.3%20-%20consultar-dados-bancarios-01_v2.html#tab3
window.onload = function() {
var ctx = document.getElementById('ps-chart').getContext('2d');
var data = {
labels: ["Jan/18", "Fev/18", "Mar/18", "Abr/18", "Mai/18", "Jun/18", "Jul/18", "Ago/18", "Set/18", "Out/18", "Nov/18", "Dez/18"],
datasets: [{
label: "Entradas",
data: [650, 590, 800, 810, 560, 550, 400, 800, 810, 560, 550, 400],
backgroundColor: '#33bfff'
},
{
label: "Saídas",
data: [-280, -480, -400, -190, -860, -270, -900, -400, -190, -860, -270, -900],
backgroundColor: '#E75A5B'
}
]
}
var myChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
responsive: false,
plugins: {
datalabels: {
formatter: function(value, context) {
return context.dataset.data[context.dataIndex].toLocaleString('pt-BR', {
style: 'currency',
currency: 'BRL'
});
}
}
},
legend: {
display: true,
},
tooltips: {
"enabled": false
},
scales: {
yAxes: [{
display: false,
ticks: {
display: false
}
}],
xAxes: [{
stacked: true,
barPercentage: 1.2,
gridLines: {
display: false
}
}]
}
}
});
}
<script src="https://github.com/chartjs/Chart.js/releases/download/v2.7.2/Chart.bundle.min.js"></script>
<script src="https://github.com/chartjs/chartjs-plugin-datalabels/releases/download/v0.3.0/chartjs-plugin-datalabels.min.js"></script>
<canvas id="ps-chart" style="width:100%"></canvas>
I am new to the chart js and javascript.
As I have faced the same problem, I wanted to display the sum of two values into the label,
I got some solution for the same as below.
Maybe it can help you.
Check it out:
http://www.chartjs.org/samples/latest/tooltips/callbacks.html
tooltips: {
mode: 'index',
callbacks: {
// Use the footer callback to display the sum of the items
showing in the tooltip
footer: function(tooltipItems, data) {
var sum = 0;
tooltipItems.forEach(function(tooltipItem) {
sum += data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
});
return 'Sum: ' + sum;
},
},
footerFontStyle: 'normal'
},
hover: {
mode: 'index',
intersect: true
},
I have managed to edit the pdf export but i need to align only one column
i searched in thes datatables forum and in the pdfmake documentation but i haven't find how to do it. Please help!
My customize function is the following
customize: function ( doc ) {
doc['footer']=(function(page, pages) {
return {
columns: [
'*',
{
alignment: 'right',
text: [
{ text: page.toString(), italics: true },
' de ',
{ text: pages.toString(), italics: true }
]
}
],
margin: [30, 0]
}
});
var d = new Date();
var fecha = d.toLocaleDateString('es-CL');
var hora = d.toLocaleTimeString('es-CL');
doc.content.splice( 1, 0, {
columns: [
{
alignment: 'left',
text: 'Comercial del Real \n Ramón Freire 471, Rancagua \n\n',
bold: true,
},
{
alignment: 'right',
text: 'Fecha: '+fecha+'\nHora: '+hora+' ',
margin: [ 0, 0, 40, 0 ],
bold: true
}
]
});
}
I found a solution on my own
var rowCount = document.getElementById("tableID").rows.length;
for (i = 0; i < rowCount+1; i++) {
doc.content[1].table.body[i][5].alignment = 'right';
};
I really don't know if it is the best solution but it works for me
I am trying to increase the header size on a pdf using pdfmake.
Currently am able to get a header on both the left and right of the page, which is what I want, but when the height passes 26, the image disappears because there is a limited amount of space for the header.
The margin can be decreased to increase the size but i want the
margin to remain.
I've searched pdfMake github for similar issues with no success.
If you need to test anything, try the code I have so far on
pdfmake playground
Keep in mind you will need to copy and paste all this code on the "playground" to make it work.
var dd = {
pageSize: 'LEGAL',
pageOrientation: 'landscape',
header: {
margin: 8,
columns: [{
table: {
widths: ['50%', '50%'],
body: [
[{
image: 'sampleImage.jpg',
width: 80,
height: 26,
}, {
image: 'sampleImage.jpg',
width: 80,
height: 26,
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'
]
}
You need to add a pageMargins and adjust the second parameter (top margin) to your total header size. You can try values until you get all header content visible.
For example:
In this case, I use 80 (pageMargin: [40,80,40,60]) to get the image with height 60
var dd = {
pageSize: 'LEGAL',
pageOrientation: 'landscape',
pageMargins: [40, 80, 40, 60],
header: {
margin: 8,
columns: [
{
table: {
widths: [ '50%','50%'],
body: [
[
{ image: 'sampleImage.jpg',
width: 80, height: 60,
},
{ image: 'sampleImage.jpg',
width: 80, height: 60,
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'
]
}
The accepted answer for this is a good one, but I thought since I found one I believe might work better for others, especially if header content length may vary, I would share.
Tables in pdfmake have a nifty feature where the header row(s) are repeated on each page the table spans. So, you can create a table that wraps your entire document, and add as many header rows as you would like, and they will be sticky throughout all pages. Here's an example doc def.
var docDefinition = {
pageSize : 'LETTER',
pageMargins : [25, 25, 25, 35],
defaultStyle : {
fontSize : 12,
columnGap : 20
},
// Page Layout
content : {
// This table will contain ALL content
table : {
// Defining the top 2 rows as the "sticky" header rows
headerRows: 2,
// One column, full width
widths: ['*'],
body: [
// Header Row One
// An array with just one "cell"
[
// Just because I only have one cell, doesn't mean I can't have
// multiple columns!
{
columns : [
{
width : '*',
text : 'Delivery Company, Inc.',
fontSize : 12,
bold : true
},
{
width : '*',
text : [
{ text: 'Delivery Slip\n', fontSize: 12 },
{ text: 'Date ', bold: true },
'2/16/2015 ',
{ text: 'Arrived ', bold: true },
'11:05 AM ',
{ text: 'Left ', bold: true },
'11:21 AM'
],
fontSize : 10,
alignment : 'right'
}
]
}
],
// Second Header Row
[
{
columns: [
{
width: 'auto',
margin: [0,0,10,0],
text: [
{ text: 'CUSTOMER\n', fontSize: 8, bold: true, color: '#bbbbbb' },
{ text: 'John Doe', fontSize: 12 }
]
},
{
width: 'auto',
margin: [0,0,10,0],
text: [
{ text: 'INVOICE #\n', fontSize: 8, bold: true, color: '#bbbbbb' },
{ text: '123456', fontSize: 12 }
]
}
]
}
],
// Now you can break your content out into the remaining rows.
// Or you could have one row with one cell that contains
// all of your content
// Content Row(s)
[{
fontSize: 10,
stack: [
// Content
{ text:'this is content', pageBreak: 'after' },
{ text:'this is more content', pageBreak: 'after' },
{ text:'this is third page content' }
]
}],
[{
fontSize: 10,
stack: [
// Content
{ text:'this is content', pageBreak: 'after' },
{ text:'this is more content', pageBreak: 'after' },
{ text:'this is third page content' }
]
}]
]
},
// Table Styles
layout: {
hLineWidth: function(i, node) { return (i === 1 || i === 2) ? 1 : 0; },
vLineWidth: function(i, node) { return 0; },
hLineColor: function(i, node) { return (i === 1 || i === 2) ? '#eeeeee' : 'white'; },
vLineColor: function(i, node) { return 'white' },
paddingBottom: function(i, node) {
switch (i) {
case 0:
return 5;
case 1:
return 2;
default:
return 0;
}
},
paddingTop: function(i, node) {
switch (i) {
case 0:
return 0;
case 1:
return 2;
default:
return 10;
}
}
}
},
// Page Footer
footer : function(currentPage, pageCount) {
return {
alignment : 'center',
text : currentPage.toString() + ' of ' + pageCount,
fontSize : 8
}
},
};
I'm working with pdfmake to generate pdf with javascript. I'm trying to build a table dynamically but not works ,this my attempt
$.ajax({
type: "POST",
url: myURL,
success:function(data){
/* data has a format like :
*[{"peaje":"Peaje 1","ruta":"Ruta 1","fechaCruce":"2014-10-18","hora":"15:42","valor":"5000"},{"peaje":"Peaje 1","ruta":"Ruta 1","fechaCruce":"2014-10-18","hora":"14:21","valor":"7000"},{"peaje":"Peaje 1","ruta":"Ruta 1","fechaCruce":"2014-09-19","hora":"11:58","valor":"17000"}]
*/
var peajes = JSON.parse( data );
var body = [];
var titulos = new Array( 'PEAJE', 'RUTA', 'FECHA CRUCE', 'HORA', 'VALOR' );
body.push( titulos );
for (key in peajes)
{
if (peajes.hasOwnProperty(key))
{
var peaje = peajes[key];
var fila = new Array();
fila.push( peaje.peaje.toString() );
fila.push( peaje.ruta.toString() );
fila.push( peaje.fechaCruce.toString() );
fila.push( peaje.hora.toString() );
fila.push( peaje.valor.toString() );
body.push(fila);
}
}
console.log( body );
var docDefinition = {
content: [
{
table: {
headerRows: 1,
widths: [ '*', 'auto', 100, '*' ],
body: body
}
}]
};//end docDefinition
pdfMake.createPdf(docDefinition).open();
}//end success
});
This is the example of the library http://pdfmake.org/#/gettingstarted
I don't know what am I doing wrong?
For multiple rows, here is an example
var externalDataRetrievedFromServer = [
{ name: 'Bartek', age: 34 },
{ name: 'John', age: 27 },
{ name: 'Elizabeth', age: 30 },
];
function buildTableBody(data, columns) {
var body = [];
body.push(columns);
data.forEach(function(row) {
var dataRow = [];
columns.forEach(function(column) {
dataRow.push(row[column].toString());
})
body.push(dataRow);
});
return body;
}
function table(data, columns) {
return {
table: {
headerRows: 1,
body: buildTableBody(data, columns)
}
};
}
var dd = {
content: [
{ text: 'Dynamic parts', style: 'header' },
table(externalDataRetrievedFromServer, ['name', 'age'])
]
}
You should make array of column names & values:
var column = [];
column.push({ text: 'A', style: 'tableHeader'});
column.push({ text: 'B', style: 'tableHeader'});
var value = [];
value.push({ text: 'Asda', style: 'tableHeader'});
value.push({ text: 'Bsa', style: 'tableHeader'});
When you make a table, you should do like this.
table: {
headerRows: 1,
body: [
column, value
]
}
For headers and rows are dynamic , we can define headers in an array and also rows and then join them into one following this example ( copy and paste into http://pdfmake.org/playground.html to see it in action ) :
// playground requires you to assign document definition to a variable called dd
var headers = {
fila_0:{
col_1:{ text: 'Faltas', style: 'tableHeader',rowSpan: 2, alignment: 'center',margin: [0, 8, 0, 0] },
col_2:{ text: 'Fecha', style: 'tableHeader',rowSpan: 2, alignment: 'center',margin: [0, 8, 0, 0] },
col_3:{ text: 'Descripción', style: 'tableHeader',rowSpan: 2, alignment: 'center',margin: [0, 8, 0, 0] },
col_4:{ text: 'Cita con acudientes', style: 'tableHeader',colSpan: 2, alignment: 'center' }
},
fila_1:{
col_1:{ text: 'Header 1', style: 'tableHeader', alignment: 'center' },
col_2:{ text: 'Header 2', style: 'tableHeader', alignment: 'center' },
col_3:{ text: 'Header 3', style: 'tableHeader', alignment: 'center' },
col_4:{ text: 'Citación', style: 'tableHeader', alignment: 'center' },
col_5:{ text: 'Cumplimiento', style: 'tableHeader', alignment: 'center'}
}
}
var rows = {
a: {
peaje: '1',
ruta: '2',
fechaCruce: '3',
hora: '4',
valor: '5'
},
b: {
peaje: '1',
ruta: '2',
fechaCruce: '3',
hora: '4',
valor: '5'
}
}
var body = [];
for (var key in headers){
if (headers.hasOwnProperty(key)){
var header = headers[key];
var row = new Array();
row.push( header.col_1 );
row.push( header.col_2 );
row.push( header.col_3 );
row.push( header.col_4 );
row.push( header.col_5 );
body.push(row);
}
}
for (var key in rows)
{
if (rows.hasOwnProperty(key))
{
var data = rows[key];
var row = new Array();
row.push( data.peaje.toString() );
row.push( data.ruta.toString() );
row.push( data.fechaCruce.toString() );
row.push( data.hora.toString() );
row.push( data.valor.toString() );
body.push(row);
}
}
var dd = {
pageMargins: [40,155,40,55],
pageOrientation: 'landscape',
header: function() {
return {
margin: 40,
columns: [
{
},
{ text:['Resumen disciplinario'],
alignment: 'left',bold:true,margin:[-405,80,0,0],fontSize: 24}
]
}
},
footer: function(currentPage, pageCount) {
return { text:'Pagina '+ currentPage.toString() + ' de ' + pageCount, alignment: 'center',margin:[0,30,0,0] };
},
content: [
//{ text: 'Tables', style: 'header' },
'\nEl estudiante AGRESOTH NEGRETE JORYETH TATIANA - 901 - TARDE tiene 1 actas, con 1 faltas acomuladas y a manera de resumen descritas a continuación:\n\n',
//{ text: 'A simple table (no headers, no width specified, no spans, no styling)', style: 'sta' },
//'The following table has nothing more than a body array',
{
style: 'tableExample',
table: {
widths: [ '*', '*', '*', '*', '*' ],
headerRows: 2,
// keepWithHeaderRows: 1,
body: body
}
}],
styles: {
header: {
fontSize: 28,
bold: true
},
subheader: {
fontSize: 15,
bold: true
},
quote: {
italics: true
},
small: {
fontSize: 8
},
sta: {
fontSize: 11,
bold: false,
alignment: 'justify'
}
}
}