为什么在 django 中使用 xhtml2pdf 呈现为 pdf 时 html table 中的某些列会折叠?

Why some of the column in html table collapsing when rendered to pdf using xhtml2pdf in django?

我正在尝试使用 xhtml2pf 在 Django 中生成 pdf。 HTML 模板主要由 HTML table 组成。呈现 pdf 时,Django PhoneField 和 EmailField 会折叠。

下面是在context中传递Django PhoneField和EmailField时生成的pdf图片-

html模板的上下文如下-

user_dict = {
            "full_name": user.full_name,
            "email": str(user.email),
            "phone_number": str(user.phone_number),
            "emergency_number": "very very long header",
            "id_proof_number": user.id_proof_number

        }

当我使用纯字符串代替 django 字段时,它正确呈现如下 -

使用的上下文如下-

user_dict = {
            "full_name": user.full_name,
            "email": "joe@gmail.com",
            "phone_number": "+14151234567",
            "emergency_number": "very very long header",
            "id_proof_number": user.id_proof_number

        }

Django 模型-

class User(models.Model):
    trip = models.ForeignKey(
    Trip, on_delete=models.CASCADE, related_name="users")
    id_proof_number = models.CharField(
    _("Id Proof"), max_length=100, null=True, blank=True)
    full_name = models.CharField(_("Full name"), max_length=255)
    email = models.EmailField(_("email"), max_length=70)
    phone_number = PhoneNumberField(_("Phone Number"))
    emergency_number = PhoneNumberField(_("Emergency Number"),  default=None, null=True)

HTML 模板-

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Details</title>
    <style type="text/css">
        @page {
            size: A4;
            margin: 1cm;
        }
        .card-header{
            text-align: center;
        }
        .table{
            border: 0.5px solid #ababab;
            text-align: center;
            width: 100%;
            max-width: 100%;
            margin-bottom: 5px;
            table-layout:fixed;
        }
        .table tr th td{
            white-space: nowrap;
        }
        .table th {
            padding: 5px;
            vertical-align: top;
            background-color: #e8e8e8;
        }
        .table td {
            padding: 5px;
            vertical-align: top;
            -pdf-keep-with-next: false;
        }
        .five {
              width: 5%;
            }
        .twenty {
              width: 20%;
            }
         .fifteen {
              width: 15%;
            }


    </style>
</head>
<body>
<div class="container">
    <div class="card">
        <div class="card-header">
            <h3>Header</h3>
        </div>
    </div>
    <table class = "table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Phone number</th>
                <th>Email</th>
                <th>ID</th>
                <th>emergency number</th>
            </tr>
        </thead>
        <tbody>
            {% for trip in trips %}
                {% for member in trip.users %}
                    <tr>
                        {% if forloop.counter == 1 %}
                            <td rowspan="{{trip.users|length}}">{{trip.id}}</td>
                        {% endif %}
                        <td>{{member.full_name}}</td>
                        <td>{{member.phone_number}}</td>
                        <td>{{member.email}}</td>
                        <td>{{member.id_proof_number}}</td>
                        <td>very very long header</td>
                    </tr>
                {% endfor %}
            {% endfor %}
        </tbody>
    </table>
</div>
</body>
</html>

用于呈现 pdf 的 Django 视图-

def trip_members_pdf(request, id):

    trip_qs = Trip.objects.filter(parent_id=id)
    trips = []
    for trip in trip_qs:
        trip_dict = {
            "id": trip.id,
            "users": []
        }
        users = trip.users.all()
        for user in users:
            user_dict = {
                "full_name": user.full_name,
                "email": "joe@gmail.com",
                "phone_number": "+14151234567",
                "emergency_number": user.emergency_number,
                "id_proof_number": user.id_proof_number

            }
            trip_dict["users"].append(user_dict)
        trips.append(trip_dict)
    return PDFRender.render('docs/trip_member_pdf.html', { 'tour': tour, 'trips': trips})

PDF 渲染器-

from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template
import xhtml2pdf.pisa as pisa


class PDFRender:

    @staticmethod
    def render(path: str, params: dict = {}):
        template = get_template(path)
        html = template.render(params)
        response = BytesIO()
        pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), response)
        if not pdf.err:
            return HttpResponse(response.getvalue(), content_type='application/pdf')
        else:
            return HttpResponse("Error Rendering PDF", status=400)

我找到了这种行为的原因。如果列中的任何值是 None,则渲染器正在折叠该列。我在 None 的情况下传递了空白 space 并且一切正常。我改变了上下文如下-

user_dict = {
        "full_name": user.full_name,
        "email": user.email or " ",
        "phone_number": user.phone_number or " ",
        "emergency_number": "very very long header",
        "id_proof_number": user.id_proof_number

    }