案例需求:
替换书签范围为指定内容, 类型:文本/文件/图片/域/剪贴板
扩展:
1.替换书签中的内容,并且想指定字体
2.不想替换整个书签,只想在书签末尾追加内容
案例可能遇到的坑:
暂无
代码流程
1. 获取书签的区域Range
2. 记录书签的起始位置和末尾位置
3. 记录替换前文章的原长度
判断书签所在的StoryType,常见为正文/文本框/页眉页脚。他们对应不同的文章Story。
如果是[1正文]记录文档Document原先的总长度。[其他]则记录对应文章中的总字符数StoryLength
WdStoryType[wdMainTextStory|1|正文部分,wdTextFrameStory|5|文本框部分,10、11|页眉页脚]
4. 判断入参type、插入对应的内容
5. 获取替换后文章的长度
6. 重新设置书签的范围,计算书签的末尾为: 原先书签末尾 + (替换后文章长度 - 替换前文章长度)
代码实现
/**
* 书签替换
* @author Li Zuxian
* @param {string} bookmarkStr 书签名
* @param {string} type 替换类型 text:文本 link:文件 pic:图片 field:域 paste:粘贴
* @param {string} text 替换内容
*/
function SetBookMark(bookmarkStr, type, text) {
var app = wps.WpsApplication();
var doc = wps.WpsApplication().ActiveDocument;
var bookmark = doc.Bookmarks.Item(bookmarkStr);
if (!bookmark) return "书签不存在";
let bookStart = bookmark.Range.Start;
let bookEnd = bookmark.Range.End;
let beforeEnd = doc.Range().End;
//Range.StoryType -> WdStoryType[wdMainTextStory|1|正文部分,wdTextFrameStory|5|文本框部分,10、11|页眉页脚]
beforeEnd = /5|10|11/.test(bookmark.Range.StoryType) ? bookmark.Range.StoryLength : beforeEnd;
if (!type || type === "text") {
bookmark.Range.Text = text;
} else if (type === "link") {
bookmark.Range.InsertFile(text);
} else if (type === "pic") {
bookmark.Range.InlineShapes.AddPicture(text);
} else if (type === "field") {
bookmark.Range.Fields.Item(1).Result.Text = text;
return;
} else if (type === "paste") {
bookmark.Range.Select();
app.Selection.PasteAndFormat(16);
}
let nowEnd = doc.Range().End;
let range = bookmark.Range;
nowEnd = /5|10|11/.test(range.StoryType) ? bookmark.Range.StoryLength : nowEnd; //文本框是不同的story
if (!doc.Bookmarks.Exists(bookmark.Name)) { //书签不存在就添加书签
range.SetRange(bookStart, bookEnd + (nowEnd - beforeEnd));
doc.Bookmarks.Add(bookmark.Name, range);
} else { //书签存在就删掉再添加
bookmark.Delete();
app.Selection.SetRange(bookStart, bookEnd + (nowEnd - beforeEnd));
doc.Bookmarks.Add(bookmark.Name, app.Selection.Range);
}
app.ActiveWindow.Selection.WholeStory();
app.ActiveWindow.Selection.EndKey();
}
扩展代码
1.替换书签中的内容,并且想指定字体
插入内容改为光标处插入样式文字的方法
/**
* 书签替换(带字体样式)
* @author Li Zuxian
* @param {string} bookmarkStr 书签名
* @param {string} text 替换内容
* @param {object} font 字体 json
* {
* "Name":"微软雅黑", //字体
* "Bold":true, //粗体
* "Italic":true, //斜体
* "Size":21, //字体大小
* "Color":"#FFF", //颜色的16进制
* "Alignment":"2", //对齐方式 [0居左 1居中 2居右]
* "CleaerIndent":true //清除缩进
* }
*/
function SetBookMark(bookmarkStr, text, font) {
var app = wps.WpsApplication();
var doc = wps.WpsApplication().ActiveDocument;
var bookmark = doc.Bookmarks.Item(bookmarkStr);
if (!bookmark) return;
let bookStart = bookmark.Range.Start;
let bookEnd = bookmark.Range.End;
let beforeEnd = doc.Range().End;
if (bookmark) {
//Range.StoryType -> WdStoryType[wdMainTextStory|1|正文部分,wdTextFrameStory|5|文本框部分,10、11|页眉页脚]
beforeEnd = /5|10|11/.test(bookmark.Range.StoryType) ? bookmark.Range.StoryLength : beforeEnd;
//这里改成样式插入文字
app.Selection.SetRange(bookStart, bookEnd);
insertText(text, font);
let nowEnd = doc.Range().End;
let range = bookmark.Range;
nowEnd = /5|10|11/.test(range.StoryType) ? bookmark.Range.StoryLength : nowEnd; //文本框是不同的story
if (!doc.Bookmarks.Exists(bookmark.Name)) { //书签不存在就添加书签
range.SetRange(bookStart, bookEnd + (nowEnd - beforeEnd));
doc.Bookmarks.Add(bookmark.Name, range);
} else { //书签存在就删掉再添加
bookmark.Delete();
app.Selection.SetRange(bookStart, bookEnd + (nowEnd - beforeEnd));
doc.Bookmarks.Add(bookmark.Name, app.Selection.Range);
}
app.ActiveWindow.Selection.WholeStory();
app.ActiveWindow.Selection.EndKey();
}
}
/**
* 光标处插入文本(带样式)
* @author Li Zuxian
* @param str 欲插入的文本内容
* @param font json
* {
* "Name":"微软雅黑", //字体
* "Bold":true, //粗体
* "Italic":true, //斜体
* "Size":21, //字体大小
* "Color":"#b50e19", //颜色的16进制
* "Alignment":"2", //对齐方式 [0居左 1居中 2居右]
* "CleaerIndent":true //清除缩进
* }
*/
function insertText(str, font) {
let app = wps.WpsApplication();
let selection = app.Selection;
let start = selection.Range.End;
let end;
selection.TypeText(str);
end = selection.Range.End;
app.Selection.SetRange(start, end);
if (font) {
//字体
if (font.Name)
selection.Font.Name = font.Name
//粗体
selection.Font.Bold = font.Bold ? -1 : 0;
selection.Font.BoldBi = font.Bold ? -1 : 0;
//斜体
selection.Font.Italic = font.Italic ? -1 : 0;
selection.Font.ItalicBi = font.Italic ? -1 : 0;
//大小
if (font.Size) {
selection.Font.Size = font.Size
selection.Font.SizeBi = font.Size
}
//颜色
if (font.Color)
selection.Font.Color = colorHex2int(font.Color)
//对齐
if (font.Alignment) {
selection.ParagraphFormat.Alignment = font.Alignment
}
//清除缩进
if (font.CleaerIndent) {
selection.ParagraphFormat.CharacterUnitFirstLineIndent = 0; //首行缩进 (以字符为单位)
selection.ParagraphFormat.CharacterUnitLeftIndent = 0; //左缩进值 (以字符为单位)
selection.ParagraphFormat.FirstLineIndent = 0; //首行缩进 (以磅为单位)
selection.ParagraphFormat.LeftIndent = 0; //左缩进值 (以磅为单位)
}
}
app.Selection.SetRange(end, end);
}
/**
* 颜色16转10进制 forWPS
* @author Li Zuxian
* @param {string} hex
* @returns int
*/
function colorHex2int(hex) {
hex = hex.replace(/#/g, "");
hex = [hex.substring(4, 6), hex.substring(2, 4), hex.substring(0, 2)].join("");
var len = hex.length, a = new Array(len), code;
for (var i = 0; i < len; i++) {
code = hex.charCodeAt(i);
if (48 <= code && code < 58) {
code -= 48;
} else {
code = (code & 0xdf) - 65 + 10;
}
a[i] = code;
}
return a.reduce(function (acc, c) {
acc = 16 * acc + c;
return acc;
}, 0);
}
2.不想替换整个书签,只想在书签末尾追加内容
这里只需要将上面书签替换中的代码 app.Selection.SetRange(bookStart, bookEnd)
改为 app.Selection.SetRange(bookEnd, bookEnd) 即可实现,意味插入时直接在书签末尾插入
/**
* 书签追加 //目前只支持文字追加
* @param {string} bookmarkStr 书签名
* @param {string} text 替换内容
* @param {object} font 字体 json
* {
* "Name":"微软雅黑", //字体
* "Bold":true, //粗体
* "Italic":true, //斜体
* "Size":21, //字体大小
* "Color":"#FFF", //颜色的16进制
* "Alignment":"2", //对齐方式 [0居左 1居中 2居右]
* "CleaerIndent":true //清除缩进
* }
*/
function BookMarkAddmore(bookmarkStr, text, font) {
var app = wps.WpsApplication();
var doc = wps.WpsApplication().ActiveDocument;
var bookmark = doc.Bookmarks.Item(bookmarkStr);
if (!bookmark) return;
let bookStart = bookmark.Range.Start;
let bookEnd = bookmark.Range.End;
let beforeEnd = doc.Range().End;
if (bookmark) {
//Range.StoryType -> WdStoryType[wdMainTextStory|1|正文部分,wdTextFrameStory|5|文本框部分,10、11|页眉页脚]
beforeEnd = /5|10|11/.test(bookmark.Range.StoryType) ? bookmark.Range.StoryLength : beforeEnd;
//这里改成样式插入文字
app.Selection.SetRange(bookEnd, bookEnd);
insertText(text, font);
let nowEnd = doc.Range().End;
let range = bookmark.Range;
nowEnd = /5|10|11/.test(range.StoryType) ? bookmark.Range.StoryLength : nowEnd; //文本框是不同的story
if (!doc.Bookmarks.Exists(bookmark.Name)) { //书签不存在就添加书签
range.SetRange(bookStart, bookEnd + (nowEnd - beforeEnd));
doc.Bookmarks.Add(bookmark.Name, range);
} else { //书签存在就删掉再添加
bookmark.Delete();
app.Selection.SetRange(bookStart, bookEnd + (nowEnd - beforeEnd));
doc.Bookmarks.Add(bookmark.Name, app.Selection.Range);
}
app.ActiveWindow.Selection.WholeStory();
app.ActiveWindow.Selection.EndKey();
}
}
/**
* 光标处插入文本(带样式)
* @author Li Zuxian
* @param str 欲插入的文本内容
* @param font json
* {
* "Name":"微软雅黑", //字体
* "Bold":true, //粗体
* "Italic":true, //斜体
* "Size":21, //字体大小
* "Color":"#b50e19", //颜色的16进制
* "Alignment":"2", //对齐方式 [0居左 1居中 2居右]
* "CleaerIndent":true //清除缩进
* }
*/
function insertText(str, font) {
let app = wps.WpsApplication();
let selection = app.Selection;
let start = selection.Range.End;
let end;
selection.TypeText(str);
end = selection.Range.End;
app.Selection.SetRange(start, end);
if (font) {
//字体
if (font.Name)
selection.Font.Name = font.Name
//粗体
selection.Font.Bold = font.Bold ? -1 : 0;
selection.Font.BoldBi = font.Bold ? -1 : 0;
//斜体
selection.Font.Italic = font.Italic ? -1 : 0;
selection.Font.ItalicBi = font.Italic ? -1 : 0;
//大小
if (font.Size) {
selection.Font.Size = font.Size
selection.Font.SizeBi = font.Size
}
//颜色
if (font.Color)
selection.Font.Color = colorHex2int(font.Color)
//对齐
if (font.Alignment) {
selection.ParagraphFormat.Alignment = font.Alignment
}
//清除缩进
if (font.CleaerIndent) {
selection.ParagraphFormat.CharacterUnitFirstLineIndent = 0; //首行缩进 (以字符为单位)
selection.ParagraphFormat.CharacterUnitLeftIndent = 0; //左缩进值 (以字符为单位)
selection.ParagraphFormat.FirstLineIndent = 0; //首行缩进 (以磅为单位)
selection.ParagraphFormat.LeftIndent = 0; //左缩进值 (以磅为单位)
}
}
app.Selection.SetRange(end, end);
}
/**
* 颜色16转10进制 forWPS
* @param {string} hex
* @returns int
*/
function colorHex2int(hex) {
hex = hex.replace(/#/g, "");
hex = [hex.substring(4, 6), hex.substring(2, 4), hex.substring(0, 2)].join("");
var len = hex.length, a = new Array(len), code;
for (var i = 0; i < len; i++) {
code = hex.charCodeAt(i);
if (48 <= code && code < 58) {
code -= 48;
} else {
code = (code & 0xdf) - 65 + 10;
}
a[i] = code;
}
return a.reduce(function (acc, c) {
acc = 16 * acc + c;
return acc;
}, 0);
}
//-------demo-以下是测试代码----------
//标题字体
var titleFont = {
"Name": "微软雅黑", //字体
"Bold": true, //粗体
"Italic": true, //斜体
"Size": 18, //字体大小
"Color": "#b50e19" //颜色的16进制
}
//正文字体
var ContentFont = {
"Name": "微软雅黑", //字体
"Bold": false, //粗体
"Italic": false, //斜体
"Size": 12, //字体大小
"Color": "#FFF" //颜色的16进制
}
//测试数据
var data = [
{ "title": "测试标题1\n", "content": "测试内容1\n" },
{ "title": "测试标题2\n", "content": "测试内容2\n" },
{ "title": "测试标题3\n", "content": "测试内容3\n" },
]
//插入测试书签
wps.Application.Selection.Bookmarks.Add("test");
//触发渲染
function render(data) {
data.forEach(d => {
BookMarkAddmore("test", d.title, titleFont)
BookMarkAddmore("test", d.content, ContentFont)
});
}
render(data);