最近有一个需要,须要在钉钉微利用 PC 端用上展现 pdf,无奈钉钉的的 webview 不反对 embed
标签,故为了兼容只能应用图片来展现 pdf 文件
我的项目是用 react 写的,ui 为 antd,脚手架 umi,npm 上找了几个 pdf 转图片的 react 库,例如 react-pdf,浏览器展现没有问题,然而在钉钉上遇到了
The browser/environment lacks native support for critical functionality used by the PDF.js library (e.g. 'ReadableStream' and/or 'Promise.allSettled'); please use an ES5-compatible build instead.
该谬误,点击这里查看相干内容。后改用了 pdfjd-dist
配合 ant ui 库,本人实现了一个简略的组件
import React, {useState, useEffect, useRef} from 'react';
import {Spin, Pagination} from 'antd';
var pdfjsLib = require('pdfjs-dist/es5/build/pdf.js');
import 'pdfjs-dist/es5/build/pdf.worker.entry';
interface PdfViewerProps {url: string;}
const PdfViewer = ({url}: PdfViewerProps) => {const [pageNumbers, setPageNumbers] = useState(0);
const [currentPage, setCurrentPage] = useState(1);
const [loading, setLoading] = useState(true);
const [rendering, setRendering] = useState(false);
const pdfRef: any = useRef(null);
function renderPdf(pdfFile: any) {let canvas: any = document.getElementById('pdf');
let canvasContext = canvas.getContext('2d');
pdfFile.getPage(currentPage).then((page: any) => {
// 逐页解析 PDF
var viewport = page.getViewport({scale: 5}); // 页面缩放比例,值越大越清晰
canvas.height = viewport.height;
canvas.width = viewport.width;
canvasContext.clearRect(0, 0, canvas.width, canvas.height);
var renderContext = {
canvasContext: canvasContext,
viewport: viewport,
rotate: 90,
};
setRendering(true);
page.render(renderContext).promise.finally(() => {setRendering(false);
}); // 渲染生成
});
}
useEffect(() => {let loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise
.then((pdf: any) => {// console.log(pdf.numPages);
pdfRef.current = pdf;
setPageNumbers(pdf.numPages);
renderPdf(pdf);
})
.catch((error: any) => {console.log(error);
})
.finally(() => {setLoading(false);
});
}, []);
useEffect(() => {if (pdfRef.current) {window.scrollTo({ top: 0});
renderPdf(pdfRef.current);
}
}, [currentPage]);
return (<Spin spinning={loading || rendering}>
<div>
<canvas id="pdf" style={{width: '100%'}} />
{!loading && (
<Pagination
style={{textAlign: 'center', marginTop: 15}}
current={currentPage}
total={pageNumbers}
pageSize={1}
onChange={value => setCurrentPage(value)}
/>
)}
</div>
</Spin>
);
};
export default PdfViewer;
页面中应用
<PdfViewer url="temp.pdf" />