需求:微信小程序云开发数据库存储,需要将数据库中的答案进行导出,从而生成一个word 难点1: 利用python的docxtpl包进行模板导出 难点2: python获取云开发的数据库数据 难点3: 数据库中存储的是fileID,仅在微信开发者工具中可以使用,在外部是无法访问,通过接口进行转化
实现方法 1.python环境中 pip install docxtpl
from docxtpl import DocxTemplate
doc = DocxTemplate("my_word_template.docx")
context = { 'company_name' : "World company" }
doc.render(context)
doc.save("generated_doc.docx")
对于图片的插入:
from docxtpl import InlineImage
from docx.shared import Mm
myimage = InlineImage(doc, image_descriptor='test_files/python_logo.png', width=Mm(20), height=Mm(10))
2.python连接数据库 直接操作指的是通过python程序对云开发数据库直接进行操作。 所有的操作前提都是在获取access_token下进行的,先通过下列代码获取access_token在进行接下来的操作。
def access_token():
""""
获取access_token
"""
APPID = '**********' //小程序ID
APPSECRET = '**************' //小程序秘钥
WECHAT_URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + APPID + '&secret=' + APPSECRET
response = requests.get(WECHAT_URL)
result = response.json()
return result["access_token"] //将返回值解析获取access_token
其中access_token是有两个小时的时效性的,access_token没必要一直获取,可以在数据库中存储access_token,当超过时效性的时候再进行获取。
class AccessToken(db.Model):
id = db.Column(db.Integer, primary_key=True)
access_token = db.Column(db.String(200), index=True)
expire = db.Column(db.Integer)
save_time = db.Column(db.Float, default=time.time)
def get_access_token():
access_token = AccessToken.query.order_by(-AccessToken.save_time).first()
if access_token and access_token.save_time + access_token.expire > time.time() - 300:
token = access_token.access_token
else:
APP_ID = "12323213"
APP_SECRET = "23123123"
url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}'.format(APP_ID, APP_SECRET)
response = requests.get(url)
result = response.json()
token = result['access_token']
expire = result['expires_in']
a_t = AccessToken(access_token=token, expire=expire, save_time=time.time())
db.session.add(a_t)
db.session.commit()
return token
创建集合
def databaseCollectionAdd(access_token):
""""
创建数据库
"""
url = 'https://api.weixin.qq.com/tcb/databasecollectionadd?access_token='+access_token
data={
"env":"******", //用户的数据库环境ID
"collection_name": "*******" //数据库集合的名称
}
response = requests.post(url, data=json.dumps(data))
result = response.json()
print(result) //将返回值打印
查询记录
def databaseQuery(access_token,collection_name):
""""
检索数据库
collection_name 集合的名称
.limit() 括号内的数值限定返回的记录数
"""
url = 'https://api.weixin.qq.com/tcb/databasequery?access_token=' + access_token
data = {
"env": "*******", //用户的数据库环境ID
"query": "db.collection(\""+collection_name+"\").limit(100).get()"
}
response = requests.post(url, data=json.dumps(data))
result = response.json()
print(result) //将返回值打印
插入记录
def databaseAdd(access_token,collection_name):
""""
新建记录并对内容进行定义
collection_name 集合的名称
"""
url = 'https://api.weixin.qq.com/tcb/databaseadd?access_token=' + access_token
data = {
"env": "",
"query": "db.collection(\""+collection_name+"\").add({"+datas+"})"
}
datas=[{
"字段名称":"内容"
"""
这里主要是对创建记录的直接定义
"""
}]
response = requests.post(url, data=json.dumps(data))
result = response.json()
print(result) //将返回值打印
删除记录
def databaseDelete(access_token,collection_name):
""""
collection_name 集合的名称
"""
url = 'https://api.weixin.qq.com/tcb/databasedelete?access_token=' + access_token
data = {
"env": "*******", //用户的数据库环境ID
"query": "db.collection(\""+collection_name+"\")..where({done:false}).remove()"
}
response = requests.post(url, data=json.dumps(data))
result = response.json()
print(result) //将返回值打印
更新记录
def databaseUpdate(access_token,collection_name):
""""
.where() 该集合所在记录的检索
"""
url = 'https://api.weixin.qq.com/tcb/databaseupdate?access_token=' + access_token
data = {
"env": "",
"query": "db.collection(\""+collection_name+"\").where({age:14}).update({data:{age: _.inc(1)}})""
}
"""
这个例子是将集合里age=14所有记录自增1
"""
response = requests.post(url, data=json.dumps(data))
result = response.json()
print(result) //将返回值打印
也可间接操作数据库,直接调用云函数
def xxxx(self):
//在函数括号内需要添加参数
ACCESS_TOKEN = xxx //获取的access_token
ENV = xxx //用户的数据库环境ID
FUNCTION_NAME = xxx //所要执行的云函数名
url = 'https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=' + ACCESS_TOKEN + '&env=' + ENV + '&name=' + FUNCTION_NAME
data = {
//所要传输的参数
}
response = requests.post(url=url, data=json.dumps(data))
result = response.json()
3.关于数据库中存储的是文件的fileID,我们需要得到对应的外部可以访问的连接:
def get_download_url(access_token, fileid):
url = "https://api.weixin.qq.com/tcb/batchdownloadfile?access_token=" + access_token
data = {
"env": "ENVID",
"file_list": [{
"fileid": fileid,
"max_age": 7200}]
}
response = requests.post(url, data=json.dumps(data))
result = response.json()
print("url", result['file_list'][0]['download_url'])
return result['file_list'][0]['download_url']
在获取外部可以访问的连接之后,我们有两种方式转化为docxtpl中所需要的,方式一:直接将外部访问的链接存储到本地:
urllib.request.urlretrieve(download_url,"00000001.jpg")
insert_image = InlineImage(doc, "00000001.jpg", width=Mm(80))
answer[index]['imageurl'] = insert_image
方法二:直接获取文件流
response = requests.get(url)
image = Image.open(BytesIO(response.content))
imgByteArr = BytesIO()
image.save(imgByteArr, format('PNG'))
insert_image = InlineImage(doc, imgByteArr, width=Mm(80))
answer[index]['imageurl'] = insert_image
好了 以上难点基本就这些,总结一下这几天的知识积累,最后再给大家看一下word中的模板: 小程序中的云数据库模糊查询:
db.collection('todos').where({
description: db.RegExp({
regexp: 'miniprogram',
options: 'i',
})
})
小程序的HTTP API文档:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/batchDownloadFile.html 参考文章:https://blog.csdn.net/qq_44001007/article/details/103944492
|