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

table center alignment #72

Open
dave-watts opened this issue Aug 17, 2014 · 17 comments
Open

table center alignment #72

dave-watts opened this issue Aug 17, 2014 · 17 comments

Comments

@dave-watts
Copy link

IS it possible to align the table in the center of the page? All the

alignment: 'center',

code I add does nothing

@bpampuch
Copy link
Owner

wow, this made me think; I was about to answer: sure it is ;) but had troubles to provide an example

it looks like alignment is not taken into consideration in this case, I'll have to take a look at it

currently you can use the following workaround:

{
    columns: [
        { width: '*', text: '' },
        {
            width: 'auto',
                table: {
                        body: [
                                ['Column 1', 'Column 2', 'Column 3'],
                                ['One value goes here', 'Another one here', 'OK?']
                        ]
                }
        },
        { width: '*', text: '' },
    ]
},

@dave-watts
Copy link
Author

nice, that does the job!

@dave-watts
Copy link
Author

it would be nice to have a table sizing that sizes all other the cells according to the largest content

i.e. cellSize = max(cellSize)

or failing that, get text metrics to calculate cell size yourself

@bpampuch
Copy link
Owner

you mean equal widths for all columns based on largest width?

@priyankaparihar
Copy link

Hi,
The above trick for getting the table center aligned dint work for me :( .

Could you please help me out fast.

Thanks.

@bpampuch
Copy link
Owner

what do you mean it didn't work? include your doc definition object, otherwise it's difficult to figure out what kind of problem you have

@priyankaparihar
Copy link

@bpampuch .. Thank you for the quick response. The table is not getting center aligned if my no. of columns are less. This trick which you have given dint work.

{
columns: [
{ width: '', text: '' },
{
width: 'auto',
table: {
body: [
['Column 1', 'Column 2', 'Column 3'],
['One value goes here', 'Another one here', 'OK?']
]
}
},
{ width: '
', text: '' },
]
},

The pdf is working perfectly for the table which has more number of columns.

This is how I am getting the table :

capture

@bpampuch
Copy link
Owner

the trick is to have first and last column start-sized; change
width: ''
to
width: '*'

@priyankaparihar
Copy link

That is what I am doing exactly. The exact code is :

content : [
{ width: '*', text: '' },
{
width: 'auto',
fontSize : 8,
table : {
headerRows : 1,
body : otArr
}

    },
    { width: '*', text: '' },
    ]

@bpampuch
Copy link
Owner

still can't reproduce this, could you include a complete example? thx

@priyankaparihar
Copy link

@bpampuch : Here is the actual code written for the same. I have removed the actual image data, due to the identity issue.

var pageOrientation;
if (ori)
pageOrientation = 'portrait';
else
pageOrientation = 'landscape';

var docDefinition = {

    pageSize : 'A4',
    pageOrientation : pageOrientation,
    // [left, top, right, bottom] or [horizontal, vertical] or just a number
    // for equal margins
    pageMargins : [ 20, 50, 20, 45 ],
    footer : function(currentPage, pageCount) {
        return {
            margin : [ 20, 0, 20,20],
            fontSize : 8,
            columns : [
                    {
                        text : '' + datetime,
                        alignment : 'left',
                        bold : true
                    },
                    {
                        text : 'Page ' + currentPage.toString() + ' of '
                                + pageCount,
                        alignment : 'center',
                        bold : true
                    }, {
                        text : username,
                        alignment : 'right',
                        bold : true
                    } ]
        };
    },
    header : {
        margin : [20,10,20,0],
        columns : [
                {
                    image : 'data:image/png;==',
                    height : 30,
                    width : 70,
                    alignment : 'center'
                }, {
                    text : title.toUpperCase() + '\n' + date.toUpperCase(),
                    margin : [ -70, 0, 0, 0 ],
                    alignment : 'center',
                    fontSize : 10,
                    bold : true
                } ]
    },
    content : [ {
        widths : [ '*', 'auto', 100, '*' ],
        alignment : 'center',
        table : {
            headerRows : 1,
            alignment : 'center',
            body : otArr
        },
        fontSize : 8
    } ]
};

@bpampuch bpampuch added the bug label Oct 20, 2014
@priyankaparihar
Copy link

Hi @bpampuch .. Did you work on this issue. I have tried but could not get it worked.

@liborm85 liborm85 added the table label Feb 5, 2017
blandine added a commit to blandine/pdfmake that referenced this issue Jun 22, 2017
@blushi
Copy link

blushi commented Jul 28, 2017

#1087

@touchaqb
Copy link
Contributor

touchaqb commented Sep 6, 2017

I have been struggling with this problem and I have found that, although it may be possible to workaround in some cases, there is a single point that makes a definite solution really hard to find.

@bpampuch workaround works for that specific case and @blushi pull request helps a lot. But both leave one problem unsolved.

The column approach causes pdfmake to crash when the table to be center aligned has any column width defined in %:

{
    content: [
        {
            columns: [
                { width: '*', text: '' },
                {
                    width: 'auto',
                    table: {
                            body: [
                                    ['Column 1', 'Column 2', 'Column 3'],
                                    ['One value goes here', 'Another one here', 'OK?']
                            ],
                            widths: ['auto', '80%', 'auto']
                    }
                },
                { width: '*', text: '' }
            ]
        }
    ]
}

@blushi pull request cannot properly centralize a table inside another table cell which is definied in %:

{
  "content": [
    {
      "table": {
        "body": [ [
          {

      "table": {
        "body": [
          ["1", "2", "3" ]
        ],
        "widths": [
          "auto", "auto", "auto"
        ]
      }, "tableAlignment": "center"

         }
        ]],"widths": ["80%"]}, "tableAlignment": "center"
    }
  ]
}

Both fail for the same reason: there is currently no treatment for column widths in % when it first attempts to calculate the column widths in points when tryLayoutDocument() does docStructure = this.docMeasure.measureDocument(docStructure);

Then it reaches measureTable(), which calls
var measures = ColumnCalculator.measureMinMax(node.table.widths);

measureMinMax() happens to be:

//TODO: refactor and reuse in measureTable
function measureMinMax(columns) {
	var result = {min: 0, max: 0};

	var maxStar = {min: 0, max: 0};
	var starCount = 0;

	for (var i = 0, l = columns.length; i < l; i++) {
		var c = columns[i];

		if (isStarColumn(c)) {
			maxStar.min = Math.max(maxStar.min, c._minWidth);
			maxStar.max = Math.max(maxStar.max, c._maxWidth);
			starCount++;
		} else if (isAutoColumn(c)) {
			result.min += c._minWidth;
			result.max += c._maxWidth;
		} else {  // touchaqb: isn't a % column width test missing here?
			result.min += ((c.width !== undefined && c.width) || c._minWidth);
			result.max += ((c.width !== undefined && c.width) || c._maxWidth);
		}
	}

	if (starCount) {
		result.min += starCount * maxStar.min;
		result.max += starCount * maxStar.max;
	}

	return result;
}

The line I commented I belive that a test for % width column is missing.

In the column workaround, the last else is reached with c.width = "80%", variable result therefore becomes:

result.min = "41.320312580%41.3203125"
result.max = "107.67187580%51.029296875"

... which are not valid numbers.

It seems not to be an easy task to implement the missing else clause (test for % width) as the code at this point have no clue about the available width there is left for it to use so it could calculate the effective width in points. The availableWidth is only calculated later in the processing phase by buildColumnWidths() called either from layoutBuilder.js (for comuns) or tableProcessor.js (for tables).

As far as I understand the problem, it seems to me that some refactoring is needed in order to measureTable() be able to receive the available width and properly measure the table. Does anyone have another idea?

One thing I could no realize yet is how the star widths are being properly solved, perhaps % widths could work in a similar manner.

@ontheterra
Copy link

Just use '*' instead of int in widths option, and you are good to go

liborm85 added a commit that referenced this issue Dec 30, 2020
@HeCorr
Copy link

HeCorr commented Mar 17, 2021

here we are... 7 years later and the issue is still present. 🙃

btw thank you very much, @bpampuch. your workaround worked (although if the content width is big enough it gets off-center to the right for some reason...)

@Varkoff
Copy link

Varkoff commented May 15, 2023

Thank you for this workaround ;)

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

9 participants