简体   繁体   English

如何将存储在 Google Drive 上的 Google Docs 文件(文档模板)转换为 PDF 并下载?

[英]How do I convert Google Docs file (Template for Document) Stored on Google Drive to PDF and download it?

Got stuck on this for few hours now.现在被困了几个小时。 I have a template that I can edit with python.我有一个可以用 python 编辑的模板。 The idea is to copy, edit, convert, download and then delete the file from drive leaving only the empty template.这个想法是复制,编辑,转换,下载然后从驱动器中删除文件,只留下空模板。 I've read through the documentation and tried different methods but I can't figure it out.我已经阅读了文档并尝试了不同的方法,但我无法弄清楚。

Edit: my code so far编辑:到目前为止我的代码

SCOPES = ['https://www.googleapis.com/auth/drive']


DOCUMENT_ID = '1ZgaYCra-7m_oWIBWK9RoMssYNTAsQLa1ELI1vyBB73c'


def main():
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
            'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

     service = build('docs', 'v1', credentials=creds)

    text1 = 'test'

requests1 = [
    {
        'insertText': {
            'location': {
                'index': 110,
            },
            'text': text1
        }
    },
    {
        'insertText': {
            'location': {
                'index': 98,
            },
            'text': text1
        }
    },
    {
        'insertText': {
            'location': {
                'index': 83,
            },
            'text': text1
        }
    },
    {
        'insertText': {
            'location': {
                'index': 72,
            },
            'text': text1
        }
    },
    {
        'insertText': {
            'location': {
                'index': 49,
            },
            'text': text1
        }
    },
]

result = service.documents().batchUpdate(
    documentId=DOCUMENT_ID, body={'requests': requests1}).execute()

if name == ' main ': main()如果名称== '主要': main()

I believe your current situation and your goal as follows.我相信你现在的情况和你的目标如下。

  • You have a Google Document as a template document.您有一个 Google 文档作为模板文档。
  • You want to achieve the following flow using googleapis for python.您希望使用针对 python 的 googleapis 实现以下流程。
    1. Copy template Document.复制模板文档。
    2. Update copied Document.更新复制的文档。
    3. Download the updated Document as PDF file.将更新后的文档下载为 PDF 文件。
    4. Delete the copied Document.删除复制的文档。

Modification points:修改点:

  • Your script updates the existing Google Document.您的脚本会更新现有的 Google 文档。 So in order to achieve your goal, it is required to prepare other flow.所以为了实现你的目标,需要准备其他流程。
  • In order to copy the template Document, download the Document as PDF file and delete the Document, Drive API is used as follows.为了复制模板文档,下载文档为 PDF 文件并删除文档,驱动器 API 使用如下。 And, when the Document is updated, Docs API is used.并且,当更新文档时,将使用文档 API。
    1. Copy template Document.复制模板文档。
      • In this case, Drive API is used.在这种情况下,使用驱动器 API。
    2. Update copied Document.更新复制的文档。
      • In this case, Docs API is used and the script is used from yoru script.在这种情况下,使用 Docs API 并且使用 yoru script 中的脚本。
    3. Download the updated Document as PDF file.将更新后的文档下载为 PDF 文件。
      • In this case, Drive API is used.在这种情况下,使用驱动器 API。
    4. Delete the copied Document.删除复制的文档。
      • In this case, Drive API is used.在这种情况下,使用驱动器 API。

When your script is modified, it becomes as follows.当你的脚本被修改后,它变成如下。

Modified script:修改后的脚本:

In this modified script, it supposes that creds of credentials=creds is used from your script.在这个修改后的脚本中,它假设creds of credentials=creds从您的脚本中使用。 And, before you use this script, please set the variables.并且,在使用此脚本之前,请设置变量。

templateDocumentId = '###' # Please set the Document ID.
outputPDFFilename = 'sample.pdf' # Please set the output PDF filename.

drive = build('drive', 'v3', credentials=creds)
docs = build('docs', 'v1', credentials=creds)

# 1. Copy template Document.
copiedDoc = drive.files().copy(fileId=templateDocumentId, body={'name': 'copiedTemplateDocument'}).execute()
copiedDocId = copiedDoc.get('id')
print('Done: 1. Copy template Document.')

# 2. Update copied Document.
text1 = 'test'
requests1 = [
    {
        'insertText': {
            'location': {
                'index': 110,
            },
            'text': text1
        }
    },
    {
        'insertText': {
            'location': {
                'index': 98,
            },
            'text': text1
        }
    },
    {
        'insertText': {
            'location': {
                'index': 83,
            },
            'text': text1
        }
    },
    {
        'insertText': {
            'location': {
                'index': 72,
            },
            'text': text1
        }
    },
    {
        'insertText': {
            'location': {
                'index': 49,
            },
            'text': text1
        }
    },
]
result = docs.documents().batchUpdate(documentId=copiedDocId, body={'requests': requests1}).execute()
print('Done: 2. Update copied Document.')

# 3. Download the updated Document as PDF file.
request = drive.files().export_media(fileId=copiedDocId, mimeType='application/pdf')
fh = io.FileIO(outputPDFFilename, mode='wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print('Download %d%%.' % int(status.progress() * 100))
print('Done: 3. Download the updated Document as PDF file.')

# 4. Delete the copied Document.
drive.files().delete(fileId=copiedDocId).execute()
print('Done: 4. Delete the copied Document.')

Note:笔记:

  • In order to download the file, import io and from googleapiclient.http import MediaIoBaseDownload are also used.为了下载文件,还使用import iofrom googleapiclient.http import MediaIoBaseDownload
  • In this answer, it supposes that your request body of requests1 for service.documents().batchUpdate(documentId=DOCUMENT_ID, body={'requests': requests1}).execute() works fine as you expected.在这个答案中,它假设您的 request1 requests1主体service.documents().batchUpdate(documentId=DOCUMENT_ID, body={'requests': requests1}).execute()可以正常工作。 So please be careful this.所以请注意这一点。

References:参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM