起源:最近了使用flask和bootstrap写了测试小工具,数据全部使用excel存储,部署到测试环境。

问题:每次每个人在使用excel数据时都需要重新编辑好的excel通过upload按钮传到服务器,然后再选择自己上传的那个文件名,使用本地xlsx的缺点是操作太过于繁琐,且对于实时协作太不方便。

优化:实际使用场景是,多人需要使用不同的数据,每个人最好是维护一份excel文档,多人协作excel国外使用google sheets,国内的也有在线协作的表格

官网资料

API文档

环境准备

  1. 打开注册api项目页面,在谷歌开发者控制台创建或选择一个项目,点击继续。
  2. 在证书添加页面,点击取消按钮。
  3. 点击顶部的tab按钮OAuth同意屏幕按钮,选择邮件地址,填写向用户显示的产品名称,点击保存。
  4. 选择app类型为其它,输入项目名称,如:test,点击创建按钮。
  5. 弹出窗上点确定关闭结果弹窗。
  6. 点击生成的json文件右边的下载按钮,保存该认证文件,重命名为:client-secret.json。

安装gdata-python-client

pip install --upgrade google-api-python-client

更多安装选项

首次运行生成credentials.json

过程:首次运行google sheets的时候,会寻找credentials.json文件,如果没有会主动打开浏览器,登陆验证后,会自动下载该文件。

步骤

步骤1 运行官方的示例

步骤2 命令行显示:

no credentials.json file.
C:\Users\lunah\.virtualenvs\mercku_qa-TKqmE-c_\lib\site-packages\oauth2client\_helpers.py:255: UserWarning: Cannot access credentials.json: No such file or directory
  warnings.warn(_MISSING_FILE_MESSAGE.format(filename))

Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fspreadsheets&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&response_type=code&client_id=418130056826-sg1hqp565gqcmcqr3c3dtbpiebnnme9j.apps.googleusercontent.com&access_type=offline

If your browser is on a different machine then exit and re-run this
application with the command-line parameter

  --noauth_local_webserver

Authentication successful.

步骤3 此时浏览器自动打开,如果打开失败则手动复制链接浏览器打开

步骤4 登陆当前google账号,如果当前没有登陆,则需要登录,如果有多个账号则需要选择一个账号

步骤5 点击接受按钮,会自动下载credentials.json,位置默认生成在~/.credentials.json,该存储位置是定义在代码中的get_credentials()函数中的,也可以修改为其它位置保存

步骤6 下载成功后浏览器会显示,查看~/.credentials.json文件已经成功下载

A1 表示法

一些 API 方法需要以 A1 表示法表示的范围。 这是一个类似 Sheet1!A1:B2 的字符串,它会引用电子表格中的一组单元格,并且一般用于公式。

例如,有效的范围如下所示:

Sheet1!A1 指定单元格
Sheet1!A1:A1 指定单元格,同第一个
Sheet1!A1:B2 斜角指定范围
Sheet1!A:A 引用 Sheet1 第一列中的所有单元格。
Sheet1!1:2 引用 Sheet1 前两行中的所有单元格。
Sheet1!A5:A 引用 Sheet1 第一列中从第 5 行开始的所有单元格。
A1:B2 引用第一个可见工作表前两行中的前两个单元格。
Sheet1 引用 Sheet1 中的所有单元格。

也支持命名范围。 如果某个命名范围与一个工作表的名称冲突,命名范围的优先级更高。

注意:按照最后有值的读取,如果中间有空的则会读取为空字符串,但是如果最后一个有值的后面都是空,哪怕指定的范围包含该单元格也不会读取到。见官方说明,搜索空白的拖尾行和列将被忽略。, 如果想要读取这些空白,则需要在要读取的最后一个单元格加上一个任意的字符.

读取操作

读取数据

使用values().get

  result = self._service.spreadsheets().values().get(spreadsheetId=spreadsheet_id,
                                            range="name!A1:H5".execute()
  values = result.get('values')
  if not values:
      print('No data.')
  else:
      return values

获取所有sheets

具体查看Method: spreadsheets.get

读取数据

查看如上代码:

spreadsheetId = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms'
rangeName = 'Class Data!A2:E'

示例中的在线数据链接为https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit

中间一串代码为spreadssheetId。

rangeName中的前面Class Data为要读取的sheet名称

如果读取的是第一个sheet,则该name也可以省略,如A2:E.

加工数据

通过不同的spreed_ID和该文档下面的sheet name获取数据。

如:

main函数中rangeName修改为

rangeName '%s!%s:%s' % (sheetname, start, end)

start 和 end使用A1表示法获取范围。

values = result.get('values', [])

该values为二维数组,结构如:

[[a, b],[c, d],[c, d]]

使用命名元祖加工为便读取的数据:

from collections import namedtuple

col_names = ['name', 'age', 'sex'] # 自定义命名
Tu = namedtuple("Tu", col_names)
datas = []
for value in values:
    tmp = Tu(*value)
    datas.append(tmp)
# get data
for data in datas:
  print data.name, data.age, data.sex

通过点操作取数据。

如需修改命名元组实例的_replace()方法。

也可以使用构造dict的方法,但命名元组效率更好,字典存储需要更多的内存空间。

写入数据

Google Sheets API 提供的 spreadsheets.values 集合可以对值进行简单的读取和写入操作。

范围获取 方法
单个范围 spreadsheets.values.update
多个范围 spreadsheets.values.batchUpdate
追加 spreadsheets.values.append

查看基本写入示例

values = [
    [
        1, 2
    ],
    # Additional rows ...
]

body = {
  'values': values
}

result = self._service.spreadsheets().values().update(
            spreadsheetId=self.spreadsheet_id,
            valueInputOption="RAW",
            range="router!G2:H2",
            body=body).execute()
print result

执行结果:

{
  'spreadsheetId': u'1EOQQjudspn7ZFTcOKA7gVh9Pk3CUrQ8agVB6NJ2aqdk',
  'updatedRange': u'router!G2:H2',
  'updatedCells': 2,
  'updatedRows': 1,
  'updatedColumns': 2
}

写入中文

直接写入:requets返回的数据,写入res.content即可,里面的中文能直接写入

总结

单个范围读写用get|update,多个范围读写用batchxxx.如果要对表格进行进一步的操作,如添加备注等,需要使用Access the API with Apps Script

格式化表格-修改表格属性

修改基本属性, 先看右边的视频

不同变成语言实现

creating frozen rows

bolding cells

implementing currency formatting

performing cell validation

restricting cell values

基本结构

sheet_id = ''
reqs = {
    'requests':[
        {'updateSheetProperties': '...'},
        {'repeatCell': '...'},
        {'setDataValidation': '...'},
        {'sortRange': '...'},
        {'addChart': '...'}
    ]
}
Sheets.spreadsheets().batchUpdate(spreadsheetId=sheet_id, body=reqs).execute()

具体结构

sheetId:第一个id为0,但是注意后面的ID并不是1,2,3这样的规律数.是一串码,通过spreadsheet.get()获取

如下的sheetId是一串数字2141796593

"sheets": [
    {
      "properties": {
        "sheetId": 0,
        "title": "user",
        "index": 0,
        ......
    }
    {
      "properties": {
        "sheetId": 2141796593,
        "title": "school",
        .......
        }
      }
  ]

指定范围:不包含末尾值

fields: 指定写的改变属性,哪些需要真正应用改变,fields masks.

如下图,需要获取绿色部分的范围值

"range": {
                    "sheetId": 0,
                    "startRowIndex": 2,  #行数要减一,从0开始
                    "endRowIndex": 4,
                    "startColumnIndex": 1,
                    "endColumnIndex": 3
                }

updateSheetProperties

{
      "updateSheetProperties": {
        "properties": {
          "sheetId": sheetId,
          "gridProperties": {
            "frozenRowCount": 1
          }
        },
        "fields": "gridProperties.frozenRowCount"
      }
    }

repeatCell

UserEnterFormat

就是用户输入的一些格式化啦。

rgba:这里的red,green,blue,alpha值在0-1之间,见文档,如果0-255的值要用0-1表示则使用:值/255得到。更改背景色,和字体颜色用到。

常用属性:

NumberFormat

TextFormat改变文本格式

setDataValidation

{
  "range": {
    object(GridRange)
  },
  "rule": {
    object(DataValidationRule)
  },
}

GridRange

DataValidationRule

试调API

错误集锦

insufficient authentication scopes

如果直接使用的是google sheets官方示例文档quickstart.py,在写入数据是会报错:

Request had insufficient authentication scopes.

说明

google sheets api提供的权限有多种,具体查看authorizing中的scope说明表。

quickstart.py中使用的scope='https://www.googleapis.com/auth/spreadsheets.readonly',如下代码段

SCOPES = 'https://www.googleapis.com/auth/spreadsheets.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Google Sheets API Python Quickstart'

只读权限,所以之前生成的credentials.json的权限是只读权限。

解决

步骤1:将代码中的scope修改为authorizing中的scope说明表中对应你想要的权限。

如,需要读写权限,修改scope:

scope = 'https://www.googleapis.com/auth/spreadsheets'

步骤2:然后,删除本地已有的credentials.json,然后运行修改过后的脚本,重新生成credentials.json文件,新生成的credentials.json就是读写权限都有的了。

注意:步骤2,很重要,很重要,很重要。

操作google_sheets的更多相关文章

  1. 关于DOM的操作以及性能优化问题-重绘重排

     写在前面: 大家都知道DOM的操作很昂贵. 然后贵在什么地方呢? 一.访问DOM元素 二.修改DOM引起的重绘重排 一.访问DOM 像书上的比喻:把DOM和JavaScript(这里指ECMScri ...

  2. Sql Server系列:分区表操作

    1. 分区表简介 分区表在逻辑上是一个表,而物理上是多个表.从用户角度来看,分区表和普通表是一样的.使用分区表的主要目的是为改善大型表以及具有多个访问模式的表的可伸缩性和可管理性. 分区表是把数据按设 ...

  3. C# ini文件操作【源码下载】

    介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...

  4. js学习笔记:操作iframe

    iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...

  5. jquery和Js的区别和基础操作

    jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...

  6. ASP.NET Aries 入门开发教程7:DataGrid的行操作(主键操作区)

    前言: 抓紧勤奋,再接再励,预计共10篇来结束这个系列. 上一篇介绍:ASP.NET Aries 入门开发教程6:列表数据表格的格式化处理及行内编辑 本篇介绍主键操作区相关内容. 1:什么时候有默认的 ...

  7. 如何在高并发环境下设计出无锁的数据库操作(Java版本)

    一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...

  8. 【翻译】MongoDB指南/CRUD操作(四)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选 ...

  9. 【翻译】MongoDB指南/CRUD操作(三)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(三) 主要内容: 原子性和事务(Atomicity and Transactions),读隔离.一致性和新近 ...

随机推荐

  1. Hive数据倾斜的原因及主要解决方法

    数据倾斜产生的原因 数据倾斜的原因很大部分是join倾斜和聚合倾斜两大类 Hive倾斜之group by聚合倾斜 原因: 分组的维度过少,每个维度的值过多,导致处理某值的reduce耗时很久: 对一些 ...

  2. STM32CubeMx——串口使用DMA收发

    用到的是DMA发送数据,接收还是普通的串口接收. 一.代码生成 1.按以前的方法设置好时钟和调试方式,这里就不多说了. 2.设置串口1. 3.在DMA Setting里点击Add添加USART1_TX ...

  3. OpenCV-Python 对极几何 | 五十一

    目标 在本节中 我们将学习多视图几何的基础知识 我们将了解什么是极点,极线,极线约束等. 基础概念 当我们使用针孔相机拍摄图像时,我们失去了重要信息,即图像深度. 或者图像中的每个点距相机多远,因为它 ...

  4. WEB缓存控制机制与varnish简介

    在说到缓存varnish前,我们首先来了解下对于web服务缓存到底是什么?它有哪些特点,基础原理是什么? http是web应用协议,通常我们说的一次http事务,不外乎就是客户端请求,服务端响应,通常 ...

  5. 6.Maven构建过程的各个环节

    构建过程中的各个环节 [1]清理:将以前编译得到的旧的class字节码文件删除,为下一次编译做准备 [2]编译:将Java源程序编译成class字节码文件 [3]测试:自动测试,自动调用junit程序 ...

  6. 树莓派扩展usb wifi-EPU-N8508GS

    树莓派zero 扩展USB WIFI EPU-N8508GS 指令: sudo lsusb 终端显示如下,其中显示RTL8188CUS信息,说明系统已经成功识别到wifi模块 Bus 001 Devi ...

  7. 一文彻底读懂MySQL事务的四大隔离级别

    前言 之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够清楚,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助~ 事务 什么是事务? 事务,由一个有限的数据库操 ...

  8. 如何使用Java中的Enum类

    Java1.5 中出现了枚举类型.当一个值都在一个固定的范围内变化,那就可以使用 enum 类型来定义.比如说,一周有七天,一年有四季. 没有枚举类的时候,我们用常量来定义一组范围值的: public ...

  9. 数据源管理 | 基于JDBC模式,适配和管理动态数据源

    本文源码:GitHub·点这里 || GitEE·点这里 一.关系型数据源 1.动态数据源 动态管理数据源的基本功能:数据源加载,容器维护,持久化管理. 2.关系型数据库 不同厂商的关系型数据库,提供 ...

  10. MiniUi遇到的一个Bug或者说坑,以div里面的内容自适应高度

    页面源码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...