使用 Google Docs API 在不影响格式的情况下更改整个文档的字体
Change the font of an entire document without affecting formatting using Google Docs API
我正在尝试使用 API 更改整个 Google 文档的字体。目的是让我们应用程序的用户使用他们公司的字体导出文档。
这是我目前正在做的事情:
from googleapiclient.discovery import build
doc_service = build("docs", "v1")
document = self.doc_service.documents().get(documentId="[Document ID]").execute()
requests = []
for element in document["body"]["content"]:
if "sectionBreak" in element:
continue # Trying to change the font of a section break causes an error
requests.append(
{
"updateTextStyle": {
"range": {
"startIndex": element["startIndex"],
"endIndex": element["endIndex"],
},
"textStyle": {
"weightedFontFamily": {
"fontFamily": "[Font name]"
},
},
"fields": "weightedFontFamily",
}
}
)
doc_service.documents().batchUpdate(
documentId=self.copy_id, body={"requests": requests}
).execute()
上面的代码更改了字体,但它也删除了所有粗体文本格式,因为它覆盖了元素的整个样式。我研究过的一些选项:
DocumentStyle
文档有DocumentStyle
属性,但不包含任何字体信息。
NamedStyles
文档还有一个NamedStyles
属性。它包含 NORMAL_TEXT
和 HEADING_1
等样式。我可以遍历所有这些并更改它们的 textStyle.weightedFontFamily
。这将是理想的解决方案,因为它将样式信息保留在它所属的位置。但是我还没有找到使用 API.
更改 NamedStyles
的方法
更深层次的循环
我可以继续我目前的方法,循环遍历每个 element
上的 elements
列表,保留 textStyle
中的字体以外的所有内容(其中包含 bold: true
).但是,我们目前的方法执行时间已经太长,而且这样的方法会更慢,更脆弱,所以我想避免这种情况。
答案:
从当前元素中提取 textStyle
,仅提取 change/add weightedFontFamily/fontFamily
对象。
代码示例:
for element in document["body"]["content"]:
if "sectionBreak" in element:
continue # Trying to change the font of a section break causes an error
textStyle = element["paragraph"]["elements"][0]["textStyle"]
textStyle["weightedFontFamily"]["fontFamily"] = "[Font name]"
requests.append(
{
"updateTextStyle": {
"range": {
"startIndex": element["startIndex"],
"endIndex": element["endIndex"],
},
"textStyle": textStyle,
"fields": "weightedFontFamily",
}
}
)
doc_service.documents().batchUpdate(
documentId=self.copy_id, body={"requests": requests}
).execute()
这似乎对我有用,即使在文档之间和末尾有分节符。您可能想探索更多极端案例..
这基本上是在尝试模仿 SelectAll
选项
document = service.documents().get(documentId=doc_id).execute()
endIndex = sorted(document["body"]["content"], key=lambda x: x["endIndex"], reverse=True,)[0]["endIndex"]
service.documents().batchUpdate(
documentId=doc_id,
body={
"requests": {
"updateTextStyle": {
"range": {
"endIndex": endIndex,
"startIndex": 1,
},
"fields": "fontSize",
"textStyle": {"fontSize": {"magnitude": 100, "unit": "pt"}},
}
}
},
).execute()
同样适用于其他领域。
但是,如果您只想与所有客户端共享一个 docx 文件,您可以保留一份 PDF/DOCX 的本地副本,然后对其进行修改。在 DOCX 中处理样式相当容易(它是一堆 xml 文件)
使用它来浏览和更新 DOCX 文件OOXML Tools Chrome Extension
同样,PDF 是作为记录存储的键值对。检查这个:ReportLab
我正在尝试使用 API 更改整个 Google 文档的字体。目的是让我们应用程序的用户使用他们公司的字体导出文档。
这是我目前正在做的事情:
from googleapiclient.discovery import build
doc_service = build("docs", "v1")
document = self.doc_service.documents().get(documentId="[Document ID]").execute()
requests = []
for element in document["body"]["content"]:
if "sectionBreak" in element:
continue # Trying to change the font of a section break causes an error
requests.append(
{
"updateTextStyle": {
"range": {
"startIndex": element["startIndex"],
"endIndex": element["endIndex"],
},
"textStyle": {
"weightedFontFamily": {
"fontFamily": "[Font name]"
},
},
"fields": "weightedFontFamily",
}
}
)
doc_service.documents().batchUpdate(
documentId=self.copy_id, body={"requests": requests}
).execute()
上面的代码更改了字体,但它也删除了所有粗体文本格式,因为它覆盖了元素的整个样式。我研究过的一些选项:
DocumentStyle
文档有DocumentStyle
属性,但不包含任何字体信息。
NamedStyles
文档还有一个NamedStyles
属性。它包含 NORMAL_TEXT
和 HEADING_1
等样式。我可以遍历所有这些并更改它们的 textStyle.weightedFontFamily
。这将是理想的解决方案,因为它将样式信息保留在它所属的位置。但是我还没有找到使用 API.
NamedStyles
的方法
更深层次的循环
我可以继续我目前的方法,循环遍历每个 element
上的 elements
列表,保留 textStyle
中的字体以外的所有内容(其中包含 bold: true
).但是,我们目前的方法执行时间已经太长,而且这样的方法会更慢,更脆弱,所以我想避免这种情况。
答案:
从当前元素中提取 textStyle
,仅提取 change/add weightedFontFamily/fontFamily
对象。
代码示例:
for element in document["body"]["content"]:
if "sectionBreak" in element:
continue # Trying to change the font of a section break causes an error
textStyle = element["paragraph"]["elements"][0]["textStyle"]
textStyle["weightedFontFamily"]["fontFamily"] = "[Font name]"
requests.append(
{
"updateTextStyle": {
"range": {
"startIndex": element["startIndex"],
"endIndex": element["endIndex"],
},
"textStyle": textStyle,
"fields": "weightedFontFamily",
}
}
)
doc_service.documents().batchUpdate(
documentId=self.copy_id, body={"requests": requests}
).execute()
这似乎对我有用,即使在文档之间和末尾有分节符。您可能想探索更多极端案例..
这基本上是在尝试模仿 SelectAll
选项
document = service.documents().get(documentId=doc_id).execute()
endIndex = sorted(document["body"]["content"], key=lambda x: x["endIndex"], reverse=True,)[0]["endIndex"]
service.documents().batchUpdate(
documentId=doc_id,
body={
"requests": {
"updateTextStyle": {
"range": {
"endIndex": endIndex,
"startIndex": 1,
},
"fields": "fontSize",
"textStyle": {"fontSize": {"magnitude": 100, "unit": "pt"}},
}
}
},
).execute()
同样适用于其他领域。
但是,如果您只想与所有客户端共享一个 docx 文件,您可以保留一份 PDF/DOCX 的本地副本,然后对其进行修改。在 DOCX 中处理样式相当容易(它是一堆 xml 文件)
使用它来浏览和更新 DOCX 文件OOXML Tools Chrome Extension
同样,PDF 是作为记录存储的键值对。检查这个:ReportLab