上的区域来缩放#preview
我已经建立了类似的PDF查看器,这可能会为您提供帮助。PDFViewer.tsx
import { Loading } from "@/components/common/Loading";
import { downloadFile } from "@/utils/file";
import { Download, Printer } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { Document, Page, pdfjs } from "react-pdf";
import "react-pdf/dist/Page/AnnotationLayer.css";
import "react-pdf/dist/Page/TextLayer.css";
import { useReactToPrint } from "react-to-print";
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
interface PDFViewerProps {
url: string;
width: number;
title: string;
showControls?: boolean;
}
// PDFViewer component to display PDF files
function PDFViewer({
url,
width,
title,
showControls = false,
}: PDFViewerProps) {
const [numPages, setNumPages] = useState<number>();
const [pdfWidth, setPdfWidth] = useState(width);
const contentRef = useRef<HTMLDivElement>(null);
const printPdf = useReactToPrint({ contentRef });
const downloadPDF = async () => {
await downloadFile(url, title + ".pdf");
};
useEffect(() => {
setPdfWidth(width);
}, [width]);
return (
<div className="mx-auto" style={{ width: pdfWidth }}>
{" "}
<header
className="card mb-4 justify-between gap-4 rounded-b-none bg-white p-3 pl-8 sm:p-4 print:hidden"
style={{ display: showControls ? "flex" : "none" }}
>
<h1 className="line-clamp-1 text-base font-semibold text-primary sm:text-xl">
{title}
</h1>
<div className="flex gap-4">
<button onClick={downloadPDF}>
<Download className="size-5 text-gray-500 hover:text-primary sm:size-7" />
</button>
<button onClick={() => printPdf()}>
<Printer className="size-5 text-gray-500 hover:text-primary sm:size-7" />
</button>
</div>
</header>
<div ref={contentRef}>
<Document
file={url}
onLoadSuccess={({ numPages }) => setNumPages(numPages)}
loading={<Loading />}
>
{Array.from(new Array(numPages), (_, index) => (
<Page
key={`page_${index + 1}`}
pageNumber={index + 1}
width={pdfWidth}
className="card mb-4 rounded-none print:mb-0 print:border-none"
/>
))}
</Document>
</div>
</div>
);
}
export default PDFViewer;
const [pdfWidth, setPDFWidth] = useState(0);
useEffect(() => {
// Set the width of the resume based on the screen size also handle resize
const handleResize = () => {
const width = window.innerWidth;
if (width > 600) setPDFWidth((width * 2) / 3);
else setPDFWidth(width - 32);
};
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
<PDFViewer title={title} url={pdfUrl} width={pdfWidth} />