ONLYOFFICE深度解锁系列.11-试试ONLYOFFICE 宏:秒算文章阅读时长

预估阅读时间是文本编辑器中一项实用的功能,它能帮助用户了解阅读文档大概需要耗费多长时间。我们的实习生 Vukasin 开发了一个别出心裁却切实有效的宏,可在 ONLYOFFICE 文档编辑器里计算预计阅读时间。在本文中,我们将对该宏进行剖析,解释每个功能的工作原理,以及它们是如何协同运作,从而给出准确的预估阅读时间的。
什么是 ONLYOFFICE 宏
如果您是一名资深 Microsoft Excel 用户,那么相信您已对于 VBA 宏非常熟悉了。这些宏是帮助您自动执行日常任务的小型脚本。无论是重构数据,还是在单元格区域中插入多个值。ONLYOFFICE 宏的基础是 JavaScript 语法与文档生成器 API 方法。基于 JavaSript 的宏易于使用,具有跨平台特性且十分安全。这就使得其与 VBA 相比有着显著的优势。
下面一起来看看,如何使用宏预估文章的阅读时间。
构建宏
首先,我们使用 Api.GetDocument() 方法检索文档对象:
try { const document = Api.GetDocument();定义常量 // Constants for reading speed calculations const WORDS_PER_MINUTE = 238; // Average adult reading speed const COMPLEX_WORD_LENGTH = 7; // Words with this many chars or more are considered complex
此处定义了两个常量:
WORDS_PER_MINUTE:代表成年人的平均阅读速度,即每分钟 238 个单词。
COMPLEX_WORD_LENGTH:作为判断单词是否复杂的标准阈值。
单词计数
然后,countWords 函数根据空格将给定的文本拆分为单词,并统计非空单词的数量:
function countWords(text) { if (!text) return 0; return text.split(/s+/).filter((word) => word.length > 0).length; }
估计复杂度
为了估计文本复杂程度,我们采用 estimatedComplexity 函数:
function estimateComplexity(text) { if (!text) return 0; const words = text.split(/s+/).filter((word) => word.length > 0); if (words.length === 0) return 0; const complexWords = words.filter( (word) => word.length >= COMPLEX_WORD_LENGTH ).length; return complexWords / words.length; }
此函数通过以下方式确定文本的复杂度:
1. 将文本拆分成单词。
2. 将文本拆分成单词。
3. 计算复杂单词在所有单词中所占的比例。
检索和处理段落
然后我们继续处理文本:
const paragraphs = document.GetAllParagraphs(); let totalWords = 0; let totalText = ""; paragraphs.forEach((paragraph) => { const text = paragraph.GetText(); totalWords += countWords(text); totalText += text + " "; });
在本部分中,我们将执行以下操作:
从文档中检索所有段落。
从文档中检索所有段落。
统计每个段落包含的单词数量,并累计总字数。
保存所有文本,以便后续进行复杂度评估。
调整复杂度
这里,复杂度系数用于调整阅读速度。复杂度越高,有效阅读速度越低:
const complexityFactor = estimateComplexity(totalText); const complexityAdjustment = 1 - complexityFactor * 0.3; const effectiveWPM = WORDS_PER_MINUTE * complexityAdjustment;
计算阅读时间
接下来,我们将总字数换算成阅读所需分钟数,再进一步转换为小时数:
const readingTimeMinutes = totalWords / effectiveWPM; const readingTimeHours = readingTimeMinutes / 60;
格式化输出
之后,我们根据计算得出的时间,对阅读时间的输出结果进行格式化处理。
let readingTimeText; if (readingTimeMinutes < 1) { readingTimeText = `less than 1 minute`; } else if (readingTimeMinutes < 60) { readingTimeText = `${Math.ceil(readingTimeMinutes)} minute${Math.ceil(readingTimeMinutes) !== 1 ? "s" : "" }`; } else { const hours = Math.floor(readingTimeHours); const remainingMinutes = Math.ceil((readingTimeHours - hours) * 60); readingTimeText = `${hours} hour${hours !== 1 ? "s" : ""}${remainingMinutes > 0 ? ` and ${remainingMinutes} minute${remainingMinutes !== 1 ? "s" : "" }` : "" }`; }
插入输出
然后我们插入格式化的输出:
const infoText = `Reading Time: ${readingTimeText} (${totalWords} words at ${Math.round( effectiveWPM )} words per minute)`; const oParagraph = Api.CreateParagraph(); oParagraph.AddText(infoText); oParagraph.SetBold(true); oParagraph.SetItalic(true); oParagraph.SetFontFamily("Arial"); document.InsertContent([oParagraph], 0); } catch (error) { console.log("Error: " + error.message); }})();

完整的宏代码
(function () { try { const document = Api.GetDocument(); // Constants for reading speed calculations const WORDS_PER_MINUTE = 238; // Average adult reading speed const COMPLEX_WORD_LENGTH = 7; // Words with this many chars or more are considered complex function countWords(text) { if (!text) return 0; return text.split(/s+/).filter((word) => word.length > 0).length; } function estimateComplexity(text) { if (!text) return 0; const words = text.split(/s+/).filter((word) => word.length > 0); if (words.length === 0) return 0; const complexWords = words.filter( (word) => word.length >= COMPLEX_WORD_LENGTH ).length; return complexWords / words.length; } const paragraphs = document.GetAllParagraphs(); let totalWords = 0; let totalText = ""; paragraphs.forEach((paragraph) => { const text = paragraph.GetText(); totalWords += countWords(text); totalText += text + " "; }); const complexityFactor = estimateComplexity(totalText); const complexityAdjustment = 1 - complexityFactor * 0.3; const effectiveWPM = WORDS_PER_MINUTE * complexityAdjustment; const readingTimeMinutes = totalWords / effectiveWPM; const readingTimeHours = readingTimeMinutes / 60; let readingTimeText; if (readingTimeMinutes < 1) { readingTimeText = `less than 1 minute`; } else if (readingTimeMinutes < 60) { readingTimeText = `${Math.ceil(readingTimeMinutes)} minute${Math.ceil(readingTimeMinutes) !== 1 ? "s" : "" }`; } else { const hours = Math.floor(readingTimeHours); const remainingMinutes = Math.ceil((readingTimeHours - hours) * 60); readingTimeText = `${hours} hour${hours !== 1 ? "s" : ""}${remainingMinutes > 0 ? ` and ${remainingMinutes} minute${remainingMinutes !== 1 ? "s" : "" }` : "" }`; } const infoText = `Reading Time: ${readingTimeText} (${totalWords} words at ${Math.round( effectiveWPM )} words per minute)`; const oParagraph = Api.CreateParagraph(); oParagraph.AddText(infoText); oParagraph.SetBold(true); oParagraph.SetItalic(true); oParagraph.SetFontFamily("Arial"); document.InsertContent([oParagraph], 0); } catch (error) { console.log("Error: " + error.message); }})();
此宏提供了一种在 ONLYOFFICE 中估算阅读时间的巧妙方法,我们相信它会成为您日常工作中的实用工具。ONLYOFFICE 宏功能多样,既能帮助增强软件的默认功能,又能编写出专为您需求量身打造的脚本。
福利推荐-软件获取方法
豆容器市场专注提供优质Docker应用服务,集成一键式容器安装功能,助力用户快速部署OnlyOffice、协作空间、Nextcloud、可道云等办公应用。平台新增IPv6内网直连技术,搭配自动化SSL证书配置及智能域名解析功能,为家庭云服务提供完整技术方案,简化私有云搭建与运维流程,轻松实现高效云端协作管理。
onlyoffice已经支持ARM和x86双模式安装,其他软件同步支持中。
地址: https://ds.sendtokindle.net.cn/
图片
