make pageMargins dynamic
Books are binded and therefore have different page margins for odd and even pages, so that the text on the page appears to be in the middle and not squeezed into the books fold. I searched the documentation/issues and tested it, the pageMargins seem to be static.
Yes, would be very helpful to be dynamic. I'd like to generate a different report footer just for the last page. It would nice to have pageMargins accept a function just like header/footer that has two parameters of currentPage and pageCount.
+1
+1
+1
+1
+1
+1
+1
+1
+1
i solve my problem with different header heights changing follow functions in documentContext.js.
function DocumentContext(pageSize, pageMargins) {
this.pages = [];
this.pageMargins = pageMargins;
this.pageMarginsFkt = null;
if (typeof this.pageMargins === 'function'){
this.pageMarginsFkt = this.pageMargins;
}
if (this.pageMarginsFkt){
this.pageMargins = this.pageMarginsFkt(1);
}
this.x =this. pageMargins.left;
this.availableWidth = pageSize.width - this.pageMargins.left - this.pageMargins.right;
this.availableHeight = 0;
this.page = -1;
this.snapshots = [];
this.endingCell = null;
this.tracker = new TraversalTracker();
this.addPage(pageSize);
this.hasBackground = false;
}
DocumentContext.prototype.initializePage = function () {
this.y = this.getCurrentPage().pageMargins.top;
this.availableHeight = this.getCurrentPage().pageSize.height - this.getCurrentPage().pageMargins.top - this.getCurrentPage().pageMargins.bottom;
this.pageSnapshot().availableWidth = this.getCurrentPage().pageSize.width - this.getCurrentPage().pageMargins.left - this.getCurrentPage().pageMargins.right;
};
DocumentContext.prototype.addPage = function (pageSize) {
var page = {items: [], pageSize: pageSize};
this.pages.push(page);
this.page = this.pages.length - 1;
if (typeof this.pageMargins === 'function'){
this.pageMarginsFkt = this.pageMargins;
}
if (this.pageMarginsFkt){
this.pageMargins = this.pagerMarginsFkt(this.pages.length);
}
page.pageMargins = Object.assign( {} , this.pageMargins );
this.initializePage();
this.tracker.emit('pageAdded');
return page;
};
DocumentContext.prototype.getCurrentPosition = function () {
var pageSize = this.getCurrentPage().pageSize;
var innerHeight = pageSize.height - this.getCurrentPage().pageMargins.top - this.getCurrentPage().pageMargins.bottom;
var innerWidth = pageSize.width - this.getCurrentPage().pageMargins.left - this.getCurrentPage().pageMargins.right;
return {
pageMargins: this.getCurrentPage().pageMargins,
pageNumber: this.page + 1,
pageOrientation: pageSize.orientation,
pageInnerHeight: innerHeight,
pageInnerWidth: innerWidth,
left: this.x,
top: this.y,
verticalRatio: ((this.y - this.getCurrentPage().pageMargins.top) / innerHeight),
horizontalRatio: ((this.x - this.getCurrentPage().pageMargins.left) / innerWidth)
};
};
LayoutBuilder.prototype.addDynamicRepeatable = function (nodeGetter, sizeFunction) {
var pages = this.writer.context().pages;
for (var pageIndex = 0, l = pages.length; pageIndex < l; pageIndex++) {
this.writer.context().page = pageIndex;
var node = nodeGetter(pageIndex + 1, l, this.writer.context().pages[pageIndex].pageSize);
if (node) {
var sizes = sizeFunction(this.writer.context().getCurrentPage().pageSize, this.writer.context().getCurrentPage().pageMargins);
this.writer.beginUnbreakableBlock(sizes.width, sizes.height);
node = this.docPreprocessor.preprocessDocument(node);
this.processNode(this.docMeasure.measureDocument(node));
this.writer.commitUnbreakableBlock(sizes.x, sizes.y);
}
}
};
so i can set a function in docDefinition for pageMargins like:
var docDefinition = {
......,
pageMargins : function(cp) {
if ( cp === 1 ){
return {left:30,top:150, right:30,bottom:60};
} else {
return {left:30,top:50, right:30,bottom:60};
}
},
.......
}
I save the pageMargins in the page object whenever a new one is created and if the parameters are needed I get them from the currentPage. I have not found any negative side effects for me and I hope to have listed all my changes (I got them from a printout). Maybe that solves the problem of one or the other. Happy Easter :-)
sorry for my english, isn't my favorit language.
@icke792 Can you create a pull-request for it?
This was really useful for me. Please add it to the project. There seems to be a small fix to make it work with dynamic horizontal margins:
DocumentContext.prototype.initializePage = function () {
this.y = this.getCurrentPage().pageMargins.top;
this.x = this.getCurrentPage().pageMargins.left;
this.availableHeight = this.getCurrentPage().pageSize.height - this.getCurrentPage().pageMargins.top - this.getCurrentPage().pageMargins.bottom;
this.availableWidth = this.getCurrentPage().pageSize.width - this.getCurrentPage().pageMargins.left - this.getCurrentPage().pageMargins.right;
};
+1
+1
+1
This was really useful for me. Please add it to the project. There seems to be a small fix to make it work with dynamic horizontal margins:
DocumentContext.prototype.initializePage = function () { this.y = this.getCurrentPage().pageMargins.top; this.x = this.getCurrentPage().pageMargins.left; this.availableHeight = this.getCurrentPage().pageSize.height - this.getCurrentPage().pageMargins.top - this.getCurrentPage().pageMargins.bottom; this.availableWidth = this.getCurrentPage().pageSize.width - this.getCurrentPage().pageMargins.left - this.getCurrentPage().pageMargins.right; };
@hobbsi Did you just edit the source, build it and roll your own version?
@hobbsi Did you just edit the source, build it and roll your own version?
I used it while doing some experimentation on a personal project. And yes, that's what did. I believe you could also fork the project and do your modifications... I didn't.
This was really useful for me. Please add it to the project. There seems to be a small fix to make it work with dynamic horizontal margins:
DocumentContext.prototype.initializePage = function () { this.y = this.getCurrentPage().pageMargins.top; this.x = this.getCurrentPage().pageMargins.left; this.availableHeight = this.getCurrentPage().pageSize.height - this.getCurrentPage().pageMargins.top - this.getCurrentPage().pageMargins.bottom; this.availableWidth = this.getCurrentPage().pageSize.width - this.getCurrentPage().pageMargins.left - this.getCurrentPage().pageMargins.right; };
@hobbsi How would you apply this, once implemented, in the document definition?
@liborm85 any chance the approach of @icke792 with the fix of @hobbsi gets merged if I would create a PR?
Also, I have the need for a dynamic margin based on a dynamic header (see #2238) which is even a step further than what we have here. Any chance a solution taking dynamic headers into account gets merged in the end?
A work around can be setting the content margins to negative value (only top margin) and passing an empty string to the header function.
For example:
pageMargins : [30, 140, 30, 30]
Then on the page where you don't need header, after passed the empty string, you can sett:
content.margins: [0, -110, 0, 0 ]
A work around can be setting the content margins to negative value (only top margin) and passing an empty string to the header function.
For example:
pageMargins : [30, 140, 30, 30]
Then on the page where you don't need header, after passed the empty string, you can sett:
content.margins: [0, -110, 0, 0 ]
Will it work for footers?
If anyone wants to create bigger footer on a specific page you can just put your items in the footer with page condition and give it margin: [0,-100,0,0] decrease the negative value to fit your content.
Note: this is just a workaround and if you have more text in your page body using negative margin might make footer and body overlap.
If you have dynamic content - ie tables that span over multiple pages it can be difficult to determine where each new page header footer dimensions should be used from just the page number
I added the following code to icke792's (thanks) above
function DocumentContext(pageSize, pageMargins) {
var _this;
_this = _EventEmitter.call(this) || this;
_this.pages = [];
_this.pageMargins = pageMargins;
_this.pageMarginsFkt = null;
_this.sections = 1;
if (typeof _this.pageMargins === "function") {
_this.pageMarginsFkt = _this.pageMargins;
}
if (_this.pageMarginsFkt) {
_this.pageMargins = _this.pageMarginsFkt(1, _this.sections);
}
_this.x = _this.pageMargins.left;
_this.availableWidth = pageSize.width - _this.pageMargins.left - _this.pageMargins.right;
_this.availableHeight = 0;
_this.page = -1;
_this.snapshots = [];
_this.endingCell = null;
_this.backgroundLength = [];
_this.addPage(pageSize);
return _this;
}
//after var _proto = DocumentContext.prototype;
_proto.addSection = function addSection () {
this.sections++;
}
//in addPage
if (this.pageMarginsFkt) {
this.pageMargins = this.pageMarginsFkt(this.pages.length, this.sections);
}
//at the end of function - _proto.processNode = function processNode(node) {
if (node.sectionEnd === true) {
_this2.writer.context().addSection();
}
//You can the add .sectionEnd = true; as a property of any section where you want to change the header/footer
{
text: "this is the end",
sectionEnd : true
}
//and when that changes the callback to pageMargins will contain the section count
docDefinition.pageMargins = function (pages, sectionCount) {
if (sectionCount % 2 === 0) {
return { left: 20, top: 50, right: 20, bottom: 50};
} else {
return { left: 20, top: 10, right: 20, bottom: 10 };
}
}
Books are binded and therefore have different page margins for odd and even pages, so that the text on the page appears to be in the middle and not squeezed into the books fold. I searched the documentation/issues and tested it, the pageMargins seem to be static.
Books are binded and therefore have different page margins for odd and even pages, so that the text on the page appears to be in the middle and not squeezed into the books fold. I searched the documentation/issues and tested it, the pageMargins seem to be static.
Did you solve the issue?
I solved this issue, contact me if someone need help ........removed....
I'm looking for this as well. We have a report with dynamic headers, and I need to set the page margins according to the header size. Currently, because of the limitation, I have to truncate the header in order for it to fit. But when the header is shorter, there is a gap between it and the content of the page.
I'm not sure how this can be solved since the header needs to know the left and right margins in order to render, but the content needs to know the top margins, depending on the header height, in order to render; it's the chicken and the egg problem.
Edit: this could be solved with the possibility to have a margin value of "auto", which would default to 0 for left and right, to the header height for top, and the footer height for bottom.
Has anyone found a solution for this?
Can I determine It's the last page of the pdf and assign different page margin for it?
+1