在 Google Docs App Script 中填充文本范围的最佳实践
Best practice for filling a text range in Google Docs App Script
我在 google 文档中使用了一个字母模板,我想通过 App 脚本自动在字母的(动态)header 之后填充字母。是否有任何最佳做法可以将文本始终设置在同一位置?我试过使用占位符并替换它。但有时我需要多次替换文本。
我不知道最佳做法,但您可以使用书签。你不能给它们命名,但如果你知道,比方说,第 5 个书签是用户名,然后循环浏览书签,当你到达第 5 个时编辑文本。
之前:
function myFunction() {
try {
var doc = DocumentApp.getActiveDocument();
var bmarks = doc.getBookmarks();
var position = null;
var i = 0;
for( i=0; i<bmarks.length; i++ ) {
console.log(bmarks[i].getId());
position = bmarks[i].getPosition();
position.insertText("i = "+i)
}
}
catch(err) {
console.log(err);
}
}
之后:
在您的情况下,使用 NamedRange 怎么样? Ref
使用NamedRange时,脚本如下
示例脚本:
// Create custom menu.
function onOpen() {
DocumentApp.getUi().createMenu("sample")
.addItem("1. Install named range", "setNamedRange")
.addItem("2. Change text by named range", "changeTextByNamedRange")
.addItem("Delete named range", "deleteNamedRange")
.addToUi();
}
const nameOfNamedRange = "sample1"; // Please set the name of your named range.
// Set named range.
function setNamedRange() {
const doc = DocumentApp.getActiveDocument();
const ele = doc.getCursor().getElement();
const range = doc.newRange().addElement(ele).build();
doc.addNamedRange(nameOfNamedRange, range);
}
// Update named range.
function changeTextByNamedRange() {
const updateText = "updated sample"; // Please set the updated text you want.
const doc = DocumentApp.getActiveDocument();
const range = doc.getNamedRanges().find(r => r.getName() == nameOfNamedRange);
if (!range) {
throw new Error("No named range. Please install a named range.");
}
range.getRange().getRangeElements().forEach(e => e.getElement().asText().setText(updateText));
}
// Delete named range.
function deleteNamedRange() {
const doc = DocumentApp.getActiveDocument();
const range = doc.getNamedRanges().find(r => r.getName() == nameOfNamedRange);
if (!range) return;
range.remove();
}
用法:
- 请将光标置于要设置命名范围的文档上。
- 运行
setNamedRange
。这样,当前光标所在的点就被设置为命名范围。
- 当您想要更改命名范围的文本时。请运行
changeTextByNamedRange
。通过这种方式,更新的文本将作为替换内容放入命名范围。
- 在这种情况下,即使改变段落,改变命名范围前后的文本,也可以使用命名范围。
如果要删除命名范围,请运行 deleteNamedRange
.
测试:
当上述脚本为运行时,得到如下结果
参考:
我在 google 文档中使用了一个字母模板,我想通过 App 脚本自动在字母的(动态)header 之后填充字母。是否有任何最佳做法可以将文本始终设置在同一位置?我试过使用占位符并替换它。但有时我需要多次替换文本。
我不知道最佳做法,但您可以使用书签。你不能给它们命名,但如果你知道,比方说,第 5 个书签是用户名,然后循环浏览书签,当你到达第 5 个时编辑文本。
之前:
function myFunction() {
try {
var doc = DocumentApp.getActiveDocument();
var bmarks = doc.getBookmarks();
var position = null;
var i = 0;
for( i=0; i<bmarks.length; i++ ) {
console.log(bmarks[i].getId());
position = bmarks[i].getPosition();
position.insertText("i = "+i)
}
}
catch(err) {
console.log(err);
}
}
之后:
在您的情况下,使用 NamedRange 怎么样? Ref
使用NamedRange时,脚本如下
示例脚本:
// Create custom menu.
function onOpen() {
DocumentApp.getUi().createMenu("sample")
.addItem("1. Install named range", "setNamedRange")
.addItem("2. Change text by named range", "changeTextByNamedRange")
.addItem("Delete named range", "deleteNamedRange")
.addToUi();
}
const nameOfNamedRange = "sample1"; // Please set the name of your named range.
// Set named range.
function setNamedRange() {
const doc = DocumentApp.getActiveDocument();
const ele = doc.getCursor().getElement();
const range = doc.newRange().addElement(ele).build();
doc.addNamedRange(nameOfNamedRange, range);
}
// Update named range.
function changeTextByNamedRange() {
const updateText = "updated sample"; // Please set the updated text you want.
const doc = DocumentApp.getActiveDocument();
const range = doc.getNamedRanges().find(r => r.getName() == nameOfNamedRange);
if (!range) {
throw new Error("No named range. Please install a named range.");
}
range.getRange().getRangeElements().forEach(e => e.getElement().asText().setText(updateText));
}
// Delete named range.
function deleteNamedRange() {
const doc = DocumentApp.getActiveDocument();
const range = doc.getNamedRanges().find(r => r.getName() == nameOfNamedRange);
if (!range) return;
range.remove();
}
用法:
- 请将光标置于要设置命名范围的文档上。
- 运行
setNamedRange
。这样,当前光标所在的点就被设置为命名范围。 - 当您想要更改命名范围的文本时。请运行
changeTextByNamedRange
。通过这种方式,更新的文本将作为替换内容放入命名范围。- 在这种情况下,即使改变段落,改变命名范围前后的文本,也可以使用命名范围。
如果要删除命名范围,请运行 deleteNamedRange
.
测试:
当上述脚本为运行时,得到如下结果