代码之家  ›  专栏  ›  技术社区  ›  chollida

以编程方式更新Google Docs上的电子表格

  •  8
  • chollida  · 技术社区  · 15 年前

    我有一个预先存在的电子表格托管在谷歌文档上。每个月我都更新这个文档。我在电子表格中有一个模板工作表,我想克隆它,然后更新它。

    我宁愿克隆工作表,而不是从头开始创建它,因为它有一些非常复杂的公式。

    我在这里使用的是Google文档的python API:

    http://code.google.com/apis/spreadsheets/data/1.0/developers_guide_python.html

    有人知道如何克隆和复制预先存在的文档中的工作表吗?

    编辑

    我好像把一个读者搞糊涂了。我没有Excel电子表格。我只有一个有模板工作表的谷歌文档电子表格。

    我想克隆这个工作表,重命名它,然后用程序编辑它。

    6 回复  |  直到 7 年前
        1
  •  6
  •   DoctorRuss    14 年前
    1. 使用上的说明克隆模板工作表 Copying Documents
    2. 访问 list of worksheets 在克隆的文档中,循环访问所需的电子表格。
    3. 使用 cell feed 要在电子表格中获取适当的单元格,则 update 价值观。
        2
  •  4
  •   Evan Plaice    12 年前

    哇!!!把卡车倒回去。有一种更简单的方法

    在过去的几周里,我一直在研究这个问题,因为我计划为我的月报做同样的事情。我还没有具体的代码,但我会在取得进展时添加它。

    在google docs中,有太多的api和类似的与使用docs相关的术语,以至于有些事情可能会变得有点混乱。如果你还不知道,在你的头脑中建立一个事实,那就是Gas(Google应用程序脚本)和Gae(Google应用程序引擎)是两个完全不同的东西。即使它们听起来相同,它们也和Java类似JavaScript。

    Gas是嵌入在Google Docs中的scrips(有望在将来作为独立模块导入),它驱动验证和动态文档等东西,但它们比大多数可疑的东西(它们可以执行诸如修改/更新外部文档和自动电子邮件响应等操作)强大得多。请记住,这些需要是轻量级的,因为它们运行在谷歌的服务器上。如果你的脚本需要很长时间才能完成,那么它的执行就会过早地被切断(谷歌会找到限制)。这意味着您应该只使用普通的JS(没有像jquery这样的框架)并尽可能调整性能。

    另一方面,gae就像一个Web服务器(具有可用的数据库层),它生活在云中的某个地方。它作为一个方便(并且已经部署)的中间件层存在,以便企业/利益集团创建自定义应用程序来执行更繁重的工作。不幸的是,外部电子表格的API太有限,无法独立完成我们的工作,所以它是不可选择的。

    使用谷歌应用程序脚本和基于时间的触发器实现自动化

    这种方法 应该 工作,但需要一个稍微黑客的方法。

    打开包含报表工作表的工作簿。单击[工具]->[脚本编辑器…]。一旦找到[Triggers]->[当前脚本的触发器…]。

    如果您没有任何触发器,请添加一个。然后,在“事件”下拉菜单下选择“时间驱动”。

    欢迎来到服务器端事件处理程序的世界。对于基于云的文档,一个很好的特性就是能够直接在文档中触发cron作业。不需要外部中间件。

    如果你现在还没有注意到,“月份计时器”就没有触发器。这就是它被黑客攻击的地方。为了解决这个功能的不足,我们需要每天触发触发器,并使用一些javascript将当前日期与前一天的日期匹配。

    [此处显示代码]

    首先,是附加到时间触发器事件处理程序的函数。这段代码只是简单地解析日期,将其与前一个日期进行比较,并将值存储在一个隐藏的工作表中(我们将其用作外持久层),以备第二天的比较。如果满足新的月份条件,则运行下一个代码块。

    [此处显示代码]

    你的和我的明显不同,但基本概念是:

    • 加载电子表格对象(不要与工作表对象混淆)
    • 定位模板工作表对象
    • 克隆模板工作表,为其提供基于日期范围的适当名称

    在我的工作中,我的下一步将是从月份中提取数据,生成一个堆积折线图,向上级汇报当前的状态。

    注意:由于文档的多用户协作性质,必须在服务器端触发事件。这给我们带来了一个大问题。因为如果代码出错,事件代码会在其他地方运行,所以我们不会从浏览器获得任何反馈。唯一的解决方案是在触发器上设置一个通知,以便在脚本出错时立即向您发送电子邮件。 .

    更新:在研究这个的时候,我发现了另一个很酷的技术。如果我能在没有任何错误的情况下成功地实现这个功能,我可能会尝试使用谷歌日历上标记的日期来调用触发器。

        3
  •  2
  •   Charles    15 年前

    首先,我以前从来没有用Python工作过,但是我会告诉你我是如何在C++中完成这项工作的。

    我用curl向 google documents API . 文件的二进制数据被返回,我把它写到一个文件中。现在我有了XLS文件,然后我使用了一个C/C++库,可以读取XLS文件来操作下载的文件。我使用的API支持多种选项;您可以在Excel中执行任何操作。修改后,我又把它上传到谷歌文档。

        4
  •  2
  •   abatishchev Marc Gravell    13 年前

    这真的很复杂。我知道你可以使用他们的API用python来编辑你的电子表格,google倾向于在他们的许多Web服务上提供这种能力,而且这一切都是通过以某种方式发送XML的HTTP Post请求来完成的,我希望你知道这一点,我不知道。

    根据 this 您至少可以添加工作表、从其他工作表读取行和向工作表写入行。如果必须这样做,您可以一次复制一行,但是为每行发送额外的post请求似乎是一个可怕的想法。

    编辑:

    我越来越了解这个问题,但离解决你原来的问题还有很长的路要走。这个 overview of REST principles 介绍Web上程序之间的基本交互样式。谷歌似乎在虔诚地追随它。

    这一切都发生在HTTP协议中,我以前对此一无所知。在这 HTTP specification 基本的游戏很清楚。它不像它看起来那么干,也许我只是一个巨大的极客,但我发现它是一个鼓舞人心的阅读。不像美国宪法。

    因此,既然您想要“克隆”一个文档,那么您将使用一个特定工作表的GET请求,然后将该工作表作为POST的有效负载发送回去。

    越来越近了:)

        5
  •  1
  •   torbiak    15 年前

    您不能将电子表格导出为XLS,然后将其作为具有(稍微)不同名称的新文档上载,并在XML元数据中指定新名称吗?

    下载和创建/上载文档部分位于 http://code.google.com/apis/documents/overview.html 应该是有益的。

    我不能立即在python api文档中看到任何导入/导出功能,但是发送一些HTTP请求也没那么糟糕。

        6
  •  0
  •   wescpy    7 年前

    (2000年2月2017日) 用当前术语重新表述问题: 你如何复制一个谷歌工作表模板,然后用程序修改它(副本)? 简单回答:使用当前的Google API,特别是 Google Drive v3 API 以及 Google Sheets v4 API 您可以使用 Google APIs Client Libraries .

    最新的Sheets API提供了旧版本中不可用的功能,即让开发人员可以像使用用户界面(UI)一样对工作表进行编程访问,即创建冻结的行、单元格格式、调整行/列的大小、添加数据透视表、单元格验证、创建图表等。

    正如您所猜测的,Sheets API主要用于以编程方式访问上述电子表格操作和功能,但用于执行 文件 水平 接近 例如复制模板工作表,使用 Google Drive API 相反。

    使用驱动器API复制文件(工作表)的伪代码(python)(假设我们首先使用模板名搜索最近修改的文件,因此 orderBy 第一个结果的选择 [0] 以下):

    TMPLFILE = 'my Sheets template'
    tmpl = DRIVE.files().list(q="name='%s'" % TMPLFILE).execute().get('files')[0]
    NEW_SHEET = {'name': 'Sheets data, Feb 2017'}
    SHEET_ID = DRIVE.files().copy(body=NEW_SHEET, fileId=tmpl['id']).execute().get('id')
    

    从SQL数据库(sqlite)中读取值并将其写入上面创建的新工作表(从单元格“a1”开始,显示为“左上角”)的伪代码,就像用户从UI输入值一样(因此可以应用公式等):

    cxn = sqlite3.connect('db.sqlite')
    cur = cxn.cursor()
    rows = cur.execute('SELECT * FROM data').fetchall()
    cxn.close()
    DATA = {'values': rows}
    SHEETS.spreadsheets().values().update(spreadsheetId=SHEET_ID,
        range='A1', body=DATA, valueInputOption='USER_ENTERED').execute()
    

    如果你对现代谷歌API比较陌生,我有一个(有点过时,但是)用户友好的 intro video 为你。之后还有2个视频可能也很有用,包括一个演示如何使用驱动器API的视频。这些是视频2、3和4英寸 this playlist . 视频23和25是另一对以驱动器和板材API为特色的视频。

    所有更新的视频都可以在 this playlist 在这里,您将看到另一对以SheetsAPI为特色的视频,以及上面“模板复制”代码的重印,但复制了幻灯片模板,然后用 Slides API )相反(视频2)。

    如另一个答案所述,您还可以使用 Google Apps Script 如果您喜欢该环境而不是使用RESTAPI,则可以执行类似的操作,尽管应用程序脚本当前使用的是较旧的API。此外,很少有优秀的bug会使它更具挑战性(特别是 this one this one )