Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make pageMargins dynamic #368

Open
peetzweg opened this issue Jul 31, 2015 · 29 comments
Open

make pageMargins dynamic #368

peetzweg opened this issue Jul 31, 2015 · 29 comments

Comments

@peetzweg
Copy link

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.

@nthnmldr
Copy link

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.

@Nor145
Copy link

Nor145 commented Jun 7, 2016

+1

3 similar comments
@oscardz10
Copy link

+1

@max-yu
Copy link

max-yu commented Jul 27, 2016

+1

@difnicolas
Copy link

+1

@aba-koepke
Copy link

+1

@kngchn
Copy link

kngchn commented Dec 6, 2017

+1

1 similar comment
@cbernecker
Copy link

+1

@steffenstolze
Copy link

+1

1 similar comment
@tkbrady
Copy link

tkbrady commented Mar 13, 2018

+1

@icke792
Copy link

icke792 commented Apr 1, 2018

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.

@renarsvilnis
Copy link

@icke792 Can you create a pull-request for it?

@hobbsi
Copy link

hobbsi commented May 8, 2018

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;
};

@kunalwatkar
Copy link

+1

2 similar comments
@vitalii4reva
Copy link

+1

@ricardocorassa
Copy link

+1

liborm85 added a commit that referenced this issue Apr 29, 2020
@liborm85 liborm85 mentioned this issue Apr 29, 2020
5 tasks
@naknode
Copy link

naknode commented Sep 17, 2020

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
Copy link

hobbsi commented Sep 18, 2020

@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.

@hielfx
Copy link

hielfx commented Sep 22, 2020

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?

@robstoll
Copy link

@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?

@gine
Copy link

gine commented Aug 3, 2021

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 ]

@qasimmehdi
Copy link

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?

@qasimmehdi
Copy link

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.

@tedbakers
Copy link

tedbakers commented Dec 1, 2021

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 };
            }             
           
        }

@bug-and-debug
Copy link

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?

@bug-and-debug
Copy link

I solved this issue, contact me if someone need help
zhengwei@byartifact.com

@yanickrochon
Copy link

yanickrochon commented Jun 1, 2022

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.

@albertoLGDev
Copy link

Has anyone found a solution for this?

@carltin0315
Copy link

Can I determine It's the last page of the pdf and assign different page margin for it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests