feat(联系人): 添加联系人信息导出为PDF功能

在联系人列表页面添加导出为PDF按钮,实现将筛选后的联系人信息导出为PDF文件。新增视图函数处理PDF生成逻辑,支持中文显示并保留原有筛选条件。
This commit is contained in:
2026-01-12 15:48:51 +08:00
parent 7c2095a52e
commit 8eba3f0160
6 changed files with 448 additions and 335 deletions

Binary file not shown.

View File

@@ -131,6 +131,15 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="mt-4 flex justify-end">
<a href="{% url 'export-contacts-pdf' %}{% if request.GET.urlencode %}?{{ request.GET.urlencode }}{% endif %}" class="inline-flex items-center px-4 py-2 bg-purple-600 hover:bg-purple-800 text-white font-medium rounded-lg shadow-md transition duration-300 ease-in-out transform hover:scale-105 hover:shadow-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
导出为PDF
</a>
</div>
</div> </div>
<script> <script>

View File

@@ -15,6 +15,7 @@ urlpatterns = [
path('branch/info/', views.Branchinfo, name='branchinfo'), path('branch/info/', views.Branchinfo, name='branchinfo'),
path('statistics/', views.Statistics, name='statistics'), path('statistics/', views.Statistics, name='statistics'),
path('contact/', views.contact_list, name='contact-list'), path('contact/', views.contact_list, name='contact-list'),
path('contact/export/pdf/', views.export_contacts_pdf, name='export-contacts-pdf'),
path('equipment-images/', views.equipment_images, name='equipment-images'), path('equipment-images/', views.equipment_images, name='equipment-images'),
path('public-screens/', views.public_screens, name='public-screens'), path('public-screens/', views.public_screens, name='public-screens'),
path('video-terminals/', views.video_terminal_list, name='video-terminals'), path('video-terminals/', views.video_terminal_list, name='video-terminals'),

View File

@@ -466,6 +466,109 @@ def contact_list(request):
return render(request, 'contact_list.html', context) return render(request, 'contact_list.html', context)
def export_contacts_pdf(request):
# 创建响应对象
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="contacts_info.pdf"'
# 注册中文字体
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# 尝试注册系统中文字体这里使用Windows系统自带的中文字体
try:
# 尝试注册微软雅黑字体
pdfmetrics.registerFont(TTFont('MSYaHei', 'C:/Windows/Fonts/msyh.ttc'))
chinese_font = 'MSYaHei'
except:
try:
# 如果微软雅黑不存在,尝试注册宋体
pdfmetrics.registerFont(TTFont('SimSun', 'C:/Windows/Fonts/simsun.ttc'))
chinese_font = 'SimSun'
except:
# 如果都找不到,使用默认字体(可能仍会有乱码)
chinese_font = 'Helvetica'
# 创建PDF文档
doc = SimpleDocTemplate(response, pagesize=letter)
elements = []
# 添加标题
styles = getSampleStyleSheet()
# 复制Title样式并修改字体
title_style = ParagraphStyle(
'ChineseTitle',
parent=styles['Title'],
fontName=chinese_font,
fontSize=18,
spaceAfter=30,
alignment=1 # 1表示居中
)
title = Paragraph("联系人信息", title_style)
elements.append(title)
# 获取筛选参数
branches_param = request.GET.get('branches')
category = request.GET.get('category')
contact_name = request.GET.get('contact_name')
# 构建查询条件
filters = Q()
# 分支机构筛选(支持多选)
if branches_param:
branch_ids = [bid.strip() for bid in branches_param.split(',') if bid.strip().isdigit()]
if branch_ids:
filters &= Q(branch_id__in=branch_ids)
# 联系人类别筛选
if category:
filters &= Q(category__contains=category)
# 联系人姓名筛选
if contact_name:
filters &= Q(name__icontains=contact_name)
# 获取筛选后的联系人
contacts = Contact.objects.filter(filters)
# 准备表格数据
data = [['分支机构', '分类', '姓名', '电话', '邮箱']] # 表头
for contact in contacts:
data.append([
contact.branch.name if contact.branch else '',
contact.category or '',
contact.name or '',
contact.phone or '',
contact.email or ''
])
# 创建表格
table = Table(data)
# 设置表格样式
style = TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), chinese_font), # 使用中文字体
('FONTSIZE', (0, 0), (-1, 0), 14),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
('FONTNAME', (0, 1), (-1, -1), chinese_font), # 使用中文字体
('GRID', (0, 0), (-1, -1), 1, colors.black)
])
table.setStyle(style)
# 添加表格到文档
elements.append(table)
# 构建PDF
doc.build(elements)
return response
def video_terminal_list(request): def video_terminal_list(request):
# 获取筛选参数 # 获取筛选参数
selected_branch = request.GET.get('branch', '') selected_branch = request.GET.get('branch', '')