css - weasyprint 没有正确渲染 bootstrap4 css
问题描述
我试图通过首先将其设计为 HTML 并将其提供给 weasyprint 以生成 pdf 来生成发票。我正在使用带有 bootstrap 4.3.1 和 weasyprint 50 的 Django 2.2.5 版本。该函数invoice_generator(request)
使用 和 调用 generate_invoicerequest
函数。username
template_name
视图.py:
from invoice_generator import generate_invoice
def invoice_generator(request, username):
ret_val = generate_invoice(request, username, template_name="ui/invoice.html")
return ret_val
发票生成器.py:
from django.shortcuts import render
from commons.models import SMSUser, SMSMessages, Invoice
from commons.serializers import InvoiceSerialzer
from django.template.loader import get_template
from django.conf import settings
from django.http import HttpResponse
from weasyprint import HTML, CSS
import tempfile
from datetime import datetime, date
def generate_invoice(request, username, template_name):
user_to_invoice = SMSUser.objects.get(username=username)
user_invoice = Invoice(invoice_to=user_to_invoice)
company_to_invoice = user_to_invoice.company_name
company_tin = user_to_invoice.company_tin
account = user_to_invoice.pk
user_email = user_to_invoice.email
all_users_in_company = SMSUser.objects.filter(company_name=company_to_invoice)
user_invoice.save()
invoice_number = user_invoice.pk
paid_status = user_invoice.payment_status
all_sms_sent_by_users = {}
for user in all_users_in_company:
# TODO you can run the code at the begining of each month by doing:
# TODO x = date.today() then x = x.replace(day=1)
total_sent_by_single_user = SMSMessages.objects.filter(
sending_user=user,
delivery_status="True",
sent_date__year=datetime.now().year,
sent_date__month = 10
# sent_date__month = datetime.now().month - 2
)
all_sms_sent_by_users = {
"all_sms_sent": [
{
"user": user,
"total_sent_single_user": total_sent_by_single_user.count()
}
]
}
total_amount_sent = SMSMessages.objects.filter(
sent_date__year = datetime.now().year,
sent_date__month = 10,
# sent_date__month = datetime.now().month - 1,
sending_user__company_name=company_to_invoice
)
# TODO feed the below object to a pdf renderer and return that pdf rendered object
context_object = {
"username": user_to_invoice,
"company_name": company_to_invoice,
"account": account,
"invoice_number": invoice_number,
"tin": company_tin,
"email": user_email,
"bill_month": datetime.now().month - 1,
"all_sms_sent": all_sms_sent_by_users,
"total_amount_sent": total_amount_sent.count(),
"vat": total_amount_sent.count() * 0.70 * 0.15,
"total_price": total_amount_sent.count() * 0.70 * 1.15,
"payment_status": paid_status
}
rendered_html = get_template(template_name).render(
context_object,
request
).encode(encoding='UTF-8')
pdf_file = HTML(string=rendered_html, base_url=request.build_absolute_uri())
pdf_file.render()
pdf_container = pdf_file.write_pdf(
stylesheets=[
CSS(
'ui' + settings.STATIC_URL + 'ui/css/bootstrap.min.css'
)
]
)
response = HttpResponse(content_type='application/pdf;')
response['Content-Disposition'] = 'filename=Invoice ' + company_to_invoice + str(datetime.now().month) + '.pdf'
response['Content-Transfer-Encoding'] = 'UTF-8'
with tempfile.NamedTemporaryFile(delete=True) as pdf_writer:
pdf_writer.write(pdf_container)
pdf_writer.flush()
pdf_writer = open(pdf_writer.name, 'rb')
response.write(pdf_writer.read())
return response
这是ui/invoice.html
:
<!DOCTYPE html>
<html lang="en">
<head>
{% load static %}
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<link rel="shortcut icon" type="image/png" href="{% static 'ui/images/favicon.ico' %}">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- bootstrap4 css -->
<link href="{% static 'ui/css/bootstrap.min.css' %}" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>sms.et | Invoice</title>
</head>
<body class="text-center d-print-block" style="background-color: #f5f5f5;">
<div class="container-fluid align-items-center align-middle">
<header>
<div class="row">
<div class="col-md-12 bg-primary">
<h1 class="font-weight-bold self-center h1 text-white">Service Invoice</h1>
</div>
</div>
<br>
<div class="row">
<div class="col-md-6">
<h4 class="font-weight-light self-center h4"><p>Customer Name: <span class="font-weight-lighter"> {{ username.company_name }}</span></p></h4>
<h4 class="font-weight-light self-center h4"><p>Account: <span class="font-weight-lighter"> {{ account }}</span></p></h4>
<h4 class="font-weight-light self-center h4"><p>T.I.N: <span class="font-weight-lighter"> {{ tin }}</span></p></h4>
</div>
<div class="col-md-6">
<h4 class="font-weight-light self-center h4"><p>Invoice number: <span class="font-weight-lighter"> {{ invoice_number }}</span></p></h4>
<h4 class="font-weight-light self-center h4"><p>Email: <span class="font-weight-lighter"> {{ email }}</span></p></h4>
<h4 class="font-weight-light self-center h4"><p>Bill Month: <span class="font-weight-lighter"> {{ bill_month }}</span></p></h4>
<h4 class="font-weight-light self-center h4"><p>Due date: <span class="font-weight-lighter"> 5 days from this invoice</span></p></h4>
</div>
</div>
</header>
</div>
<hr class="bg-primary">
<h6 class="font-weight-lighter self-center h6"><p>Paid status: {{payment_status}}</p></h6>
<hr class="bg-primary">
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<label class="font-weight-light self-center h2">All users that sent sms:</label>
<div class="row">
<div class="col-md-4">
<!-- dict object all _sms_sent is garnered from the views and parsed accordingly as key & value of all_sms_sent.items -->
{% for key, value in all_sms_sent.items %}
<h4 class="font-weight-lighter h4">username</h4>
{% for val in value %}
<p>{{ val.user }}</p>
</div>
<div class="col-md-4">
<h4 class="font-weight-lighter h4">Company</h4>
<p>{{ val.user.company_name }}</p>
</div>
<div class="col-md-4">
<h4 class="font-weight-lighter h4">Total sent</h4>
<p>{{ val.total_sent_single_user }}</p>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="col-md-6">
<h4 class="font-weight-light self-center h4">Total sms sent in the month:</h4>
</div>
<div class="col-md-6">
<p>{{ total_amount_sent }}</p>
</div>
</div>
<br>
<div class="row">
<div class="col-md-6">
<h4 class="font-weight-light self-center h4">Price per text:</h4>
</div>
<div class="col-md-6">
<p>0.70 Birr</p>
</div>
</div>
<br>
<div class="row">
<div class="col-md-6">
<h4 class="font-weight-light self-center h4">V.A.T:</h4>
</div>
<div class="col-md-6">
<p>{{ vat }} Birr</p>
</div>
<br>
</div>
<br>
<div class="row">
<div class="col-md-6">
<h4 class="font-weight-light self-center h4">Total:</h4>
</div>
<div class="col-md-6">
<p>{{ total_price }} Birr</p>
</div>
</div>
</div>
</div>
</div>
<br>
<br>
<div class="container-fluid align-items-center align-middle bg-primary">
<footer>
<div class="row text-white">
<div class="col-md-4">
<h4 class="font-weight-light self-center h4"><p>Address</p></h4>
<p class="quote font-weight-light center">Ethiopia, Addis Ababa, Kirkos sub-city, woreda 02, House No. 700.</p>
</div>
<div class="col-md-4">
<img src="{% static 'ui/images/logo.jpg' %}" width="50" height="40" class="d-inline-block align-top navbar-brand" alt="">
<br>
<a href="www.sms.et" class="text-white blockquote">www.sms.et</a>
</div>
<div class="col-md-4">
<p class="quote font-weight-light center">Outstanding bill must be settled 5 days after issuance of this service invoice.</p>
<p class="quote font-weight-light center">Any questions can be forwared to us via our phone number: +251977207777</p>
</div>
</div>
</footer>
</div>
</body>
</html>
问题是 weasyprint 没有按预期呈现引导程序 4 css,即如上所述。这是一个问题Bootstrap CSS is not applied in weasyprint 这与我的问题很接近,但所描述的解决方案没有任何区别。澄清一下,这就是它应该看起来的样子(html 版本) :. 但它最终看起来像这样: 还有这个: 有人可以帮忙吗?
编辑以包含项目和应用程序的 urls.py
这是项目中的 urls.py:
urlpatterns = [
# for the ui app
path('ui/', include('ui.urls')),
]
这是 ui 应用程序的 urls.py:
from django.urls import path
from . import views
app_name = "ui"
urlpatterns = [
path('homepage/', views.homepage, name="homepage"),
path('login/', views.login_request, name="login"),
path('dashboard/<username>/', views.dashboard, name="dashboard"),
path('logout/', views.logout_request, name="logout"),
path('register/', views.register_request, name="register"),
path('ajax/dashboard_update/', views.ajax_dashboard_update, name="ajax_dashboard_update"),
path('<username>/invoice/', views.invoice_generator, name="invoice_generator"),
]
解决方案
推荐阅读
- c# - 它们是“相同”的 CodeWars。我的代码没有通过所有测试
- php - 灵活的 jQuery 复选框禁用每个表格行
- machine-learning - 关于SVM,软边际的作用是什么?
- mysql - MySQL date_format(date, '%Y-%m-%d %h') 在 Presto 中相当于 `day-hour`
- javascript - Div 本身就可以正常工作,但在合并到项目中时却不行
- c++ - (C++) 在游戏循环中执行一次指令 (SFML)
- mysql - MySql:如果我将 binlog 格式设置为 row,dose change buffer 仍然有效吗?
- fortran - 将数据存储在一维数组中
- jquery - “node_modules”文件夹的用途是什么?
- c++ - C++ 项目的 MakeFile