【WPS JSAPI加载项】 书签替换功能的实现

本文档详细介绍了如何在WPS中使用书签进行文本替换,包括设置字体样式、在书签末尾追加内容等操作。通过获取书签范围,判断故事类型,根据不同内容类型插入文本、文件、图片、域或粘贴内容。同时,提供了扩展功能,如指定字体样式插入文本和在书签后追加内容的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

案例需求:

替换书签范围为指定内容, 类型:文本/文件/图片/域/剪贴板

扩展:

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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值