85 lines
2.0 KiB
JavaScript
85 lines
2.0 KiB
JavaScript
|
|
import { Button, message, Modal, Spin } from "antd";
|
|||
|
|
import { useState } from "react";
|
|||
|
|
import { Document, Page, pdfjs } from "react-pdf";
|
|||
|
|
import { getFileUrl } from "../../utils/index";
|
|||
|
|
|
|||
|
|
function Pdf(props) {
|
|||
|
|
const {
|
|||
|
|
visible = false,
|
|||
|
|
onCancel,
|
|||
|
|
file,
|
|||
|
|
inline = false,
|
|||
|
|
style = {},
|
|||
|
|
} = props;
|
|||
|
|
|
|||
|
|
const fileUrl = getFileUrl();
|
|||
|
|
const [numPages, setNumPages] = useState(0);
|
|||
|
|
const [pdfWidth, setPdfWidth] = useState(600);
|
|||
|
|
const [loading, setLoading] = useState(true);
|
|||
|
|
|
|||
|
|
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
|||
|
|
"pdfjs-dist/build/pdf.worker.min.mjs",
|
|||
|
|
import.meta.url,
|
|||
|
|
).toString();
|
|||
|
|
|
|||
|
|
const onDocumentLoadSuccess = ({ numPages }) => {
|
|||
|
|
setNumPages(numPages);
|
|||
|
|
setLoading(false);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const onDocumentLoadError = () => {
|
|||
|
|
setLoading(false);
|
|||
|
|
message.error("加载 PDF 文件失败");
|
|||
|
|
if (onCancel)
|
|||
|
|
onCancel();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const onPageLoadSuccess = ({ width }) => {
|
|||
|
|
setPdfWidth(width);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 内联模式的PDF内容
|
|||
|
|
const renderPdfContent = () => (
|
|||
|
|
<>
|
|||
|
|
{loading && (
|
|||
|
|
<div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "80vh" }}>
|
|||
|
|
<Spin size="large" />
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
<div style={{ height: "88vh", overflowY: "auto", padding: "24px", ...style }}>
|
|||
|
|
<Document
|
|||
|
|
file={fileUrl + file}
|
|||
|
|
onLoadSuccess={onDocumentLoadSuccess}
|
|||
|
|
onLoadError={onDocumentLoadError}
|
|||
|
|
>
|
|||
|
|
{
|
|||
|
|
Array.from({ length: numPages }).map((el, index) => (
|
|||
|
|
<Page key={`page_${index + 1}`} pageNumber={index + 1} onLoadSuccess={onPageLoadSuccess} />
|
|||
|
|
))
|
|||
|
|
}
|
|||
|
|
</Document>
|
|||
|
|
</div>
|
|||
|
|
</>
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// 如果是内联模式,直接返回PDF内容
|
|||
|
|
if (inline) {
|
|||
|
|
return renderPdfContent();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 默认弹窗模式
|
|||
|
|
return (
|
|||
|
|
<Modal
|
|||
|
|
open={visible}
|
|||
|
|
width={pdfWidth + 100}
|
|||
|
|
title="PDF预览"
|
|||
|
|
onCancel={onCancel}
|
|||
|
|
footer={<Button onClick={onCancel}>关闭</Button>}
|
|||
|
|
>
|
|||
|
|
{renderPdfContent()}
|
|||
|
|
</Modal>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default Pdf;
|