赞
踩
需求是预览本地的pdf/word/epub格式的文件,但是搜索后发现没有可以直接使用的,格式不同,显示的方式和效果也都略有不同。
最后还是分别实现预览的功能。
方案:pdfjs+iframe
因为这样可以使用浏览器自带的pdf阅读器,不需要再自己实现小图预览等功能。
pdf.js实现pdf的预览与下载(vue+springboot+pdf.js) 有demo,比较基础的功能。也是本地引入pdf.js的用法
扩展:web打开在线的pdf文件,禁用打印和下载功能
VUE预览PDF文件并利用pdf.js获取鼠标选中的文字和搜索,在iframe中获取选中文字,监听鼠标事件,右键菜单
直接本地引入pdf.js的方法也可以参考上面这篇文章,写的很详细。
主要参考的还是获取选中文字的部分:
getSelectText() { let _this = this; let iframe = document.getElementsByClassName("pdf-viewer-local")[0]; let x = ""; let y = ""; let _x = ""; let _y = ""; // iframe 加载完成后执行并将双击事件过滤掉,因为双击事件可能也触发滑选,所以为了不误操作,将其剔除 iframe.onload = function () { // 鼠标点击监听 iframe.contentDocument.addEventListener( "mousedown", function (e) { x = e.pageX; y = e.pageY; _this.isShowNotePop = false; }, true ); // 鼠标抬起监听 iframe.contentDocument.addEventListener( "mouseup", function (e) { _x = e.pageX; _y = e.pageY; if (x == _x && y == _y) return; //判断点击和抬起的位置,如果相同,则视为没有滑选,不支持双击选中 var selection = iframe.contentWindow.getSelection(); var range = selection.getRangeAt(0); var choose = selection.toString(); _this.selectText = choose; console.log("选中文本:" + choose); }, true ); }; },
扩展:在iframe中获取选中的数据/iframe中鼠标事件 来自上一篇参考文章的参考文章。
旨在转换 .docx 文档(例如由 Microsoft Word 创建的文档),并将其转换为 HTML。 不支持样式。
Vue Word预览之mammoth.js
我的博客:关于实现
功能:实现预览、电子书切换、目录、换背景色、字体大小调整、进度的功能。
方案:使用epub.js,官方文档
版本选择:使用epub对电子书进行渲染(Blocked script execution in 'http://localhost:8080/’ because the document 's frame is sandboxed and the ‘allow-scripts’ permission is not set.),出现了上述报错,原因是epub.js版本太高,所以切换了版本。省流:版本是epubjs@0.3.71
参考文章:
this.book.ready
.then(() => {
this.navigation = this.book.navigation;
return this.book.locations.generate();
})
.then((result) => {
this.locations = this.book.locations;
this.bookAvailable = true;
// 获取总页数
this.totalPages = this.locations.length();
// console.log("Total pages: " + this.totalPages);
});
2.左右翻页或跳转页数
通过父子组件间通信传递当前的页码、监听左右翻页或输入页码跳转。
//epub翻页 prevPage() { if (this.rendition) { console.log("prev"); this.rendition.prev(); this.currentPage--; // 向前翻页时更新 currentPage } }, nextPage() { if (this.rendition) { try { this.rendition.next(); this.currentPage++; // 向后翻页时更新 currentPage } catch (error) { console.log("EPUB 下一页出错:", error); alert("出错,请重试或检查 EPUB 文件格式。"); } } },
注意:“跳转到对应页”这个功能是在子组件中进行监听实现的,
子组件不能直接修改父组件的值,所以需要中转一下。在子组件中使用currentPageLocal
(进行页码的显示或者是传递)
currentPage: {
handler: function (value) {
this.currentPageLocal = value;
},
},
3.监听鼠标滚动控制左右翻页
在包裹epub内容的div上增加监听鼠标滚轮的动作 @wheel="handleWheel"
handleWheel(event) {
if (event.deltaY < 0) {
// console.log("往上");
this.prevPage();
} else if (event.deltaY > 0) {
// console.log("往下");
this.nextPage();
}
},
优化了一下上面的左右翻页代码,如下:
ps:还是存在一些问题的,滚动翻页可能会导致页码和实际的页码对不上?不知道是哪里的逻辑错了。
prevPage() { if (this.rendition) { console.log("prev"); this.rendition.prev(); this.currentPage--; // 向前翻页时更新 currentPage if (this.currentPage <= 1) { this.currentPage = 1; } } }, nextPage() { if (this.rendition) { try { this.rendition.next(); this.currentPage++; // 向后翻页时更新 currentPage if (this.currentPage >= this.totalPages) { this.currentPage = this.totalPages; } } catch (error) { console.log("EPUB 下一页出错:", error); alert("出错,请重试或检查 EPUB 文件格式。"); } } },
4.高亮选中文本(不保存版)
ps:如果是跨行的文本,无法高亮会报错,最好排除一下,加一个用户提示。
//读取epub信息并挂载 async readEpubMes(file) { this.book = ePub(file); await this.book.ready; // console.log(this.book); if (this.book !== null && typeof this.book !== "undefined") { this.rendition = this.book.renderTo("read", { flow: "paginated", width: "100%", height: "100%", }); this.rendition.display(); // 添加选中事件监听器 let lastChoosed = ""; this.rendition.on("selected", (cfiRange, contents) => { // 获取选中范围 let range = contents.window.getSelection().getRangeAt(0); if (range.toString() != lastChoosed) { console.log(range.toString()); lastChoosed = range.toString(); } // 创建标记 let marker = document.createElement("span"); marker.style.backgroundColor = "yellow"; // 设置高亮颜色 marker.classList.add("highlight"); // 可选,添加自定义类名 // 将选中范围用标记包裹起来 range.surroundContents(marker); }); // 获取locations对象 epubjs的钩子函数实现 this.book.ready .then(() => { this.navigation = this.book.navigation; return this.book.locations.generate(); }) .then((result) => { this.locations = this.book.locations; this.bookAvailable = true; // 获取总页数 this.totalPages = this.locations.length(); // console.log("Total pages: " + this.totalPages); }); } },
关于epubjs写得不是很详细,因为是在前面的源码上二改的。所需要的功能也不多。(单页+上下滑动显示不知道怎么实现)
关于pdf的预览,其实直接用vue-pdf也是不错的。
后面补充吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。