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
}
},
};
Related
There are graphics data for which it was necessary to make the appearance of the plate when choosing an item. But the standard function does not support the title of the table in html format, although the title of the chart supports it normally. I did it by adding a new button to the menu, through menuItemDefinitions inside exporting, but how to overwrite its text after selection? It is necessary that, as with the standard output, it was. Changed View data table to Hide data table and vice versa. The code that i have now and the photo as i would like are given below:
var html = '<div style="display: inline-block"></div>';
html += '<div style="display: inline-block; margin-left: 20px; cursor: pointer;" class="description-title" id="">';
html += '<img style="width: 20px;" src="https://img.icons8.com/ios/500/info--v1.png" alt="Info">';
html += '</div>';
new Highcharts.Chart({
chart: {
renderTo: 'chart_1',
type: 'column',
height: 350,
},
title: {
text: html,
useHTML: true,
},
xAxis: {
categories: ['Processing.js', 'Impact.js', 'Other', 'Ease.js', 'Box2D.js', 'WebGL', 'DOM', 'CSS', 'Canvas', 'Javascript']
},
yAxis: {
title: {
text: 'Asked'
}
},
series: [{
name: 'Dev #1',
data: [5, 10, 20, 22, 25, 28, 30, 40, 80, 90],
color: '#FF0000',
states: {
inactive: {
enabled: false
}
}
}, {
name: 'Dev #2',
data: [15, 15, 18, 40, 30, 25, 60, 60, 80, 70],
states: {
inactive: {
enabled: false
}
}
}, {
name: 'Dev #3',
data: [1, 3, 6, 0, 50, 25, 50, 60, 30, 100]
}],
exporting: {
menuItemDefinitions: {
// Custom definition
label: {
onclick: function() {
if (this.dataTableDiv && this.dataTableDiv.style.display !== 'none') {
this.text = "View data table";// Assigned but not displayed in the menu
this.dataTableDiv.style.display = 'none';
this.dataTableDiv.querySelector(".highcharts-table-caption").innerHTML = html;
} else {
this.viewData();
this.text = "Hide data table";// Assigned but not displayed in the menu
this.dataTableDiv.style.display = '';
this.dataTableDiv.querySelector(".highcharts-table-caption").innerHTML = html;
}
},
text:"View data table",
}
},
buttons: {
contextButton: {
menuItems: ["viewFullscreen", "printChart", "separator", "downloadPNG", "downloadJPEG", "downloadPDF", "downloadSVG", "separator", "downloadCSV", "downloadXLS", 'label']
}
}
}
});
.actions, .chart {
margin: 15px auto;
width: 820px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/accessibility.js"></script>
<div id="chart_1" class="chart"></div>
And the solution was easier than I thought. Just instead this.text = "Hide data table"; should have written:
document.getElementsByClassName("highcharts-menu-item")[8].innerHTML = "Hide/View data table";
What solved the problem
It looks like the text inside the button is implemented, it changes the name when you hide the table to show table and vice versa, when you add:
exporting: {
showTable: true,
},
Demo: http://jsfiddle.net/BlackLabel/9musLgp2/
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]
}
}
};
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 have a HighCharts Treemap showing a set of categories containing subcategories. The point of the graph is to show how much of the data is in Category A, and how much of Category A is in Subcategory A1.
I have created this as follows:
http://jsfiddle.net/jbcfk93m/
$(function () {
$('#container').highcharts({
series: [{
colorByPoint: true,
layoutAlgorithm: "stripes",
alternateStartingDirection: true,
allowPointSelect: true,
point: {
events: {
click: function () {
alert(this.name + ": " + this.value);
}
}
},
dataLabels: {
},
type: "treemap",
levels: [{
level: 1,
dataLabels: {
enabled: true,
align: 'right',
rotation: 30,
crop: false,
overflow: 'none',
inside: false,
style: {
fontSize: '15px',
fontWeight: 'bold'
}
}
}, {
level: 2,
dataLabels: {
style: {
}
},
layoutAlgorithm: "stripes",
}],
data: [{
// Add parents without values
id: 'CategoryA',
name: 'Category A'
}, {
id: 'CategoryB',
name: 'Category B',
}, {
// And the children with values
name: 'Subcat A1',
value: 4,
parent: 'CategoryA'
}, {
name: 'Subcat A2',
value: 6,
parent: 'CategoryA'
}, {
name: 'Subcat B1',
value: 6,
parent: 'CategoryB'
}, {
name: 'Subcat B2',
value: 2,
parent: 'CategoryB'
}
]
}],
title: {
text: 'Treemap',
margin: 100
},
xAxis: {
min: 0,
max: 100
}
});
});
I want to get both the X- and Y axes in the graph to show percentages so I can more easily see how much of my data is in a certain category.
Does anyone know how to do this?
I didn't find anything about axis on treemaps and i'm not really sure if showing a percentage on X and Y axis would help you that much, because you basically have to multiply the values on X and Y(eg. if your subcat B1 is from 20% to 100% on X axis and from 60% to 100% on the Y axis then you would have to do (100% - 20%) * (100% - 60%) = 32%).
I did implement however a tooltip formatter that will show you the percentage when you hover over the subcategories.
formatter: function () {
var total = 0;
for (var i = 0; i < this.series.data.length; i++)
{
if (this.series.data[i].node.children.length == 0)
total+=this.series.data[i].node.val;
}
var value;
if (this.point.node.children.length == 0)
{
value = this.point.options.value;
}
else
{
value = this.point.node.childrenTotal;
}
return this.key + " " + (value / total) *100 + " %";
}
Here is the working fiddle http://jsfiddle.net/jbcfk93m/4/
I've been trying to figure out this particular object for quite a while and it's frustrating me endlessly so I was hoping to get it resolved here.
I have an object that looks like this:
options = {
headers: {
rows: [
cols = {
text: "Blah",
span: 12,
color: "#FFF"
}
],
[
cols = {
text: "Blah2",
span: 8,
color: "#FFF"
}
cols = {
text: "Blah2",
span: 4,
color: "#FFF"
}
]
}
}
With the intended result being an object that can be used to populate header rows above a table using a combination of the text, span, and color properties (with a few additions for later) to customize styling it properly.
I'm going for:
var text = options.headers.rows[x].cols[y].text;
Such that a nested loop can generate out the headers. Any help is appreciated!
[See it in action]
var options = {
headers: {
rows: [ // Array
{ // row: 0
cols: [ // Array
{ // col: 0
text: "Blah",
span: 12,
color: "#FFF"
},
{ // col: 1
text: "Blah2",
span: 8,
color: "#FFF"
},
{ // col: 2
text: "Blah2",
span: 4,
color: "#FFF"
}]
},
{ // row: 1
cols: [ // Array
{ // col: 0
text: "Blah",
span: 12,
color: "#FFF"
},
{ // col: 1
text: "Blah2",
span: 4,
color: "#FFF"
}]
}]
}
};