任务:保存json
格式数据到pdf
表格
1. 背景
来源,小练手项目。
请求数据的前端接口为:/get/all/userinfo
采用的后端为flask
,因为后端自定定义了对应的数据获取,这里就直接调用后端的接口:from db.users import UserDB UserDB().getAllUserInfo()
对应的数据库采用mongodb
,删除其余的非相关部分,UserDB
类如下:
import pymongo
import db.settings as setting
class UserDB(object):
def __init__(self):
# 获取MongoClient对象
self.myclient = pymongo.MongoClient("mongodb://" + setting.DB_HOST + ":" + setting.DB_PORT + "/")
# 得到数据库链接
self.mydb = self.myclient[setting.DB_DATABASE_NAME]
# 得到user数据库表
self.userTabConnection = self.mydb[setting.DB_TABLE_USERS]
def getAllUserInfo(self):
return list(self.userTabConnection.find())
而setting
就是简单的定义了一些配置信息,如:
PORT = 4040
HOST = '127.0.0.1'
STATIC_FOLDER = 'static'
TEMPLATES_FOLDER = 'templates'
在前端的views
,对应如下定义:
@app.route('/get/all/userinfo', methods=["get"])
def getAllUserInfo():
# username = request.args.get("username")
results = []
for obj in UserDB().getAllUserInfo():
obj = dict(obj)
obj.pop('_id')
results.append(obj)
return json.dumps({
"data": results})
该链接调用:
对应的渲染页面:
而链接地址中的showAll=true
用于在表格中的渲染所有参数,在js
中使用
// 来源:链接获取
// 如:http://127.0.0.1:4040/admin/userinfo?username=%E7%8E%8B%E5%88%9A&showAll=true
if(window.location.search.split("&")[1] != undefined && window.location.search.split("&")[1].split("=")[0] == 'showAll'){
var showAll = JSON.parse(window.location.search.split("&")[1].split("=")[1]); //保存为pdf的时候,需要显示所有
}else{
var showAll = false;
}
来获取到showAll
参数,然后简单配置逻辑即可。
2. 保存pdf
使用pdfkit
,参考使用python生成pdf进行安装。这里做简单记录:
- 安装
pdfkit
:pip install pdfkit -i https://pypi.douban.com/simple
- 安装
wkhtmltopdf
:https://wkhtmltopdf.org/downloads.html
经过测试,使用pdfkit.from_url
没有延迟,不能完整加载所有内容,故这里考虑直接使用字符串的格式。
import pdfkit
from db.users import UserDB
config=pdfkit.configuration(wkhtmltopdf=r"D:\softwares\wkhtmltopdf\bin\wkhtmltopdf.exe")
options = {
'page-size': 'A4',
'margin-top': '10mm',
'margin-right': '10mm',
'margin-bottom': '10mm',
'margin-left': '10mm',
'orientation':'Landscape', #横向
'encoding': "UTF-8",
'no-outline': None,
'footer-right':'[page]' #设置页码
}
HTML = "<center style='margin-bottom: 20px;'><h1>总用户信息</h1></center><table class='mytable'><tr class='mytable-th'><td>用户ID</td><td>用户姓名</td><td>性别</td><td>电话</td><td>QQ</td><td>微信</td><td>用户角色</td><td>所属部门</td><td>直接领导</td></tr>"
kehu_num = 0
datas = list(UserDB().getAllUserInfo())
for i in range(len(datas)):
if datas[i]['role'] == "客户":
kehu_num += 1
HTML += "<tr class='mytable-tr'><td>"+str(i+1)+"</td><td>"+datas[i]['username']+\
"</td><td>"+datas[i]['sex']+"</td><td>"+datas[i]['phone']+"</td><td>"+datas[i]['qq']+\
"</td><td>"+datas[i]['weichat']+"</td><td>"+datas[i]['role']+"</td><td>"+datas[i]['department']+\
"</td><td>"+datas[i]['superior']+"</td></tr>"
HTML += "<div style='font-size: 1.2rem;margin-top: 20px;margin-bottom: 20px;'>用户总数量:"+str(len(datas))+",客户数量:"+str(kehu_num)+",职工数量:"+str(len(datas)-kehu_num)+"</div>"
pdfkit.from_string(HTML, "Test.pdf", options=options, css="randerTable.css", configuration=config)
打开pdf
查看效果:
附css
文件
.mytable{
line-height: 30px;
width: 100%;
border: 1px solid #CCCCCC;
}
.mytable-th{
background: #EEEEEE;
border-bottom: 1px solid #B2B2B2;
}
.mytable-th td{
padding: 5px 20px;
font-size: 1.2rem;
font-weight: bold;
color: #4E5465;
text-align: center;
border-left: 1px solid #EEEEEE;
border-top: 1px solid #EEEEEE;
}
.mytable-tr:hover{
background: #CCCCCC;
}
.mytable-tr td{
padding: 5px 20px;
font-size: 1.2rem;
color: #333333;
text-align: center;
border-left: 1px solid #EEEEEE;
border-top: 1px solid #EEEEEE;
}
.mytable-tr td::selection{
background: #000000;
color: white;
}
.mytable-th td:first-child input,
.mytable-tr td:first-child input{
width: 15px;
height: 15px;
}
.mytable-th td:first-child,
.mytable-tr td:first-child{
padding: 5px 8px;
}
.mytable-tr td:last-child span{
display: inline-block;
margin-left: 10px;
padding: 1px 5px;
border-radius: 3px;
color: white;
font-size: 0.9rem;
cursor: pointer;
/* 设置可选择属性 */
-moz-user-select:none;
-o-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
user-select:none;
letter-spacing: 0.2rem;
}
.mytable-tr td:last-child span:first-child{
margin-left: 0;
background: #009688;
}
.mytable-tr td:last-child span:first-child:hover{
background: #037E74;
color: #EEEEEE;
}
.mytable-tr td:last-child span:last-child{
margin-right: 0;
background: #EB7350;
}
.mytable-tr td:last-child span:last-child:hover{
background: #BC4827;
color: #EEEEEE;
}
.mytable-header{
background: #CCCCCC;
height: 50px;
text-align: left;
display: flex;
flex-direction: row;
border: 2px solid #CCCCCC;
margin-bottom: 10px;
}
.mytable-header-left,
.mytable-header-right{
flex: 1;
}
.mytable-header-right{
text-align: right;
}
.mytable-header span{
display: inline-block;
line-height: 30px;
margin-top: 10px;
padding-left: 8px;
padding-right: 8px;
border-radius: 5px;
color: white;
/* 设置可选择属性 */
-moz-user-select:none;
-o-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
user-select:none;
letter-spacing: 0.2rem;
margin-left: 5px;
cursor: pointer;
}
.mytable-header .mytable-header-left span:first-child:hover{
background: #087167;
color: #EEEEEE;
}
.mytable-header .mytable-header-left span:first-child{
background: #009688;
}
.mytable-header .mytable-header-left span:last-child:hover{
background: #6C6C6C;
color: #EEEEEE;
}
.mytable-header .mytable-header-left span:last-child{
background: #999999;
}
.mytable-header .mytable-header-left span:nth-child(2):hover{
background: #8E2108;
color: #EEEEEE;
}
.mytable-header .mytable-header-left span:nth-child(2){
background: #CB2D01;
}
.mytable-header .mytable-header-right span:hover{
background: #1C6F36;
}
.mytable-header .mytable-header-right span{
background: #41A863;
margin-right: 10px;
}
.mytable-header .mytable-header-right input{
border: none;
outline:none;
height: 24px;
border-radius: 5px;
width: 200px;
padding-left: 5px;
}
.mytable-bottom{
margin-top: 5px;
display: flex;
flex-direction: row;
font-size: 1.2rem;
padding-bottom: 10px;
}
.mytable-bottom-left{
flex: 1;
}
.mytable-bottom-right{
flex: 1;
text-align: center;
height: 40px;
}
.mytable-bottom-left span,
.mytable-bottom-right span{
display: inline-block;
margin-left: 10px;
height: 30px;
line-height: 30px;
margin-top: 5px;
cursor: pointer;
}
.mytable-bottom-left span:first-child{
margin-left: none;
margin-right: 10px;
color: #555;
font-weight: bold;
}
.mytable-bottom-left span input{
width: 2rem;
}
.mytable-bottom-left span:last-child:hover{
background: #08675F;
}
.mytable-bottom-left span:last-child{
background: #009688;
padding: 2px 5px;
height: 30px;
line-height: 30px;
border-radius: 5px;
color: white;
}
.selected{
background: #BC4827;
color: white;
padding: 2px 5px;
border-radius: 2px;
}
#page-reset:hover{
background: #BC401F;
}
#page-reset{
background: #EB7350;
margin-left: 0;
}