从模板 Google 文档中获取 Header 和页脚,并应用于 Google Drive 文件夹中的所有文档
Get Header and Footer from template Google Doc, and apply to all docs in a Google Drive folder
我需要帮助在 Google 驱动器文件夹中的所有 Google 文档中应用包含表格、段落和图像(品牌 content/letterhead)的 header 和页脚.
目标:
- Get/Copy header 来自包含表格、段落和图像的源文档。
- Paste/Apply/Replace header 复制到 Google 驱动器文件夹中的所有文档
- 对页脚执行相同操作。
- 不需要程序化“附加”到现有页脚。
我希望有一种方法可以为模板做 CSS 或类似的事情,可以应用于一批 google 文档...但我相信脚本是唯一的方法。
这是对 post 的补充:Find and Replace text in entire Google Drive folder, headers, footers, google docs using a script
function replaceHeaderAndFooter() {
const headerToCopyandPaste = DocumentApp.openById("<SourceDocID>").getHeader().getTables().toString(); // ID contains source header
const footerToCopyandPaste = DocumentApp.openById("<SourceDocID>").getHeader().copy(); // ID contains source footer
var files = DriveApp.getFolderById("<FolderID>").getFiles(); //ID contains folder that has Google Docs that will have Header and Footer Replaced
while (files.hasNext()) {
var file = files.next();
var doc = DocumentApp.openById(file.getId());
var headerSectionToBeReplaced = doc.getHeader()
var footerSectionToBeReplaced = doc.getFooter()
headerSectionToBeReplaced.clear();
footerSectionToBeReplaced.clear();
headerSectionToBeReplaced.appendTable(headerToCopyandPaste); //This does not work
footerSectionToBeReplaced = footerToCopyandPaste // This does not work
}
}
我相信你的目标和情况如下。
- 根据您的情况,目标文档有多个页面,并且已经设置了文本,您希望将模板文档的header和页脚复制到每个目标文档的所有页面作为覆盖.
- 从您的共享文档中,
- 我确认在模板文档的 header 中,图像作为内嵌图像放在 table 单元格中。
- 我确认在模板文档的页脚中使用了图片。
- 当图像在table中使用时,即使复制了table,图像似乎也没有被复制。
- 我认为这可能是您遇到问题的原因。
- 根据大家的回复,我可以确认如下。
- 您要使用的 Google 个文档文件有数百个。
- 但是你会运行每几个文档的脚本。
为了实现您的目标,在此示例脚本中,我想提出以下流程。
流量:
- 从特定文件夹中检索 Google 文档文件。
- 在这种情况下,不检查子文件夹就从特定文件夹下检索文档文件。
- 因为从您的回复评论来看,虽然有数百个 Google 文档文件要使用,但您会 运行 每几个文档的脚本。
- 将 header 从模板文档复制到目标文档。
- 将页脚从模板文档复制到目标文档。
重要提示:
作为重要的一点,在当前阶段,不幸的是,当 header 和页脚被 Google 文档服务的 getHeader()
和 getFooter()
检索时无法识别第 1 页 header 的检查是否启用和禁用。因此,在此示例脚本中,headers 和页脚无论是否检查第一页 header 都会被覆盖。
示例脚本:
请将以下脚本复制粘贴到脚本编辑器,并设置templateDocumentId
和folderId
的值,然后运行main()
.
function getObjs(dstDoc, key) {
if (!dstDoc.getHeader()) dstDoc.addHeader(); // Added
if (!dstDoc.getFooter()) dstDoc.addFooter(); // Added
var dd = dstDoc.getHeader().getParent();
var cc = dd.getNumChildren();
const objs = [];
for (let i = 0; i < cc; i++) {
if (dd.getChild(i).getType() == DocumentApp.ElementType[key == "header" ? "HEADER_SECTION" : "FOOTER_SECTION"]) {
objs.push(dd.getChild(i)[key == "header" ? "asHeaderSection" : "asFooterSection"]());
}
}
return objs;
}
function copyFooter(tempDoc, dstDoc) {
getObjs(dstDoc, "footer").forEach(dstFooter => {
dstFooter.clear();
const d = tempDoc.getFooter();
const c = d.getNumChildren();
for (let i = 0; i < c; i++) {
const child = d.getChild(i);
const type = child.getType();
if (type == DocumentApp.ElementType.PARAGRAPH) {
dstFooter.insertParagraph(i, child.copy().asParagraph());
} if (type == DocumentApp.ElementType.TABLE) {
dstFooter.insertTable(i, child.copy().asTable());
}
}
});
}
function copyHeader(tempDoc, dstDoc) {
getObjs(dstDoc, "header").forEach(dstHeader => {
dstHeader.clear();
const d = tempDoc.getHeader();
const c = d.getNumChildren();
for (let i = 0; i < c; i++) {
const child = d.getChild(i);
const type = child.getType();
if (type == DocumentApp.ElementType.PARAGRAPH) {
dstHeader.insertParagraph(i, child.copy().asParagraph());
} if (type == DocumentApp.ElementType.TABLE) {
const table = child.copy().asTable();
let imgObj = [];
for (let r = 0, rows = table.getNumRows(); r < rows; r++) {
const row = table.getRow(r);
for (let c = 0, cols = row.getNumCells(); c < cols; c++) {
const cell = row.getCell(c);
for (let ce = 0, cc = cell.getNumChildren(); ce < cc; ce++) {
if (cell.getChild(ce).getType() == DocumentApp.ElementType.PARAGRAPH) {
const cp = cell.getChild(ce).asParagraph();
for (let cee = 0, cpn = cp.getNumChildren(); cee < cpn; cee++) {
const ceec = cp.getChild(cee);
if (ceec.getType() == DocumentApp.ElementType.INLINE_IMAGE) {
const img = ceec.asInlineImage();
imgObj.push({child: cee, img: img, row: r, col: c, blob: img.getBlob(), width: img.getWidth(), height: img.getHeight()});
ceec.removeFromParent();
}
}
}
}
}
}
const dstTable = dstHeader.insertTable(i, table);
if (imgObj.length > 0) {
imgObj.forEach(({row, col, child, blob, width, height}) => dstTable.getCell(row, col).insertImage(child, blob).setWidth(width).setHeight(height));
}
}
}
});
}
// Please run this function.
function main() {
const templateDocumentId = "###"; // Please set the template Document ID.
const folderId = "###"; // Please set the folder ID.
const tempDoc = DocumentApp.openById(templateDocumentId);
const docs = DriveApp.getFolderById(folderId).getFilesByType(MimeType.GOOGLE_DOCS);
while (docs.hasNext()) {
const docId = docs.next().getId();
const dstDoc = DocumentApp.openById(docId);
copyHeader(tempDoc, dstDoc);
copyFooter(tempDoc, dstDoc);
}
}
注:
- 此示例脚本假设根据您的回复评论,尽管您要使用数百个 Google 文档文件,但您将为每几个文档 运行 该脚本。请注意这一点。
- 此示例脚本用于您的示例模板文档。因为我只有您的示例模板文档中的信息。当您更改模板文档的结构时,此脚本可能无法使用。请注意这一点。
参考文献:
我需要帮助在 Google 驱动器文件夹中的所有 Google 文档中应用包含表格、段落和图像(品牌 content/letterhead)的 header 和页脚.
目标:
- Get/Copy header 来自包含表格、段落和图像的源文档。
- Paste/Apply/Replace header 复制到 Google 驱动器文件夹中的所有文档
- 对页脚执行相同操作。
- 不需要程序化“附加”到现有页脚。
我希望有一种方法可以为模板做 CSS 或类似的事情,可以应用于一批 google 文档...但我相信脚本是唯一的方法。
这是对 post 的补充:Find and Replace text in entire Google Drive folder, headers, footers, google docs using a script
function replaceHeaderAndFooter() {
const headerToCopyandPaste = DocumentApp.openById("<SourceDocID>").getHeader().getTables().toString(); // ID contains source header
const footerToCopyandPaste = DocumentApp.openById("<SourceDocID>").getHeader().copy(); // ID contains source footer
var files = DriveApp.getFolderById("<FolderID>").getFiles(); //ID contains folder that has Google Docs that will have Header and Footer Replaced
while (files.hasNext()) {
var file = files.next();
var doc = DocumentApp.openById(file.getId());
var headerSectionToBeReplaced = doc.getHeader()
var footerSectionToBeReplaced = doc.getFooter()
headerSectionToBeReplaced.clear();
footerSectionToBeReplaced.clear();
headerSectionToBeReplaced.appendTable(headerToCopyandPaste); //This does not work
footerSectionToBeReplaced = footerToCopyandPaste // This does not work
}
}
我相信你的目标和情况如下。
- 根据您的情况,目标文档有多个页面,并且已经设置了文本,您希望将模板文档的header和页脚复制到每个目标文档的所有页面作为覆盖.
- 从您的共享文档中,
- 我确认在模板文档的 header 中,图像作为内嵌图像放在 table 单元格中。
- 我确认在模板文档的页脚中使用了图片。
- 当图像在table中使用时,即使复制了table,图像似乎也没有被复制。
- 我认为这可能是您遇到问题的原因。
- 根据大家的回复,我可以确认如下。
- 您要使用的 Google 个文档文件有数百个。
- 但是你会运行每几个文档的脚本。
为了实现您的目标,在此示例脚本中,我想提出以下流程。
流量:
- 从特定文件夹中检索 Google 文档文件。
- 在这种情况下,不检查子文件夹就从特定文件夹下检索文档文件。
- 因为从您的回复评论来看,虽然有数百个 Google 文档文件要使用,但您会 运行 每几个文档的脚本。
- 将 header 从模板文档复制到目标文档。
- 将页脚从模板文档复制到目标文档。
重要提示:
作为重要的一点,在当前阶段,不幸的是,当 header 和页脚被 Google 文档服务的 getHeader()
和 getFooter()
检索时无法识别第 1 页 header 的检查是否启用和禁用。因此,在此示例脚本中,headers 和页脚无论是否检查第一页 header 都会被覆盖。
示例脚本:
请将以下脚本复制粘贴到脚本编辑器,并设置templateDocumentId
和folderId
的值,然后运行main()
.
function getObjs(dstDoc, key) {
if (!dstDoc.getHeader()) dstDoc.addHeader(); // Added
if (!dstDoc.getFooter()) dstDoc.addFooter(); // Added
var dd = dstDoc.getHeader().getParent();
var cc = dd.getNumChildren();
const objs = [];
for (let i = 0; i < cc; i++) {
if (dd.getChild(i).getType() == DocumentApp.ElementType[key == "header" ? "HEADER_SECTION" : "FOOTER_SECTION"]) {
objs.push(dd.getChild(i)[key == "header" ? "asHeaderSection" : "asFooterSection"]());
}
}
return objs;
}
function copyFooter(tempDoc, dstDoc) {
getObjs(dstDoc, "footer").forEach(dstFooter => {
dstFooter.clear();
const d = tempDoc.getFooter();
const c = d.getNumChildren();
for (let i = 0; i < c; i++) {
const child = d.getChild(i);
const type = child.getType();
if (type == DocumentApp.ElementType.PARAGRAPH) {
dstFooter.insertParagraph(i, child.copy().asParagraph());
} if (type == DocumentApp.ElementType.TABLE) {
dstFooter.insertTable(i, child.copy().asTable());
}
}
});
}
function copyHeader(tempDoc, dstDoc) {
getObjs(dstDoc, "header").forEach(dstHeader => {
dstHeader.clear();
const d = tempDoc.getHeader();
const c = d.getNumChildren();
for (let i = 0; i < c; i++) {
const child = d.getChild(i);
const type = child.getType();
if (type == DocumentApp.ElementType.PARAGRAPH) {
dstHeader.insertParagraph(i, child.copy().asParagraph());
} if (type == DocumentApp.ElementType.TABLE) {
const table = child.copy().asTable();
let imgObj = [];
for (let r = 0, rows = table.getNumRows(); r < rows; r++) {
const row = table.getRow(r);
for (let c = 0, cols = row.getNumCells(); c < cols; c++) {
const cell = row.getCell(c);
for (let ce = 0, cc = cell.getNumChildren(); ce < cc; ce++) {
if (cell.getChild(ce).getType() == DocumentApp.ElementType.PARAGRAPH) {
const cp = cell.getChild(ce).asParagraph();
for (let cee = 0, cpn = cp.getNumChildren(); cee < cpn; cee++) {
const ceec = cp.getChild(cee);
if (ceec.getType() == DocumentApp.ElementType.INLINE_IMAGE) {
const img = ceec.asInlineImage();
imgObj.push({child: cee, img: img, row: r, col: c, blob: img.getBlob(), width: img.getWidth(), height: img.getHeight()});
ceec.removeFromParent();
}
}
}
}
}
}
const dstTable = dstHeader.insertTable(i, table);
if (imgObj.length > 0) {
imgObj.forEach(({row, col, child, blob, width, height}) => dstTable.getCell(row, col).insertImage(child, blob).setWidth(width).setHeight(height));
}
}
}
});
}
// Please run this function.
function main() {
const templateDocumentId = "###"; // Please set the template Document ID.
const folderId = "###"; // Please set the folder ID.
const tempDoc = DocumentApp.openById(templateDocumentId);
const docs = DriveApp.getFolderById(folderId).getFilesByType(MimeType.GOOGLE_DOCS);
while (docs.hasNext()) {
const docId = docs.next().getId();
const dstDoc = DocumentApp.openById(docId);
copyHeader(tempDoc, dstDoc);
copyFooter(tempDoc, dstDoc);
}
}
注:
- 此示例脚本假设根据您的回复评论,尽管您要使用数百个 Google 文档文件,但您将为每几个文档 运行 该脚本。请注意这一点。
- 此示例脚本用于您的示例模板文档。因为我只有您的示例模板文档中的信息。当您更改模板文档的结构时,此脚本可能无法使用。请注意这一点。