Is there a way to create a table footer in pdfMake? I have a big table that only fits on multiple pages. I want to repeat the table footer on each page.
Seems like it is still not implemented: https://github.com/bpampuch/pdfmake/issues/620
Add this to your document:
footer: {
columns: [
'',
{
alignment: 'right',
text: 'Footer text'
}
],
margin: [10, 0]
}
I finally figured out how to do this.
(1.) Increase your current "headerRows" count by 1.
(2.) Put the footer row between your header row and data rows.
(3.) Set marginTop of footer row to a little less than the height of the page.
(4.) Set marginBottom of footer row to ((marginTop + height of row) * -1).
This pushes the table footer outside the space of the table into the footer space of the page.
Example:
table: { headerRows: 2, widths: [700], body: [
[{ text: 'My Header' }],
[{ marginTop: 480, marginBottom: -490, text: 'My Footer' }], //480 roughly fits Landscape-Letter
[{ text: 'My Data Row 1' }],
[{ text: 'My Data Row 2' }],
// more data rows
[{ text: 'My Data Row N' }]
]}
try this footer
footer: function (currentPage, pageCount) {
return currentPage.toString() + " of " + pageCount;
},
or
footer: {
columns: [
'Report generated on 8/30/2021 6:02:31PM',
{ text: 'Page 1 of 2', alignment: 'right' },
// { text: 'Developed by KRATOS Fitness Software ', alignment: 'left' },
],
},
footer: {
columns: [
'Report generated on 8/30/2021 6:02:31PM',
'Developed by XYZ Fitness Software',
{
alignment: 'right',
text: 'Page 1 of 2'
},
{
alignment: 'right',
text: 'www.xyz.com'
},
],
margin: [60, 10, 60, 10 ]
},
It's work
Related
In this demo from ag-Grid.
Age field is display at the bottom.
How to display Age field at the top?
Thanks!
.
ColumnDefs looks like :
return [
{
headerName: 'Athlete Details',
headerClass: 'participant-group',
children: [
{
field: 'athlete',
colId: 'athlete',
},
...
],
},
{
// how to display this field's harder at top
field: 'age',
colId: 'age',
},
...
];
I am using pdfmake to created pdf which is working fine I have used style to align the text to right which is also works fine but I would like to align one particular column in a table to be right aligned but it couldn't do it if I give the alignment it is taking for the entire table instead of single column can anyone tell me how to align a particular column to right in a table.
var previousbillitems = invoice.Items.map(function (item) {
return [item.Date, item.Description, item.Amount];
});
{
style: 'itemsTable',
table: {
widths: [75, '*', 75],
body: [
[
{ text: $translate.instant('{{"billdate_message" | translate}}'), style: 'itemsTableHeader' },
{ text: $translate.instant('{{"description_message" | translate}}'), style: 'itemsTableHeader' },
{ text: $translate.instant('{{"amount_message" | translate}}'), style: 'itemsTableHeader' },
]
].concat(previousbillitems)
},
},
Style for it:
itemsTable: {
alignment: 'center',
margin: [0, 5, 0, 15]
},
Expected output is like:
By changing the code like this i got the solution to right align the data
var previousbillitems = invoice.Items.map(function (item) {
return [
{text: item.Date, alignment: 'center'},
{text: item.Description, alignment: 'center'},
{text: item.Amount, alignment: 'right'}
];
});
{
style: 'itemsTable',
table: {
widths: [75, '*', 75],
body: [
[
{ text: $translate.instant('{{"billdate_message" | translate}}'), style: 'itemsTableHeader' },
{ text: $translate.instant('{{"description_message" | translate}}'), style: 'itemsTableHeader' },
{ text: $translate.instant('{{"amount_message" | translate}}'), style: 'itemsTableHeader' },
]
].concat(previousbillitems)
},
},
it work for me like this
var previousbillitems = invoice.Items.map(function (item) {
return [
{text: item.Date, style: 'cellCenter'},
{text: item.Description, style: 'cellCenter'},
{text: item.Amount, style: 'cellRight'},
];
});
{
style: 'itemsTable',
table: {
widths: [75, '*', 75],
body: [
[
{ text: $translate.instant('{{"billdate_message" | translate}}'), style: 'itemsTableHeader' },
{ text: $translate.instant('{{"description_message" | translate}}'), style: 'itemsTableHeader' },
{ text: $translate.instant('{{"amount_message" | translate}}'), style: 'itemsTableHeader' },
]
].concat(previousbillitems)
},
},
Styles
styles:{
cellLeft: {
// fontSize: 13,
// fillColor : 'gray',
alignment : 'left'
},
cellCenter: {
//fontSize: 13,
// fillColor : 'gray',
alignment : 'center'
},
cellRight: {
// fontSize: 13,
// fillColor : 'gray',
alignment : 'right'
}
}
I have a Panel where in I wish to add two text fields in 'hbox' layout for every entry in the json data.
For e.g. : Suppose I have a json like this:
{
..
ids : [
{
'name' : 'first name',
'surname' : 'first surname',
},
{
'name' : 'second name',
'surname' : 'second surname'
}
]
}
In this example the panel will consist of two rows of two textfields each with the labels being 'name' and 'surname'
So in the for loop I need to know how to insert the two textfields in 'hbox' layout inside the Panel. Had it been a grid it would be easy to add to the store.
Here's what I have done.
Ext.getCmp('panelid').items.add(Ext.create('Ext.container.Container', {
layout: {
type: 'hbox'
},
defaults: {
bodyPadding: 10,
margin: '10 0 10 10',
height: 100
},
items: [
{
fieldLabel: 'Name',
id: 'idFieldName',
name : 'Data',
margin:'0 10 10 0',
width:225,
labelWidth: 40
},
{
fieldLabel: 'Datatype',
name : 'Type',
id: 'idFielddataType',
margin: '0 10 10 0',
width:225,
labelWidth:55
}
]
}));
EDIT1: Added my progress.
EDIT2: I have found half the solution to the problem. The problem was that I don't need to add to the items but rather I can just add to the panel itself. So this is working :
Ext.getCmp('panelid').add(....)
But now the issue is that in the second iteration of the loop the next hbox formatted text fields come on TOP of the existing ones, i.e., instead of adding a row below this line is adding on top of the panel. Kindly advise how to get rid of this issue.
EDIT 3:
I have found the solution as to why it was adding elements on top of the existing ones. It's because whenever I was adding elements in the loop the id of the added elements was same. So in effect it was replacing the two textfields I had already put in the previous iteration.
So, I have just altered the id name as follows:
id: 'idFieldName' + i
I think you should use the "form" layout instead (or an Ext.form.Panel), and use a Ext.form.FieldContainer to group your 2 text field.
Example :
Ext.create('Ext.form.Panel', {
title: 'FieldContainer Example',
width: 550,
bodyPadding: 10,
items: [
{
xtype: 'fieldcontainer',
fieldLabel: 'first line',
labelWidth: 100,
layout: 'hbox',
items: [{
xtype: 'textfield',
flex: 1
}, {
xtype: 'textfield',
flex: 1
}]
},
{
xtype: 'fieldcontainer',
fieldLabel: 'second line',
labelWidth: 100,
layout: 'hbox',
items: [{
xtype: 'textfield',
flex: 1
}, {
xtype: 'textfield',
flex: 1
}]
}
]
});
If you want to do it dynamically you can do :
Ext.create('Ext.form.Panel', {
title: 'FieldContainer Example',
width: 550,
bodyPadding: 10,
addRow : function(rowLabel) {
this.add({
xtype: 'fieldcontainer',
fieldLabel: rowLabel,
labelWidth: 100,
layout: 'hbox',
items: [{
xtype: 'textfield',
flex: 1
}, {
xtype: 'textfield',
flex: 1
}]
});
}
});
and then in your loop you can use :
myPanel.addRow('test');
You should use different names for each field too, to be able to retrieve the form values later.
name: 'Data' + i
EDIT
Besides, I would use itemId instead of id, as stated here: https://stackoverflow.com/a/18472598/2085604
You can then use Ext.ComponentQuery.query(..) to get components by their itemId:
https://stackoverflow.com/a/24407896/2085604
What version of ExtJS are you using for this example? 3, 4 or 5? I ask this because changes the solution of your problem (more or less) depending on the version.
EDIT
Seems that you found a solution. I don't know if you are doing this in the view, but if that's the case, you should use a controller linked to that particular view. In this way your code will look better, more clear and another important reason, the following versions of ExtJS(5), use this kind of structure.
I have created a jsfiddle over here.
There is a row (no.4) in the the store having empty/null values, but the grid display appears to be collapsed.
code snippet:
function(Grid, Memory) {
var data = [
{ id: 1, name: 'Peter', age:24 },
{ id: 2, name: 'Paul', age: 30 },
{ id: 3, name: 'Mary', age:46 },
{ id: '', name: '', age:'' }
];
var store = new Memory({ data: data });
var options = {
columns: [
/*{ field: 'id', label: 'ID' },*/
{ field: 'name', label: 'Name' },
{ field: 'age', label: 'Age' }
],
store: store
};
new Grid(options, 'gridcontainer');
}
I would like to have blank rows in the grid with the same height as other populated rows.
Is it possible in dGrid?
I believe the reason why blank rows do not have the same height as other rows is that dGrid doesn't actually set a specific height that a row should have. In situations where a cell may need a 2nd row, then the cell would grow in height. If you want a set height, you can add a css attribute to your fiddle that does something like:
#gridcontainer .dgrid-content .dgrid-cell {
height: 24px;
}
I am working on extjs for first time is it possible to have border layout inside card layout.If possible please provide me a sample example.
Coding:
Ext.define('app.view.main'{
extend: 'Ext.panel.Panel',
xtype: 'mainview',
layout: 'border',
border: false,
items:[
{
xtype:'panel',
region:'north',
......
.........
},
{
xtype:'panel',
region:'west',
......
.........
},
{
xtype:'panel',
region:'center',
items: [
{
xtype:'panel',
layout:'card',
items:[{
xtype: 'panel',
region: 'center',
margin: 10,
layout: 'border',
items:[{
xtype:'panel',
region:'center',
......
.........
},
{
xtype:'panel',
region:'south',
......
.........
}]
}]
}
]
}
]
});
In this the items inside card layout is not working if i remove the layout border then the panels are displayed.
It's possible. I've created your basic layout in the fiddle. The general structure seems to be border > card > border. I've added panel titles so that you can get a feel for where each panel is displayed. A couple things to note:
region: 'center' near margin: 10 within the card layout does nothing.
You've nested more than necessary. The center panel can just have card layout directly, rather than having one child panel with the card layout. The power users within the ExtJS forums always suggest flattening the layout as much as possible. I suspect this layout could be simplified more, depending on the needs of your application
Here's what the code looks like:
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
height: 300,
width: 500,
title: 'testing',
layout: 'border',
items: [{
xtype: 'panel',
region: 'north',
title: 'outer north',
height: 60
}, {
xtype: 'panel',
region: 'west',
title: 'outer west',
width: 60
}, {
xtype: 'panel',
region: 'center',
title: 'outer center',
layout: 'card',
items: [{
xtype: 'panel',
title: 'card 1',
layout: 'border',
items: [{
xtype: 'panel',
region: 'center',
title: 'inner center'
}, {
xtype: 'panel',
region: 'south',
title: 'inner south'
}]
}, {
xtype: 'panel',
title: 'card 2'
}]
}]
});