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;
							 |