当 HTML 代码转换为 pdf 文件时,Dompdf table 边框问题

Dompdf table border issue when HTML code converted to pdf file

我正在使用 DOMPdf 库将 HTML 代码转换为 PDF。我在 HTML 中设计了 table 当我 运行 浏览器中的文件呈现良好但是当我实际生成 PDF 文件时,一个单元格缺少右侧边框,一个单元格应该不显示边框有边框

预期结果

我得到的实际结果。

这是我的代码

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>PaySlip</title>

    <style>
        .custom-font {
            font-weight: bold;
        }


        table.blueTable {
            border: 1px solid #000000;
            background-color: #ffffff;
            width: 100%;
            text-align: left;
            border-collapse: collapse;
        }

        table.blueTable td,
        table.blueTable th {
            border: 1px solid #020202;
            padding: 3px 2px;
        }

        table.blueTable tbody td {
            font-size: 13px;
        }

        table.blueTable tr:nth-child(even) {
            background: #ffffff;
        }

        table.blueTable thead {
            background: #1c6ea4;
            background: -moz-linear-gradient(top,
                #5592bb 0%,
                #327cad 66%,
                #1c6ea4 100%);
            background: -webkit-linear-gradient(top,
                #5592bb 0%,
                #327cad 66%,
                #1c6ea4 100%);
            background: linear-gradient(to bottom,
                #5592bb 0%,
                #327cad 66%,
                #1c6ea4 100%);
            border-bottom: 2px solid #444444;
        }

        table.blueTable thead th {
            font-size: 15px;
            font-weight: bold;
            color: #ffffff;
            border-left: 2px solid #d0e4f5;
        }

        table.blueTable tfoot td {
            font-size: 14px;
        }

        table.blueTable tfoot .links {
            text-align: right;
        }


    </style>
</head>

<body>
    <table class="blueTable">
        <thead>
            <tr>
                <th colspan="4" style="text-align: center">
                    Payslip for the Month of XYZ - 2019
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="custom-font">Name Of Employee</td>
                <td>Placeholder</td>


                <td class="custom-font">Payable Days</td>
                <td>Placeholder</td>
            </tr>

            <tr>
                <td class="custom-font">Employee Code</td>
                <td>Placeholder</td>


                <td class="custom-font">Paid Days</td>
                <td>Placeholder</td>
            </tr>

            <tr>
                <td class="custom-font">Designation</td>
                <td>Placeholder</td>

                <td class="custom-font">Joining Date</td>
                <td>Placeholder</td>
            </tr>

            <tr>
                <td class="custom-font">PAN No.</td>
                <td>Placeholder</td>

                <td class="custom-font">Date Of Birth</td>
                <td>Placeholder</td>
            </tr>
            <tr>
                <td class="custom-font">Aadhaar No.</td>
                <td>Placeholder</td>

                <td class="custom-font">Bank Name</td>
                <td>Placeholder</td>
            </tr>
            <tr>
                <td class="custom-font">PF No.</td>
                <td>Placeholder</td>

                <td class="custom-font">Bank Account No</td>
                <td>Placeholder</td>
            </tr>
            <tr>
                <td class="custom-font">UAN</td>
                <td>Placeholder</td>

                <td class="custom-font">Location</td>
                <td>Placeholder</td>
            </tr>

            <!-- space -->
            <tr style="border-right:">
                <td style="border-right-style: hidden;">&nbsp;</td>
                <td style="border-right-style: hidden;">&nbsp;</td>
                <td style="border-right-style: hidden;">&nbsp;</td>
                <td>&nbsp;</td>
            </tr>

            <!-- Salary info -->
            <tr style="text-align: center">
                <th>Earnings</th>
                <th>Amount[INR]</th>
                <th>Deductions</th>
                <th>Amount[INR]</th>
            </tr>

            <tr>
                <td class="custom-font">Basic Salary</td>
                <td></td>

                <td class="custom-font">Provident Fund</td>
                <td></td>
            </tr>

            <tr>
                <td class="custom-font">House Rent Allowance</td>
                <td class="custom-font"></td>

                <td class="custom-font">Professional Tax</td>
                <td></td>
            </tr>

            <tr>
                <td class="custom-font">Conveyance Allowance</td>
                <td></td>

                <td class="custom-font">TDS</td>
                <td></td>
            </tr>

            <tr>
                <td class="custom-font">Medical Allowance</td>
                <td></td>

                <td rowspan="3"></td>
                <td rowspan="3"></td>
            </tr>

            <tr>
                <td class="custom-font">Mobile Allowance</td>
                <td></td>
            </tr>

            <tr>
                <td class="custom-font">Executive Allowance</td>
                <td></td>
            </tr>

            <!-- space -->
            <tr>
                <td style="border-right-style: hidden;">&nbsp;</td>
                <td style="border-right-style: hidden;">&nbsp;</td>
                <td style="border-right-style: hidden;">&nbsp;</td>
                <td>&nbsp;</td>
            </tr>

            <!-- Totals -->
            <tr>
                <th>Total Earnings</th>
                <td>0</td>
                <td>0</td>
                <td>0</td>
            </tr>

            <tr>
                <th colspan="4">Net Pay : - Rs. 00,000.00/-</th>
            </tr>
            <tr>
                <th colspan="4">
                    Net Pay (In Words): - Rs. 0 Thousand 0 Hundred and 0 Only
                </th>
            </tr>

            <!-- space -->
            <tr style="border-bottom:hidden">
                <td colspan="4" style="border-left-style: hidden;border-right-style: hidden;text-align: center">
                    "This is a computer generated statement and does not require any
                    signature or stamp."
                </td>
            </tr>

            <!-- leave details -->
            <tr>
                <th class="custom-font" colspan="4" style="border-left-style:hidden;border-right-style:hidden">Leave Balance</th>
            </tr>

            <tr>
                <td class="custom-font" colspan="2">Accumulated Leave (Opening Leaves)</td>
                <td colspan="2">0</td>
            </tr>

            <tr>
                <td class="custom-font" colspan="2">Leave Taken</td>
                <td colspan="2">0</td>
            </tr>

            <tr>
                <td class="custom-font" colspan="2">Leave Balance (Closing Leaves)</td>
                <td colspan="2">0</td>
            </tr>
        </tbody>
    </table>
</body>

</html>

这是 Dompdf 0.8.3 及更早版本的呈现问题。问题的核心是 table 单元格的渲染顺序与用于渲染 table 单元格边框和折叠边框时的背景的技术相结合。

首先,与 Dompdf 中的所有内容一样,较早的元素在文档结构中较晚的元素之前呈现。当一个单元格跨行时,它会先于后续行中的单元格呈现。这一点很重要,因为 PDF 中对象的堆叠顺序(后面的对象呈现在前面的对象之上)。

其次,单元格边框由任意两个相邻单元格组成的一组中的单个单元格呈现。对于水平相邻的单元格,右侧的单元格呈现左边框。对于垂直相邻的单元格,底部的单元格呈现顶部边框。

第三,单元格背景渲染到单元格边缘,不考虑边框。

现在将这三个事实考虑到一个 row-spanned 单元格位于其他 table 单元格的右侧。 row-spanned 单元格的左边框将被渲染。下一行中的相邻单元格不会呈现边框,任何背景都会呈现单元格的整个宽度。因此,后面的单元格背景将呈现在 row-spanned 单元格的边框上方。

您可以在以下示例中看到此问题(例如,当 运行 在 Dompdf 0.8.3 中):

    <head>
        <title>Row-span overlap</title>
        <style>
            table {
                border-collapse: collapse;
            }
            table td {
                border: 1px solid red;
                background-color: #0000ff66;
            }
            .rowspan {
                border-left-width: 10px;
            }
        </style>
    </head>
    
    <body>
        <table>
            <tbody>
                <tr>
                    <td>1</td>
                    <td rowspan="2">2</td>
                </tr>
                <tr>
                    <td>3</td>
                </tr>
            </tbody>
        </table>
    </html>

该问题将在 Dompdf 0.8.4 中得到解决。解决该错误的主要更改是在边框内渲染背景。