导出为 PDF Django / Python 时如何在 HTML table 中保存 space
How save space in HTML table when exporting to PDF Django / Python
我有一个非常简单的 table,它让所有员工在一个特定的地址上工作,然后 returns 我得到一个如下所示的姓名列表:
我的问题是如何让 table 填满整个页面,这样我就有 1 页并排排列的页面,以便在打印时保存 space,而不是 3 页或更多。
现在的布局是
第 1 页:名称(中断)
第2页:名称(中断)
第3页:名称(中断)
我想要这样的东西:
第 1 页:姓名 |名称 |名称(在不破坏页面的情况下尽可能多地保存 space。)
到目前为止我尝试使用的代码是这样的:
<style type="text/css">
@page {
size: letter portrait;
size: Letter;
margin: 1.0cm;
}
body {
font-size: 10pt;
}
. {
padding: 4px;
}
table {
border-collapse: collapse;
}
table,
th,
td,
tr,{
word-wrap:break-word;
table-layout:fixed;
border: 1px solid black;
margin-top: 50%;
text-align: left;
padding: 8px;
}
.wrap {
width: 50%;
}
.left_col {
float: left;
width: 48.4%;
}
.right_col {
float: right;
width: 50%;
}
</style>
</head>
<body style="margin-bottom:1px;">
<div>
<h1>Jobsite: <b>{{location}}</b></h1>
<h4>Date: <b>{{date}}</b></h4>
</div>
<table>
<tr>
<th>Name</th>
</tr>
{% for item in data %}
<tr><td>{{forloop.counter}} - {{ item.LastFirst }}</tr></td>
{% endfor %}
<h5>Manager's Signature: _______________________________________</h5>
</table>
</body>
</html>
这是我处理视图的地方:
@login_required()
def download_pdf(request, location_name):
current = CurrentInfo()
pdf_data = current.detail_employees_by_location(location_name) # this gives me the list of people
pf = pd.DataFrame.from_dict(pdf_data, orient='index', columns=['EmployeeNumber', 'LastFirst'])
data = pf.drop_duplicates()
count = data.count()
data = data.to_dict('records')
today = datetime.datetime.now()
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="report.pdf"'
html = render_to_string('user_area/template_download.html',
context={
'data': data,
'location': location_name,
'date': today
})
pisa_status = pisa.CreatePDF(html, dest=response)
if pisa_status.err:
return HttpResponse('We had some errors <pre>' + html + '</pre>')
return response
我能想到的最简单的解决方案是将几个 td
元素并排放置。
正如您所注意到的,forloop
有几个属性。我们可以将其用于决策。
请注意,我向第 th 添加了一个 colspan=3
以使其跨越所有三列。
无法测试 Django HTML 代码,因此它可能略有偏差 ;)
<body style="margin-bottom:1px;">
<div>
<h1>Jobsite: <b>{{location}}</b></h1>
<h4>Date: <b>{{date}}</b></h4>
</div>
<table>
<tr>
<th colspan="3">Name</th>
</tr> #changed the for loop to accept remainder operation.
{% for item in data %}
{% if forloop.first or forloop.counter0|divisibleby:"3"%}<tr>{%endif%}
<td>{{forloop.counter}} - {{ item.LastFirst }}</td>
{% if forloop.last or forloop.counter|divisibleby:"3"%}</tr>{%endif%}
{% endfor %}
</table>
<h5>Manager's Signature: _______________________________________</h5>
</body>
一些解释,我使用了两个不同版本的 counter
,零基础的和普通的。原因是我不能 100% 确定 Django 模板是否正确解析了 + 1。在 python 我会这样做:
In [2]: for i in range(100):
...: if i==0 or i % 3 == 0:
...: print('<tr>')
...: print(i)
...: if i==99 or (i + 1) % 3 == 0:
...: print('</tr>')
输出与我的想法相似:
<tr>
0
1
2
</tr>
<tr>
3
4
5
</tr>
{% if forloop.first or forloop.counter0 % 3 == 0 %}<tr>{%endif%}
如果是第一次迭代,或者如果是“第三次迭代”:开始 <tr>
、
类似,但对于结束标记:
{% if forloop.last or forloop.counter % 3 == 0 %}</tr>{%endif%}
如果它是最后一项,或者是“第三项”,请关闭 tr。
我有一个非常简单的 table,它让所有员工在一个特定的地址上工作,然后 returns 我得到一个如下所示的姓名列表:
我的问题是如何让 table 填满整个页面,这样我就有 1 页并排排列的页面,以便在打印时保存 space,而不是 3 页或更多。
现在的布局是
第 1 页:名称(中断) 第2页:名称(中断) 第3页:名称(中断)
我想要这样的东西: 第 1 页:姓名 |名称 |名称(在不破坏页面的情况下尽可能多地保存 space。)
到目前为止我尝试使用的代码是这样的:
<style type="text/css">
@page {
size: letter portrait;
size: Letter;
margin: 1.0cm;
}
body {
font-size: 10pt;
}
. {
padding: 4px;
}
table {
border-collapse: collapse;
}
table,
th,
td,
tr,{
word-wrap:break-word;
table-layout:fixed;
border: 1px solid black;
margin-top: 50%;
text-align: left;
padding: 8px;
}
.wrap {
width: 50%;
}
.left_col {
float: left;
width: 48.4%;
}
.right_col {
float: right;
width: 50%;
}
</style>
</head>
<body style="margin-bottom:1px;">
<div>
<h1>Jobsite: <b>{{location}}</b></h1>
<h4>Date: <b>{{date}}</b></h4>
</div>
<table>
<tr>
<th>Name</th>
</tr>
{% for item in data %}
<tr><td>{{forloop.counter}} - {{ item.LastFirst }}</tr></td>
{% endfor %}
<h5>Manager's Signature: _______________________________________</h5>
</table>
</body>
</html>
这是我处理视图的地方:
@login_required()
def download_pdf(request, location_name):
current = CurrentInfo()
pdf_data = current.detail_employees_by_location(location_name) # this gives me the list of people
pf = pd.DataFrame.from_dict(pdf_data, orient='index', columns=['EmployeeNumber', 'LastFirst'])
data = pf.drop_duplicates()
count = data.count()
data = data.to_dict('records')
today = datetime.datetime.now()
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="report.pdf"'
html = render_to_string('user_area/template_download.html',
context={
'data': data,
'location': location_name,
'date': today
})
pisa_status = pisa.CreatePDF(html, dest=response)
if pisa_status.err:
return HttpResponse('We had some errors <pre>' + html + '</pre>')
return response
我能想到的最简单的解决方案是将几个 td
元素并排放置。
正如您所注意到的,forloop
有几个属性。我们可以将其用于决策。
请注意,我向第 th 添加了一个 colspan=3
以使其跨越所有三列。
无法测试 Django HTML 代码,因此它可能略有偏差 ;)
<body style="margin-bottom:1px;">
<div>
<h1>Jobsite: <b>{{location}}</b></h1>
<h4>Date: <b>{{date}}</b></h4>
</div>
<table>
<tr>
<th colspan="3">Name</th>
</tr> #changed the for loop to accept remainder operation.
{% for item in data %}
{% if forloop.first or forloop.counter0|divisibleby:"3"%}<tr>{%endif%}
<td>{{forloop.counter}} - {{ item.LastFirst }}</td>
{% if forloop.last or forloop.counter|divisibleby:"3"%}</tr>{%endif%}
{% endfor %}
</table>
<h5>Manager's Signature: _______________________________________</h5>
</body>
一些解释,我使用了两个不同版本的 counter
,零基础的和普通的。原因是我不能 100% 确定 Django 模板是否正确解析了 + 1。在 python 我会这样做:
In [2]: for i in range(100):
...: if i==0 or i % 3 == 0:
...: print('<tr>')
...: print(i)
...: if i==99 or (i + 1) % 3 == 0:
...: print('</tr>')
输出与我的想法相似:
<tr>
0
1
2
</tr>
<tr>
3
4
5
</tr>
{% if forloop.first or forloop.counter0 % 3 == 0 %}<tr>{%endif%}
如果是第一次迭代,或者如果是“第三次迭代”:开始 <tr>
、
类似,但对于结束标记:
{% if forloop.last or forloop.counter % 3 == 0 %}</tr>{%endif%}
如果它是最后一项,或者是“第三项”,请关闭 tr。