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

Set custom size and margin for each page #325

Open
diegito opened this issue Jun 16, 2015 · 9 comments
Open

Set custom size and margin for each page #325

diegito opened this issue Jun 16, 2015 · 9 comments

Comments

@diegito
Copy link

diegito commented Jun 16, 2015

I need to set my own margins and dimensions for each page. I managed to do that for the whole document but not for a single page.

Could you point out where I need to change the code? Kind of the same way we change the page orientation, but for the size.

Or is there any other way to do it? I'm developing a front-end app so cannot use nodejs.

Thanks

@diegito
Copy link
Author

diegito commented Jun 17, 2015

I believe I can add something here
https://github.com/bpampuch/pdfmake/blob/master/build/pdfmake.js#L15090
inside DocumentContext.prototype.moveToNextPage

I'll try to play around some more...

@diegito
Copy link
Author

diegito commented Jun 17, 2015

To allow for custom dimensions, I've included these parameters to be added at the beginning of the document definition.

if (!docDefinition.pageSize && docDefinition.pageCustomWidth && docDefinition.pageCustomHeight) {
  pageSize = { width: docDefinition.pageCustomWidth, height: docDefinition.pageCustomHeight }
} else 
  pageSize = pageSize2widthAndHeight(docDefinition.pageSize || 'a4');

If pageSize is not defined but pageCustomWidth and pageCustomHeight are, the document's pages will have those dimensions set.

This works for all the pages though. Looking for a solution that customizes the size of every single page in the document.

@diegito
Copy link
Author

diegito commented Jun 19, 2015

Would it be possible to have some leads on the pieces of code that I can edit to obtain this result? I tried several solutions but till now they all failed..

If you could give me some insight on what section of the code deals with the new pages and how the size is passed I can try to hack a bit :)

I'm using pdfmake for a project and I need to have it done... thanks for any help!

@jthoenes
Copy link
Contributor

The trouble is, there is not a single piece of code you need to touch. It's a bit spread through the code.

The page is created internally here: https://github.com/bpampuch/pdfmake/blob/master/src/documentContext.js#L194
And for the pdfkit output, here: https://github.com/bpampuch/pdfmake/blob/master/src/printer.js#L118 and here https://github.com/bpampuch/pdfmake/blob/master/src/printer.js#L183

But because we have tables and column contexts spanning across pages, it's not that simple. Have a look at initializePage in DocumentContext - it's also re-using the page, when another column already has been there.

That's everything from the top of my mind.

@diegito
Copy link
Author

diegito commented Jun 19, 2015

Thanks, I'll try something and let you know how it goes...

@Raven24
Copy link

Raven24 commented Sep 2, 2015

I'd be interested in that kind of functionality, too.
In my usecase it would even be sufficient if I could just print multiple document definitions into the same pdf as seperate pages - so in my understanding of how the layout works, there would be no need to handle flowing content onto different-sized pages.
I would just like to specify pageSize per document definition and get a pdf with every document on a new page with the specified attributes.
... don't know if that would reduce the amount of work necessary to get it implemented.

@pianetarosso
Copy link

Hi, I need this feature to show some parts of a document in A3.
There are any updates?

@pianetarosso
Copy link

Hi, I've set up a simple way to create a document in multiple page sizes.
Two notes about it:

  • It will mess up your page nubers. I solved it generating the doc two times, and overriding the footer function
  • The change of page size will be considered as page break

I've worked directly on sources for version 1.4.

First, when generating contents, I added the property pageSize to identify the page size of the element, like 'a4' or 'a3'.

Then file src/browser-extensions/pdfMake.js line ~32 is changed as following:

Document.prototype._createDoc = function (options, callback) {
	options = options || {};
	if (this.tableLayouts) {
		options.tableLayouts = this.tableLayouts;
	}
	var printer = new PdfPrinter(this.fonts);
	require('fs').bindFS(this.vfs); // bind virtual file system to file system

	let contestBackup = this.docDefinition.content.slice(); // backup of contents of the document
	let originalFooter = this.docDefinition.footer; // backup of the footer function 

        // generates an array from document's content, grouped by page size
	let contentsArray = this.docDefinition.content.reduce((acc, c) => {
		if (acc.length === 0 || (c.pageSize && acc[acc.length - 1].size !== c.pageSize)) {
			acc.push({size: c.pageSize, content: []});
		}
		acc[acc.length - 1].content.push(c);
		return acc;
	}, []);

	var doc = undefined; // doc generated by pdfKit
	var total = 0; //total number of pages of the document
        
	contentsArray.map(c => { // we must do this first cycle to obtain the page numbers
		this.docDefinition.pageSize = c.size; // forcing the size of the document to the subset of the content
		this.docDefinition.content = c.content; // forcing the subset of the content
		doc = printer.createPdfKitDocument(this.docDefinition, options, doc); // this method has been changed to get in input also a pre-existing doc instead of generating a new one every time
		let range = doc.bufferedPageRange();
		c.start = total; // we keep track of the start point of pages of this subset of the document
		total = range.start + range.count; // updating the max number of pages
	});
	
	var doc = undefined; // resetting the doc
	contentsArray.map(c => { // second cycle, with correct page numbers
		this.docDefinition.pageSize = c.size; // forcing the size of the document to the subset of the content
		this.docDefinition.content = c.content; // forcing the subset of the content
		this.docDefinition.footer = (currentPage, pageCount) => { //override of footer function
			return originalFooter(currentPage + c.start, total);
		};
		doc = printer.createPdfKitDocument(this.docDefinition, options, doc); // this method has been changed to get in input also a pre-existing doc instead of generating a new one every time
	});

	// restoring old values, otherwise subsequentials doc generation will be messed up
	this.docDefinition.content = contestBackup;
	this.docDefinition.footer = originalFooter;
	this.docDefinition.pageSize = undefined;
        .....

And also the file /src/printer.js at line ~85

// added the capability to get an original doc in input
PdfPrinter.prototype.createPdfKitDocument = function (docDefinition, options, doc = undefined) {
	options = options || {};

	var pageSize = fixPageSize(docDefinition.pageSize, docDefinition.pageOrientation);
	var compressPdf = isBoolean(docDefinition.compress) ? docDefinition.compress : true;
	var bufferPages = options.bufferPages || false;

	if (doc) { // if we passed a doc, we set it and update the pageSize
		this.pdfKitDoc = doc;
		this.pdfKitDoc.options.size = [pageSize.width, pageSize.height];
	}
	else { // original flow
		this.pdfKitDoc = PdfKitEngine.createPdfDocument({
			size: [pageSize.width, pageSize.height],
			bufferPages: bufferPages,
			autoFirstPage: false,
			compress: compressPdf
		});
		setMetadata(docDefinition, this.pdfKitDoc);
		this.fontProvider = new FontProvider(this.fontDescriptors, this.pdfKitDoc);
         }
         ...

Currently this solution seems to work well also with tables and images.
Hope that someone else find this useful.

Best Regards

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

Hi.. All.. need a Help. i want to have pageMargins dynamically to be set for footer.. if there is more than one page i need pageMargins for the first page to be as [40,15,40,60] and for the another page it should be like [40,15,40,250] as in the footer i need to mention some text and images.. as i tried here but couldn't found the solution or else i am missing out something.. so if anyone know the solution.. for this kind of thing.. I would be grateful

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

6 participants