python连接小程序云开发数据库,并根据word模板导出word

需求:微信小程序云开发数据库存储,需要将数据库中的答案进行导出,从而生成一个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()  # order_by默认是升序 -或desc()是降序
    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'))  # 把我们得图片以‘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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值