实现该需求,主要分为两部
- 利用第三方库将pdf的内容渲染到浏览器中,并且文字可勾选
- 利用js方法将勾选的内容获取
我们先了解下PDF在浏览器通常的展示方式:
- 在网页中直接打开 PDF 文件进行浏览
- 在网页中嵌入 PDF 文件作为页面的一部分
在网页中直接打开 PDF 文件进行浏览:现在主流现代浏览器如 Chrome、Sarafi 基本都内置了支持 PDF 浏览的插件,可以直接打开 PDF 文件,而IE等可能还需要安装插件才能打开 PDF 文件。
在网页中嵌入 PDF 文件作为页面的一部分:可以通过嵌入 iframe 的方式实现,但由于浏览器的同源策略限制,想自定义 PDF 的显示样式让其和页面更和谐,如背景色、默认文字大小,或者禁止打印下载等几乎是不可能的任务。
而PDFjs 则可以统一浏览器中 PDF 的显示(免插件),以及提供更多自定义的功能给web开发者。
PDF.js是什么
PDFjs 由 Mozilla 官方出品,是基于 HTML5 技术构建的用于展示 PDF 的 js 库 ,它可以在现代浏览器中使用且无需安装任何第三方插件。
如何使用PDFjs
方法一
- 可以从官方下载地址 中下载Prebuilt版本,将pdf.js、pdf.worker.js进行引入
2. 读取PDF内容,将PDF内容渲染到页面上
let pdfDocument;
let PAGE_HEIGHT;
const DEFAULT_SCALE = 1.5;
let pdfUrl = 'https://www.gjtool.cn/pdfh5/git.pdf'; // 在线地址
pdfjsLib.getDocument(pdfUrl).promise.then(pdf => {
pdfDocument = pdf;
let viewer = document.getElementById('viewer');
for (let i = 0; i < pdf.numPages; i++) { // pdf.numPages读取pdf的页数
let page = createEmptyPage(i+1); // 根据pdf页面创建多个空的文档div
viewer.appendChild(page);
}
// 先加载第一页
loadPage(1).then(pdfPage => {
let viewport = pdfPage.getViewport({scale: DEFAULT_SCALE});
PAGE_HEIGHT = viewport.height;
document.body.style.width = `${viewport.width}px`;
});
})
function createEmptyPage(num) {
let page = document.createElement('div');
let canvas = document.createElement('canvas');
let wrapper = document.createElement('div');
let textLayer = document.createElement('div');
page.className = 'page';
wrapper.className = 'canvasWrapper';
textLayer.className = 'textLayer';
page.setAttribute('id', `pageContainer${num}`);
page.setAttribute('data-loaded', 'false');
page.setAttribute('data-page-number', num);
canvas.setAttribute('id', `page${num}`);
page.appendChild(wrapper);
page.appendChild(textLayer);
wrapper.appendChild(canvas);
return page;
}
// 渲染pdf
function loadPage(pageNum) {
return pdfDocument.getPage(pageNum).then(pdfPage => {
let page = document.getElementById(`pageContainer${pageNum}`);
let canvas = page.querySelector('canvas');
let wrapper = page.querySelector('.canvasWrapper');
let container = page.querySelector('.textLayer');
let canvasContext = canvas.getContext('2d');
let viewport = pdfPage.getViewport({scale: DEFAULT_SCALE}); // 渲染canvas
canvas.width = viewport.width * 2;
canvas.height = viewport.height * 2;
page.style.width = `${viewport.width}px`;
page.style.height = `${viewport.height}px`;
wrapper.style.width = `${viewport.width}px`;
wrapper.style.height = `${viewport.height}px`;
container.style.width = `${viewport.width}px`;
container.style.height = `${viewport.height}px`;
pdfPage.render({
canvasContext,
viewport
});
page.setAttribute('data-loaded', 'true');
return pdfPage;
});
}
function handleWindowScroll() {
let visiblePageNum = Math.round(window.scrollY / PAGE_HEIGHT) + 1;
let visiblePage = document.querySelector(`.page[data-page-number="${visiblePageNum}"][data-loaded="false"]`);
if (visiblePage) {
setTimeout(function () {
loadPage(visiblePageNum);
});
}
}
到此PDF内容就已经通过pdfjs渲染到了浏览器里,支持本地PDF文件和线上PDF地址进行预览
将PDF内容在浏览器可勾选
如何将pdf内容的文本解析并以dom的形式展现在对应canvas下事先创建好的div中呢,可以利用pdfjsLib.renderTextLayer进行渲染,具体看如何使用
- 首先我们引入web里面的viewer.css文件
2. 然后我们改造loadPage方法
// 渲染pdf
function loadPage(pageNum) {
return pdfDocument.getPage(pageNum).then(pdfPage => {
let page = document.getElementById(`pageContainer${pageNum}`);
let canvas = page.querySelector('canvas');
let wrapper = page.querySelector('.canvasWrapper');
let container = page.querySelector('.textLayer');
let canvasContext = canvas.getContext('2d');
let viewport = pdfPage.getViewport({scale: DEFAULT_SCALE}); // 渲染canvas
canvas.width = viewport.width * 2;
canvas.height = viewport.height * 2;
page.style.width = `${viewport.width}px`;
page.style.height = `${viewport.height}px`;
wrapper.style.width = `${viewport.width}px`;
wrapper.style.height = `${viewport.height}px`;
container.style.width = `${viewport.width}px`;
container.style.height = `${viewport.height}px`;
pdfPage.render({
canvasContext,
viewport
});
// 渲染pdf的dom结构
pdfPage.getTextContent().then(textContent => {
pdfjsLib.renderTextLayer({
textContent: textContent,
container: container,
viewport: viewport,
textDivs: []
});
});
page.setAttribute('data-loaded', 'true');
return pdfPage;
});
}
至此PDF文件在浏览器中,文字也就可勾选了
方法二
- 利用PDFjs提供的web端模板功能,除了将pdf.js、pdf.worker.js引入外,还需要将viewer.css、viewer.js和viewer.html引入
images为viewer.html引入的字体图标, locale为viewer.html引入的国际化文本
2.1将PDF在新打开页面使用
window.open(viewer.html的路径?file=相对于viewer.html的pdf文件的路径)
2.2 将viewer.html内嵌到网页中使用,使用iframe标签引入
<iframe src="viewer.html的路径?file=相对于viewer.html的pdf文件的路径" id="iframePDF" frameborder="0" style="width:100%;height:100%;min-height:490px"></iframe>
读取勾选内容
利用document.getSelection方法将勾选的内容获取
参考文章:
引入PDFjs
mozilla.github.io/pdf.js/exam…
解析文字