tush
tush

Reputation: 71

vertically align tables when html page is printed

I have two tables of size 7cm×15cm that I want to export to a pdf file, of A4 portrait paper size, using the browser's "Save to PDF" option in its print tool.

Ideally, I want to vertically center the two tables on the A4 paper. But if that is not possible to do, I would like them to be positioned on the same place in the page.

At the moment, for some reason, the two tables are not positioned at the exact place on the page, as I want them to (see in the image below).

The html code is the following:

<body>
<!-- 1st table: -->
<table>
<tr> <td>content of the first table</td>
<!-- some other tr's and td's -->
</tr>
</table>
<!-- 2nd table: -->
<table>
<tr> <td>content of the second table</td>
<!-- some other tr's and td's -->
</tr>
</table>

</body>

together with the following css rules:

table {width:7cm; height:15cm; border: 1px solid;
  page-break-after: always;
  margin: auto;
  }
@media print {
  @page { size: A4 portrait; }
  }

The page-break-after: always; rule instructs the browser to insert a page break after the table;

The margin: auto; rule horizontally aligns the tables on the canvas.

I need to print the two tables on the same paper, in a two-sided printing, so that the tables are printed just behind each other.

What I have at the moment:

illustration

Any help would be much appreciated!

Upvotes: 7

Views: 2308

Answers (3)

John Collins
John Collins

Reputation: 2951

Here's perhaps one possible solution. I've used your exact provided HTML and CSS, with the simple addition of a transform trick which ensures perfect centering of the objects:

<html><head>
    <title>Two Centered Tables</title>
    <style>
        table {
                width: 7cm;
                height: 15cm;
                border: 1px solid;
                page-break-after: always;
                margin: 50%;
                transform: translate(-50%, -50%);
                text-align: center;
        }

        @media print {
                @page {
                        size: A4 portrait;
                }

        }
    </style>
</head>
<body>

        <!-- 1st table: -->
        <table>
            <tbody>
                <tr>
                    <td>content of the first table</td>
                    <!-- some other tr's and td's -->
                </tr>
            </tbody>
        </table>
        <!-- 2nd table: -->
        <table>
            <tbody>
                <tr>
                    <td>content of the second table</td>
                    <!-- some other tr's and td's -->
                </tr>
            </tbody>
        </table>


</body></html>

Shown through Chrome DevTools

shown through chrome dev tools

Simply using ctrl/cmd-P to open print dialogue.

Here, I've selected 2 pages per sheet just for illustrative purposes to show the perfect alignment. When you do your printing, of course this would be set to one page per sheet (the default). Margins set to none (although auto will work fine too); and background graphics and header not selected. printing from browser

<!DOCTYPE html>
<html>
<head>
    <title>Two Centered Tables</title>
    <style>
        table {
                width: 7cm;
                height: 15cm;
                border: 1px solid;
                page-break-after: always;
                margin: 50% 50% 50% 50%;
                transform: translate(-50%, -50%);
                text-align: center;
        }

        @media print {
                @page {
                        size: A4 portrait;
                }

        }
    </style>
</head>
<body>
    <div style="display: grid;">
        <!-- 1st table: -->
        <table>
            <tbody>
                <tr>
                    <td>content of the first table</td>
                    <!-- some other tr's and td's -->
                </tr>
            </tbody>
        </table>
        <!-- 2nd table: -->
        <table>
            <tbody>
                <tr>
                    <td>content of the second table</td>
                    <!-- some other tr's and td's -->
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

Try running this snippet, go to full screen (after running the snipper → "Full Page" (not "Extend snippet"), then print like this: print ex Again, as sanity check only (showing 2 per page to check for alignment): its aligned

It may be because of the hard-coding in centimeters, that when you ran this code it didn't work for you; and so it does depend on the actual size of your monitor what you get (if you hardcode width and height in units of cm [or pixels?]?). Can anyone shed light on that?

Upvotes: 1

AziMez
AziMez

Reputation: 2072

[Tips]:

@tush, We can do as you mentioned in the comments. Since the height is known AND the container (body) height is known then we can fix them by "manually" positioning it.

Using margin: 6cm auto; . Look at the sample below.

[Result]:

Centred PDF file

[HTML/CSS Code]:

table {width:7cm; height:15cm; border: 1px solid;
  page-break-after: always;
  margin: 6cm auto;
  }
@media print {
  @page { size: A4 portrait; }
  }
<body>
<!-- 1st table: -->
<table>
<tr> <td>content of the first table</td>
<!-- some other tr's and td's -->
</tr>
</table>
<!-- 2nd table: -->
<table>
<tr> <td>content of the second table</td>
<!-- some other tr's and td's -->
</tr>
</table>

</body>

Upvotes: 5

DiaRar
DiaRar

Reputation: 569

So I found the fix without javascript. Change your media for print to this:

@media print {
    body {margin-top:0 !important;}
  @page { size: A4 portrait; }

  }

Edit for centering the tables:
You have to wrap the tables in a div like this:

<body>
    <!-- 1st table: -->
    <div class="page">
    <table>
    <tr> <td>content of the first table</td>
    <!-- some other tr's and td's -->
    </tr>
    </table>
  </div>
    <!-- 2nd table: -->
    <div class="page">

    <table>
    <tr> <td>content of the second table</td>
    <!-- some other tr's and td's -->
    </tr>
    </table>
    </div>
    </body>

Then in the css add this for flex display:

@media print {
    body {margin-top:0 !important;}
    .page{
      height: 100vh;
      width: 100vw;
      display: flex;
      align-items: center;
      justify-content: center;
    }

  @page { 
    size: A4 portrait;
  }
  }

And it should be centered and all now.

Upvotes: 6

Related Questions